diff --git a/.github/test-spec.yml b/.github/test-spec.yml new file mode 100644 index 00000000000..d9dcf1280f1 --- /dev/null +++ b/.github/test-spec.yml @@ -0,0 +1,297 @@ +# 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/**/*" + - "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": null +# Not necessary to run tests on changes to this repo. + +"CI-boot-dfu-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + - "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": + - 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/**/*" + - "samples/bluetooth/hci_rpc/**/*" + +"CI-mesh-test": + - "subsys/bluetooth/mesh/**/*" + - "include/zephyr/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": + - "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": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"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": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"CI-rs-test": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"CI-thread-test": + - "include/zephyr/net/**/*" + - "modules/mbedtls/**/*" + - "modules/openthread/**/*" + - "samples/net/openthread/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-nfc-test": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"CI-matter-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "drivers/net/**/*" + - "samples/bluetooth/hci_rpc/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + +"CI-find-my-test": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"CI-gazell-test": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"CI-rpc-test": + - any: + - "**/*" + - "!samples/bluetooth/**/*" + - "!tests/bluetooth/**/*" + +"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/**/*" + +"CI-sidewalk-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpc/**/*" + - any: + - "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_rpc/**/*" + - "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/**/*" + +"CI-pmic-samples-test": + - "samples/shields/npm1300_ek/**/*" + - "boards/shields/npm1300_ek/**/*" + - "**/**npm1300**/**" + - "drivers/regulator/regulator_common.c" + - "drivers/regulator/regulator_shell.c" + - "drivers/gpio/gpio_shell.c" + - "drivers/sensor/sensor_shell.c" + +"CI-test-low-level": + - "dts/**/*" + - "include/zephyr/**/*" + - "tests/arch/**/*" + - "arch/**/*" + - "tests/kernel/**/*" + - "kernel/**/*" + - "tests/drivers/**/*" + - "drivers/**/*" + - "samples/subsys/settings/**/*" + - "subsys/settings/**/*" + - "samples/subsys/logging/**/*" + - "subsys/logging/**/*" + - "samples/sensor/**/*" + - "samples/hello_world/**/*" + - "samples/synchronization/**/*" + - "samples/drivers/watchdog/**/*" + - "modules/hal_nordic/**/*" diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 0aa8d5cd690..34b4b8595a9 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -8,8 +8,7 @@ concurrency: jobs: clang-build: - if: github.repository_owner == 'zephyrproject-rtos' - runs-on: zephyr-runner-linux-x64-4xlarge + runs-on: ubuntu-latest container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.5 options: '--entrypoint /bin/bash' @@ -19,11 +18,13 @@ jobs: fail-fast: false matrix: platform: ["native_posix"] + subset: [1, 2, 3, 4, 5] env: 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 }} + MATRIX_SIZE: 5 outputs: report_needed: ${{ steps.twister.outputs.report_needed }} steps: @@ -86,7 +87,7 @@ jobs: id: cache-ccache uses: zephyrproject-rtos/action-s3-cache@v1.2.0 with: - key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.platform }}-ccache + key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.subset }}-ccache path: /github/home/.cache/ccache aws-s3-bucket: ccache.zephyrproject.org aws-access-key-id: ${{ vars.AWS_CCACHE_ACCESS_KEY_ID }} @@ -99,6 +100,16 @@ jobs: test -d github/home/.cache/ccache && rm -rf /github/home/.cache/ccache && mv github/home/.cache/ccache /github/home/.cache/ccache ccache -M 10G -s + - name: Build test plan with Twister + id: twister_test_plan + run: | + export ZEPHYR_BASE=${PWD} + export ZEPHYR_TOOLCHAIN_VARIANT=llvm + + # check if we need to run a full twister or not based on files changed + python3 ./scripts/ci/test_plan.py -p native_posix -c origin/${BASE_REF}.. + + - name: Run Tests with Twister id: twister run: | @@ -112,7 +123,7 @@ jobs: if [ -s testplan.json ]; then echo "report_needed=1" >> $GITHUB_OUTPUT # Full twister but with options based on changes - ./scripts/twister --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 + ./scripts/twister --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 --subset ${{matrix.subset}}/${MATRIX_SIZE} else # if nothing is run, skip reporting step echo "report_needed=0" >> $GITHUB_OUTPUT @@ -127,7 +138,7 @@ jobs: if: always() && steps.twister.outputs.report_needed != 0 uses: actions/upload-artifact@v3 with: - name: Unit Test Results (Subset ${{ matrix.platform }}) + name: Unit Test Results (Subset ${{ matrix.subset }}) path: twister-out/twister.xml clang-build-results: 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..036729418cb 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 -e ModulesMaintainers -c origin/${BASE_REF}.. - name: upload-results uses: actions/upload-artifact@v3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 164d82fde0e..10196c43540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,6 +213,11 @@ endif() # Apply the final optimization flag(s) zephyr_compile_options(${OPTIMIZATION_FLAG}) +if(CONFIG_LTO) + zephyr_compile_options($) + add_link_options($) +endif() + # @Intent: Obtain compiler specific flags related to C++ that are not influenced by kconfig zephyr_compile_options($<$:$>) @@ -803,6 +808,10 @@ target_include_directories(${OFFSETS_LIB} PRIVATE kernel/include ${ARCH_DIR}/${ARCH}/include ) + +# Make sure that LTO will never be enabled when compiling offsets.c +set_source_files_properties(${OFFSETS_C_PATH} PROPERTIES COMPILE_OPTIONS $) + target_link_libraries(${OFFSETS_LIB} zephyr_interface) add_dependencies(zephyr_interface ${SYSCALL_LIST_H_TARGET} @@ -1226,10 +1235,11 @@ 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 + OUTPUT isr_tables.c isr_tables_vt.ld isr_tables_swi.ld COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/gen_isr_tables.py --output-source isr_tables.c + --linker-output-files isr_tables_vt.ld isr_tables_swi.ld --kernel $ --intlist-section .intList --intlist-section intList @@ -1806,8 +1816,15 @@ endif() # Generate and use MCUboot related artifacts as needed. if(CONFIG_BOOTLOADER_MCUBOOT) get_target_property(signing_script zephyr_property_target SIGNING_SCRIPT) + if(NOT signing_script) - set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) + zephyr_get(signing_script VAR SIGNING_SCRIPT SYSBUILD) + + if(signing_script) + set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${signing_script}) + else() + set_target_properties(zephyr_property_target PROPERTIES SIGNING_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/cmake/mcuboot.cmake) + endif() endif() endif() 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 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) diff --git a/Kconfig.zephyr b/Kconfig.zephyr index c484898206b..848ce58da7e 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -417,6 +417,13 @@ config NO_OPTIMIZATIONS default stack sizes in order to avoid stack overflows. endchoice +config LTO + bool "Link Time Optimization [EXPERIMENTAL]" + depends on !(GEN_ISR_TABLES || GEN_IRQ_VECTOR_TABLE) || ISR_TABLES_LOCAL_DECLARATION + select EXPERIMENTAL + help + This option enables Link Time Optimization. + config COMPILER_WARNINGS_AS_ERRORS bool "Treat warnings as errors" help diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 97d0ec0222f..c6f75fd234d 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -707,7 +707,6 @@ Documentation: - doc/images/Zephyr-Kite-in-tree.png - doc/index-tex.rst - doc/index.rst - - doc/kconfig.rst - doc/known-warnings.txt - doc/templates/sample.tmpl - doc/templates/board.tmpl @@ -1100,6 +1099,8 @@ Release Notes: - doc/hardware/peripherals/gnss.rst - drivers/gnss/ - include/zephyr/drivers/gnss.h + - include/zephyr/drivers/gnss/ + - tests/drivers/build_all/gnss/ - tests/drivers/gnss/ labels: - "area: GNSS" @@ -2473,7 +2474,7 @@ GD32 Platforms: - dts/*/gigadevice/ - dts/bindings/*/*gd32* - soc/arm/gigadevice/ - - soc/riscv/riscv-privileged/gd32vf103/ + - soc/riscv/gd_gd32/ - scripts/west_commands/*/*gd32* labels: - "platform: GD32" @@ -2851,7 +2852,7 @@ ITE Platforms: - drivers/*/*it8xxx2*.c - dts/bindings/*/*ite* - dts/riscv/ite/ - - soc/riscv/riscv-ite/ + - soc/riscv/ite_ec/ labels: - "platform: ITE" diff --git a/arch/Kconfig b/arch/Kconfig index 5e3b96f414d..5c0ad5f49d9 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -391,6 +391,29 @@ config NOCACHE_MEMORY menu "Interrupt Configuration" +config ISR_TABLES_LOCAL_DECLARATION_SUPPORTED + bool + default y + # Userspace is currently not supported + depends on !USERSPACE + # List of currently supported architectures + depends on ARM || ARM64 + # List of currently supported toolchains + depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr" || "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "gnuarmemb" + +config ISR_TABLES_LOCAL_DECLARATION + bool "ISR tables created locally and placed by linker [EXPERIMENTAL]" + depends on ISR_TABLES_LOCAL_DECLARATION_SUPPORTED + select EXPERIMENTAL + help + Enable new scheme of interrupt tables generation. + This is totally different generator that would create tables entries locally + where the IRQ_CONNECT macro is called and then use the linker script to position it + in the right place in memory. + The most important advantage of such approach is that the generated interrupt tables + are LTO compatible. + The drawback is that the support on the architecture port is required. + config DYNAMIC_INTERRUPTS bool "Installation of IRQs at runtime" help diff --git a/arch/arc/core/arc_smp.c b/arch/arc/core/arc_smp.c index 9fb43c41152..1aa61be53f0 100644 --- a/arch/arc/core/arc_smp.c +++ b/arch/arc/core/arc_smp.c @@ -145,7 +145,7 @@ void arch_sched_ipi(void) } } -static int arc_smp_init(void) +int arch_smp_init(void) { struct arc_connect_bcr bcr; @@ -188,6 +188,5 @@ static int arc_smp_init(void) return 0; } - -SYS_INIT(arc_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 1b4fa58eae5..680e21fdb59 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -34,3 +34,11 @@ else() zephyr_linker_sources(ROM_START SORT_KEY 0x0vectors vector_table.ld) zephyr_linker_sources(ROM_START SORT_KEY 0x1vectors cortex_m/vector_table_pad.ld) endif() + +if(CONFIG_GEN_SW_ISR_TABLE) + if(CONFIG_DYNAMIC_INTERRUPTS) + zephyr_linker_sources(RWDATA swi_tables.ld) + else() + zephyr_linker_sources(RODATA swi_tables.ld) + endif() +endif() 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 diff --git a/arch/arm/core/cortex_a_r/smp.c b/arch/arm/core/cortex_a_r/smp.c index 2aeb36c1735..c17f2fa048f 100644 --- a/arch/arm/core/cortex_a_r/smp.c +++ b/arch/arm/core/cortex_a_r/smp.c @@ -245,7 +245,7 @@ void arch_sched_ipi(void) broadcast_ipi(SGI_SCHED_IPI); } -static int arm_smp_init(void) +int arch_smp_init(void) { cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR()); @@ -259,6 +259,6 @@ static int arm_smp_init(void) return 0; } -SYS_INIT(arm_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm/core/cortex_m/Kconfig b/arch/arm/core/cortex_m/Kconfig index 95e05604783..61dd3dbba3c 100644 --- a/arch/arm/core/cortex_m/Kconfig +++ b/arch/arm/core/cortex_m/Kconfig @@ -283,7 +283,20 @@ config ARMV8_1_M_MVEF supporting the M-Profile Vector Extension (MVE) floating-point instruction set. -menu "ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33 options" +config ARMV8_1_M_PMU + bool + help + This option is enabled when the CPU implements ARMv8-M Performance + Monitoring Unit (PMU). + +config ARMV8_M_PMU_EVENTCNT + int "Number of event counters in the Performance Monitoring Unit" + depends on ARMV8_1_M_PMU + range 2 8 + help + The number of event counters implemented. + +menu "ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33/M55 options" depends on ARMV6_M_ARMV8_M_BASELINE || ARMV7_M_ARMV8_M_MAINLINE config GEN_ISR_TABLES 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/arch/arm/core/swi_tables.ld b/arch/arm/core/swi_tables.ld new file mode 100644 index 00000000000..a5dd3eaf652 --- /dev/null +++ b/arch/arm/core/swi_tables.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +INCLUDE isr_tables_swi.ld +#endif diff --git a/arch/arm/core/vector_table.ld b/arch/arm/core/vector_table.ld index 615067dbf74..463e389de9f 100644 --- a/arch/arm/core/vector_table.ld +++ b/arch/arm/core/vector_table.ld @@ -51,6 +51,10 @@ _vector_start = .; KEEP(*(.exc_vector_table)) KEEP(*(".exc_vector_table.*")) +#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +INCLUDE isr_tables_vt.ld +#else KEEP(*(.vectors)) +#endif _vector_end = .; diff --git a/arch/arm64/core/CMakeLists.txt b/arch/arm64/core/CMakeLists.txt index 1804556c1a7..05e4be8c0ea 100644 --- a/arch/arm64/core/CMakeLists.txt +++ b/arch/arm64/core/CMakeLists.txt @@ -55,3 +55,11 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU") endif() add_subdirectory_ifdef(CONFIG_XEN xen) + +if(CONFIG_GEN_SW_ISR_TABLE) + if(CONFIG_DYNAMIC_INTERRUPTS) + zephyr_linker_sources(RWDATA swi_tables.ld) + else() + zephyr_linker_sources(RODATA swi_tables.ld) + endif() +endif() diff --git a/arch/arm64/core/prep_c.c b/arch/arm64/core/prep_c.c index c12d5e7d1c4..510476d2ef7 100644 --- a/arch/arm64/core/prep_c.c +++ b/arch/arm64/core/prep_c.c @@ -69,6 +69,7 @@ void z_arm64_prep_c(void) CODE_UNREACHABLE; } + #if CONFIG_MP_MAX_NUM_CPUS > 1 extern FUNC_NORETURN void z_arm64_secondary_start(void); void z_arm64_secondary_prep_c(void) diff --git a/arch/arm64/core/smp.c b/arch/arm64/core/smp.c index e67032eb2a4..043e07eb305 100644 --- a/arch/arm64/core/smp.c +++ b/arch/arm64/core/smp.c @@ -279,7 +279,7 @@ void arch_spin_relax(void) } #endif -static int arm64_smp_init(void) +int arch_smp_init(void) { cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR()); @@ -302,6 +302,6 @@ static int arm64_smp_init(void) return 0; } -SYS_INIT(arm64_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif diff --git a/arch/arm64/core/swi_tables.ld b/arch/arm64/core/swi_tables.ld new file mode 100644 index 00000000000..a5dd3eaf652 --- /dev/null +++ b/arch/arm64/core/swi_tables.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +INCLUDE isr_tables_swi.ld +#endif diff --git a/arch/common/CMakeLists.txt b/arch/common/CMakeLists.txt index 1a89ba9c13a..409c378f620 100644 --- a/arch/common/CMakeLists.txt +++ b/arch/common/CMakeLists.txt @@ -39,6 +39,11 @@ zephyr_linker_sources_ifdef(CONFIG_GEN_ISR_TABLES ${ZEPHYR_BASE}/include/zephyr/linker/intlist.ld ) +zephyr_linker_sources_ifdef(CONFIG_ISR_TABLES_LOCAL_DECLARATION + SECTIONS + ${ZEPHYR_BASE}/include/zephyr/linker/isr-local-drop-unused.ld +) + zephyr_linker_sources_ifdef(CONFIG_GEN_IRQ_VECTOR_TABLE ROM_START SORT_KEY 0x0vectors diff --git a/arch/common/isr_tables.c b/arch/common/isr_tables.c index 0311f81f252..050597b7b1d 100644 --- a/arch/common/isr_tables.c +++ b/arch/common/isr_tables.c @@ -15,15 +15,27 @@ struct int_list_header { uint32_t table_size; uint32_t offset; +#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) + uint32_t swi_table_entry_size; + uint32_t shared_isr_table_entry_size; + uint32_t shared_isr_client_num_offset; +#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ }; /* These values are not included in the resulting binary, but instead form the * header of the initList section, which is used by gen_isr_tables.py to create * the vector and sw isr tables, */ -Z_GENERIC_SECTION(.irq_info) struct int_list_header _iheader = { +Z_GENERIC_SECTION(.irq_info) __used struct int_list_header _iheader = { .table_size = IRQ_TABLE_SIZE, .offset = CONFIG_GEN_IRQ_START_VECTOR, +#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) + .swi_table_entry_size = sizeof(struct _isr_table_entry), +#if IS_ENABLED(CONFIG_SHARED_INTERRUPTS) + .shared_isr_table_entry_size = sizeof(struct z_shared_isr_table_entry), + .shared_isr_client_num_offset = offsetof(struct z_shared_isr_table_entry, client_num), +#endif /* IS_ENABLED(CONFIG_SHARED_INTERRUPTS) */ +#endif /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ }; /* These are placeholder tables. They will be replaced by the real tables diff --git a/arch/common/shared_irq.c b/arch/common/shared_irq.c index 68641cb2bb0..a05e78002ce 100644 --- a/arch/common/shared_irq.c +++ b/arch/common/shared_irq.c @@ -20,7 +20,7 @@ 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; + const struct _isr_table_entry *client; entry = data; @@ -42,7 +42,7 @@ void z_isr_install(unsigned int irq, void (*routine)(const void *), { struct z_shared_isr_table_entry *shared_entry; struct _isr_table_entry *entry; - struct z_shared_isr_client *client; + struct _isr_table_entry *client; unsigned int table_idx; int i; k_spinlock_key_t key; @@ -103,10 +103,10 @@ 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) +static void swap_client_data(struct _isr_table_entry *a, + struct _isr_table_entry *b) { - struct z_shared_isr_client tmp; + struct _isr_table_entry tmp; tmp.arg = a->arg; tmp.isr = a->isr; @@ -162,7 +162,7 @@ int z_isr_uninstall(unsigned int irq, { struct z_shared_isr_table_entry *shared_entry; struct _isr_table_entry *entry; - struct z_shared_isr_client *client; + struct _isr_table_entry *client; unsigned int table_idx; size_t i; k_spinlock_key_t key; diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index a1cefcbdf43..a816d1c5501 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -47,6 +47,12 @@ config INCLUDE_RESET_VECTOR Include the reset vector stub, which initializes the stack and prepares for running C code. +config RISCV_PRIVILEGED + bool + select ARCH_HAS_RAMFUNC_SUPPORT if XIP + help + Option selected by SoCs implementing the RISC-V privileged ISA. + config RISCV_SOC_HAS_ISR_STACKING bool depends on !USERSPACE @@ -147,13 +153,32 @@ config RISCV_SOC_OFFSETS in offsets.h. The last one should not end in a semicolon. See gen_offset.h for more details. +config RISCV_HAS_PLIC + bool + depends on RISCV_PRIVILEGED + help + Does the SOC provide support for a Platform Level Interrupt Controller (PLIC). + +config RISCV_HAS_CLIC + bool + depends on RISCV_PRIVILEGED + help + Does the SOC provide support for a Core-Local Interrupt Controller (CLIC). + +config RISCV_SOC_EXCEPTION_FROM_IRQ + bool + help + Option selected by SoCs that require a custom mechanism to check if + an exception is the result of an interrupt or not. If selected, + __soc_is_irq() needs to be implemented by the SoC. + config RISCV_SOC_INTERRUPT_INIT bool "SOC-based interrupt initialization" help Enable SOC-based interrupt initialization (call soc_interrupt_init, within _IntLibInit when enabled) -config RISCV_SOC_MCAUSE_EXCEPTION_MASK +config RISCV_MCAUSE_EXCEPTION_MASK hex default 0x7FFFFFFFFFFFFFFF if 64BIT default 0x7FFFFFFF @@ -168,11 +193,6 @@ config RISCV_GENERIC_TOOLCHAIN Allow SOCs that have custom extended riscv ISA to still compile with generic riscv32 toolchain. -config RISCV_HAS_CPU_IDLE - bool "Does SOC has CPU IDLE instruction" - help - Does SOC has CPU IDLE instruction - config GEN_ISR_TABLES default y @@ -333,7 +353,7 @@ config RISCV_TRAP_HANDLER_ALIGNMENT The minimum alignment is 4 bytes according to the Spec. config GEN_IRQ_VECTOR_TABLE - select RISCV_VECTORED_MODE if SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_VECTORED_MODE if RISCV_PRIVILEGED config ARCH_HAS_SINGLE_THREAD_SUPPORT default y if !SMP diff --git a/arch/riscv/core/cpu_idle.c b/arch/riscv/core/cpu_idle.c index 0c7f5f3dac7..0d8e4fedeb2 100644 --- a/arch/riscv/core/cpu_idle.c +++ b/arch/riscv/core/cpu_idle.c @@ -5,24 +5,18 @@ */ #include - -/* - * In RISC-V there is no conventional way to handle CPU power save. - * Each RISC-V SOC handles it in its own way. - * Hence, by default, arch_cpu_idle and arch_cpu_atomic_idle functions just - * unlock interrupts and return to the caller, without issuing any CPU power - * saving instruction. - * - * Nonetheless, define the default arch_cpu_idle and arch_cpu_atomic_idle - * functions as weak functions, so that they can be replaced at the SOC-level. - */ +#include void __weak arch_cpu_idle(void) { + sys_trace_idle(); irq_unlock(MSTATUS_IEN); + __asm__ volatile("wfi"); } void __weak arch_cpu_atomic_idle(unsigned int key) { + sys_trace_idle(); irq_unlock(key); + __asm__ volatile("wfi"); } diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index 171497ff0ca..6e8831f1026 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -167,7 +167,7 @@ void _Fault(z_arch_esf_t *esf) __asm__ volatile("csrr %0, mtval" : "=r" (mtval)); #endif - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; LOG_ERR(""); LOG_ERR(" mcause: %ld, %s", mcause, cause_str(mcause)); #ifndef CONFIG_SOC_OPENISA_RV32M1_RISCV32 diff --git a/arch/riscv/core/irq_manage.c b/arch/riscv/core/irq_manage.c index e0ef1374bf1..f95b099a4da 100644 --- a/arch/riscv/core/irq_manage.c +++ b/arch/riscv/core/irq_manage.c @@ -10,6 +10,10 @@ #include #include +#ifdef CONFIG_RISCV_HAS_PLIC +#include +#endif + LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); FUNC_NORETURN void z_irq_spurious(const void *unused) @@ -20,11 +24,11 @@ FUNC_NORETURN void z_irq_spurious(const void *unused) mcause = csr_read(mcause); - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; LOG_ERR("Spurious interrupt detected! IRQ: %ld", mcause); #if defined(CONFIG_RISCV_HAS_PLIC) - if (mcause == RISCV_MACHINE_EXT_IRQ) { + if (mcause == RISCV_IRQ_MEXT) { unsigned int save_irq = riscv_plic_get_irq(); const struct device *save_dev = riscv_plic_get_dev(); diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index c36679ae6db..982e6777b36 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "asm_macros.inc" @@ -50,7 +51,9 @@ /* imports */ GDATA(_sw_isr_table) +#ifdef CONFIG_RISCV_SOC_EXCEPTION_FROM_IRQ GTEXT(__soc_is_irq) +#endif GTEXT(__soc_handle_irq) GTEXT(_Fault) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE @@ -90,7 +93,8 @@ GTEXT(_isr_wrapper) * what standard behavior is defined). Hence, the arch level code expects * the following functions to be provided at the SOC level: * - * - __soc_is_irq: decide if we're handling an interrupt or an exception + * - __soc_is_irq (optional): decide if we're handling an interrupt or an + exception * - __soc_handle_irq: handle SoC-specific details for a pending IRQ * (e.g. clear a pending bit in a SoC-specific register) * @@ -283,10 +287,14 @@ no_fp: /* increment _current->arch.exception_depth */ * function (that needs to be implemented by each SOC). The result is * returned via register a0 (1: interrupt, 0 exception) */ +#ifdef CONFIG_RISCV_SOC_EXCEPTION_FROM_IRQ jal ra, __soc_is_irq - - /* If a0 != 0, jump to is_interrupt */ bnez a0, is_interrupt +#else + csrr t0, mcause + srli t0, t0, RISCV_MCAUSE_IRQ_POS + bnez t0, is_interrupt +#endif /* * If the exception is the result of an ECALL, check whether to @@ -294,22 +302,22 @@ no_fp: /* increment _current->arch.exception_depth */ * to report the exception. */ csrr t0, mcause - li t2, SOC_MCAUSE_EXP_MASK + li t2, CONFIG_RISCV_MCAUSE_EXCEPTION_MASK and t0, t0, t2 /* - * If mcause == SOC_MCAUSE_ECALL_EXP, handle system call from + * If mcause == RISCV_EXC_ECALLM, handle system call from * kernel thread. */ - li t1, SOC_MCAUSE_ECALL_EXP + li t1, RISCV_EXC_ECALLM beq t0, t1, is_kernel_syscall #ifdef CONFIG_USERSPACE /* - * If mcause == SOC_MCAUSE_USER_ECALL_EXP, handle system call + * If mcause == RISCV_EXC_ECALLU, handle system call * for user mode thread. */ - li t1, SOC_MCAUSE_USER_ECALL_EXP + li t1, RISCV_EXC_ECALLU beq t0, t1, is_user_syscall #endif /* CONFIG_USERSPACE */ @@ -527,7 +535,7 @@ on_irq_stack: /* Get IRQ causing interrupt */ csrr a0, mcause - li t0, SOC_MCAUSE_EXP_MASK + li t0, CONFIG_RISCV_MCAUSE_EXCEPTION_MASK and a0, a0, t0 /* diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 7730138a376..96982341b1a 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -16,7 +16,6 @@ #include #include #include -#include #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE #include @@ -25,6 +24,8 @@ #include #endif +#include + /* struct _callee_saved member offsets */ GEN_OFFSET_SYM(_callee_saved_t, sp); GEN_OFFSET_SYM(_callee_saved_t, ra); diff --git a/arch/riscv/core/prep_c.c b/arch/riscv/core/prep_c.c index 8b9b118b24c..b486b4949d8 100644 --- a/arch/riscv/core/prep_c.c +++ b/arch/riscv/core/prep_c.c @@ -20,6 +20,10 @@ #include #include +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void); +#endif + /** * * @brief Prepare to and run C code diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 6154450e58d..99f67f57ecc 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include volatile struct { @@ -22,6 +23,10 @@ volatile void *riscv_cpu_sp; extern void __start(void); +#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) +void soc_interrupt_init(void); +#endif + void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz, arch_cpustart_t fn, void *arg) { @@ -67,14 +72,15 @@ void z_riscv_secondary_cpu_init(int hartid) z_riscv_pmp_init(); #endif #ifdef CONFIG_SMP - irq_enable(RISCV_MACHINE_SOFT_IRQ); + irq_enable(RISCV_IRQ_MSOFT); #endif riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg); } #ifdef CONFIG_SMP -#define MSIP(hartid) ((volatile uint32_t *)RISCV_MSIP_BASE)[hartid] +#define MSIP_BASE 0x2000000UL +#define MSIP(hartid) ((volatile uint32_t *)MSIP_BASE)[hartid] static atomic_val_t cpu_pending_ipi[CONFIG_MP_MAX_NUM_CPUS]; #define IPI_SCHED 0 @@ -104,7 +110,7 @@ void z_riscv_flush_fpu_ipi(unsigned int cpu) } #endif -static void ipi_handler(const void *unused) +static void sched_ipi_handler(const void *unused) { ARG_UNUSED(unused); @@ -151,14 +157,13 @@ void arch_spin_relax(void) } #endif -static int riscv_smp_init(void) +int arch_smp_init(void) { - IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 0, ipi_handler, NULL, 0); - irq_enable(RISCV_MACHINE_SOFT_IRQ); + IRQ_CONNECT(RISCV_IRQ_MSOFT, 0, sched_ipi_handler, NULL, 0); + irq_enable(RISCV_IRQ_MSOFT); return 0; } - -SYS_INIT(riscv_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(arch_smp_init, PRE_KERNEL_2, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif /* CONFIG_SMP */ diff --git a/arch/x86/core/intel64/irq.c b/arch/x86/core/intel64/irq.c index a7304271746..09b1961585c 100644 --- a/arch/x86/core/intel64/irq.c +++ b/arch/x86/core/intel64/irq.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); @@ -154,7 +155,7 @@ void arch_irq_offload(irq_offload_routine_t routine, const void *parameter) #if defined(CONFIG_SMP) -void z_x86_ipi_setup(void) +int arch_smp_init(void) { /* * z_sched_ipi() doesn't have the same signature as a typical ISR, so @@ -166,8 +167,11 @@ void z_x86_ipi_setup(void) /* TLB shootdown handling */ x86_irq_funcs[CONFIG_TLB_IPI_VECTOR - IV_IRQS] = z_x86_tlb_ipi; + return 0; } +SYS_INIT(arch_smp_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); + /* * it is not clear exactly how/where/why to abstract this, as it * assumes the use of a local APIC (but there's no other mechanism). diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index ee095efe33d..8f7618495a9 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -74,7 +74,7 @@ FUNC_NORETURN void z_x86_prep_c(void *arg) #endif #if defined(CONFIG_SMP) - z_x86_ipi_setup(); + arch_smp_init(); #endif z_cstart(); 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..3d31ede313f 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 @@ -189,6 +189,10 @@ arduino_spi: &spi2 { status = "okay"; }; +&gpiote { + status = "okay"; +}; + &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; diff --git a/boards/arm/b_u585i_iot02a/CMakeLists.txt b/boards/arm/b_u585i_iot02a/CMakeLists.txt index dde73804665..f6ca91f1a73 100644 --- a/boards/arm/b_u585i_iot02a/CMakeLists.txt +++ b/boards/arm/b_u585i_iot02a/CMakeLists.txt @@ -10,6 +10,6 @@ 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} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/b_u585i_iot02a/Kconfig.defconfig b/boards/arm/b_u585i_iot02a/Kconfig.defconfig index ae1e57aba8e..6b3b72554ff 100644 --- a/boards/arm/b_u585i_iot02a/Kconfig.defconfig +++ b/boards/arm/b_u585i_iot02a/Kconfig.defconfig @@ -16,4 +16,15 @@ config SPI_STM32_INTERRUPT config USE_DT_CODE_PARTITION default y if TRUSTED_EXECUTION_NONSECURE +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 + +endif # BUILD_WITH_TFM + endif # BOARD_B_U585I_IOT02A diff --git a/boards/arm/b_u585i_iot02a/doc/index.rst b/boards/arm/b_u585i_iot02a/doc/index.rst index 3c794b4de79..5512a95f16d 100644 --- a/boards/arm/b_u585i_iot02a/doc/index.rst +++ b/boards/arm/b_u585i_iot02a/doc/index.rst @@ -346,14 +346,14 @@ can be generated using ``b_u585i_iot02a_ns`` as build target. $ west build -b b_u585i_iot02a_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/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 + $ build/tfm/api_ns/regression.sh Finally, to flash the board, run: diff --git a/boards/arm/bl5340_dvk/CMakeLists.txt b/boards/arm/bl5340_dvk/CMakeLists.txt index 541334195dd..863c8bb599e 100644 --- a/boards/arm/bl5340_dvk/CMakeLists.txt +++ b/boards/arm/bl5340_dvk/CMakeLists.txt @@ -9,7 +9,7 @@ zephyr_library_sources(bl5340_dvk_cpunet_reset.c) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/bl654_usb/bl654_usb.dts b/boards/arm/bl654_usb/bl654_usb.dts index 80600290dbf..fa814f4b80e 100644 --- a/boards/arm/bl654_usb/bl654_usb.dts +++ b/boards/arm/bl654_usb/bl654_usb.dts @@ -59,6 +59,10 @@ status = "okay"; }; +&gpiote { + status = "okay"; +}; + &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; diff --git a/boards/arm/nrf52840_mdk/doc/index.rst b/boards/arm/nrf52840_mdk/doc/index.rst index fce05bee593..6e0b24b65f2 100644 --- a/boards/arm/nrf52840_mdk/doc/index.rst +++ b/boards/arm/nrf52840_mdk/doc/index.rst @@ -7,7 +7,7 @@ Overview ******** The nRF52840-MDK is a versatile, easy-to-use IoT hardware platform for -Bluetooth 5, Bluetooth mesh, Thread, IEEE 802.15.4, ANT and 2.4GHz proprietary +Bluetooth 5, Bluetooth Mesh, Thread, IEEE 802.15.4, ANT and 2.4GHz proprietary applications using the nRF52840 SoC. The development kit comes with a fully integrated debugger (also known as 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 { diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt index c950fd91724..fa1c1ba14d9 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt +++ b/boards/arm/nrf5340_audio_dk_nrf5340/CMakeLists.txt @@ -8,7 +8,7 @@ if ((CONFIG_BOARD_NRF5340_AUDIO_DK_NRF5340_CPUAPP OR CONFIG_BOARD_NRF5340_AUDIO_ if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c index 4368ca303fc..f9082e6ca40 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c @@ -10,8 +10,7 @@ #include #include - -#include +#include LOG_MODULE_REGISTER(nrf5340_audio_dk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -25,11 +24,11 @@ static int core_config(void) { nrf_gpiote_latency_t latency; - latency = nrfx_gpiote_latency_get(); + latency = nrf_gpiote_latency_get(NRF_GPIOTE); if (latency != NRF_GPIOTE_LATENCY_LOWPOWER) { LOG_DBG("Setting gpiote latency to low power"); - nrfx_gpiote_latency_set(NRF_GPIOTE_LATENCY_LOWPOWER); + nrf_gpiote_latency_set(NRF_GPIOTE, NRF_GPIOTE_LATENCY_LOWPOWER); } return 0; diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi index ada32e709ac..6804c040d12 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_nrf5340_cpunet-pinctrl.dtsi @@ -26,4 +26,21 @@ }; }; + spi0_default: spi0_default { + group1 { + psels = , + , + ; + }; + }; + + spi0_sleep: spi0_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + }; 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 16aa4179fa9..22a05cac020 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 @@ -24,6 +24,46 @@ zephyr,code-partition = &slot0_partition; watchdog0 = &wdt0; }; + + 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 9 0>, /* D0 */ + <7 0 &gpio1 8 0>, /* D1 */ + <8 0 &gpio0 31 0>, /* D2 */ + <9 0 &gpio1 0 0>, /* D3 */ + <10 0 &gpio1 1 0>, /* D4 */ + <11 0 &gpio1 14 0>, /* D5 */ + <12 0 &gpio1 7 0>, /* D6 */ + <13 0 &gpio1 11 0>, /* D7 */ + <14 0 &gpio1 10 0>, /* D8 */ + <15 0 &gpio1 13 0>, /* D9 */ + <16 0 &gpio1 12 0>, /* D10 */ + <17 0 &gpio0 9 0>, /* D11 */ + <18 0 &gpio0 10 0>, /* D12 */ + <19 0 &gpio0 8 0>, /* D13 */ + <20 0 &gpio1 2 0>, /* D14 */ + <21 0 &gpio1 3 0>; /* D15 */ + }; + +}; + +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"; }; &gpiote { diff --git a/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt index 8ba3238c40b..5128462d70c 100644 --- a/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt +++ b/boards/arm/nrf5340dk_nrf5340/CMakeLists.txt @@ -8,7 +8,7 @@ zephyr_library_sources(nrf5340_cpunet_reset.c) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board new file mode 100644 index 00000000000..b76cfce6800 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.board @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54H20PDK_NRF54H20_CPUAPP + bool "nRF54H20 PDK nRF54H20 Application MCU" + depends on SOC_NRF54H20_ENGA_CPUAPP + +config BOARD_NRF54H20PDK_NRF54H20_CPURAD + bool "nRF54H20 PDK nRF54H20 Radio MCU" + depends on SOC_NRF54H20_ENGA_CPURAD diff --git a/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig new file mode 100644 index 00000000000..954276ec829 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "nrf54h20pdk_nrf54h20_cpuapp" if BOARD_NRF54H20PDK_NRF54H20_CPUAPP + default "nrf54h20pdk_nrf54h20_cpurad" if BOARD_NRF54H20PDK_NRF54H20_CPURAD + +if BOARD_NRF54H20PDK_NRF54H20_CPUAPP || BOARD_NRF54H20PDK_NRF54H20_CPURAD + +# Data cache is disabled due to a HW issue in the EngA SoC revision. +config DCACHE + default n + +endif # BOARD_NRF54H20PDK_NRF54H20_CPUAPP || BOARD_NRF54H20PDK_NRF54H20_CPURAD diff --git a/boards/arm/nrf54h20pdk_nrf54h20/board.cmake b/boards/arm/nrf54h20pdk_nrf54h20/board.cmake new file mode 100644 index 00000000000..4c63f1dd05e --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp b/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp new file mode 100644 index 00000000000..bcda6b0732b Binary files /dev/null and b/boards/arm/nrf54h20pdk_nrf54h20/doc/img/nrf54h20pdk_nrf54h20.webp differ diff --git a/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst b/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst new file mode 100644 index 00000000000..985e8d36d88 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/doc/index.rst @@ -0,0 +1,148 @@ +.. _nrf54h20pdk_nrf54h20: + +nRF54H20 PDK +############ + +Overview +******** + +The nRF54H20 PDK is a single-board preview development kit for evaluation +and development on the Nordic nRF54H20 System-on-Chip (SoC). + +The nRF54H20 is a multicore SoC with: + +* an Arm Cortex-M33 core with DSP instructions, FPU, and Armv8-M Security + Extensions, running at up to 320 MHz, referred to as the **application core** +* an Arm Cortex-M33 core with DSP instructions, FPU, and Armv8-M Security + Extensions, running at up to 256 MHz, referred to as the **radio core**. + +The ``nrf54h20pdk_nrf54h20_cpuapp`` build target provides support for +the application core on the nRF54H20 SoC. +The ``nrf54h20pdk_nrf54h20_cpurad`` build target provides support for +the radio core on the nRF54H20 SoC. + +nRF54H20 SoC provides support for the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`GPIOTE (General Purpose Input Output tasks and events)` +* :abbr:`GRTC (Global real-time counter)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* MRAM +* :abbr:`PWM (Pulse Width Modulation)` +* RADIO (Bluetooth Low Energy and 802.15.4) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UART (Universal asynchronous receiver-transmitter)` +* :abbr:`USB (Universal Serial Bus)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf54h20pdk_nrf54h20.webp + :align: center + :alt: nRF54H20 PDK + + nRF54H20 PDK (Credit: Nordic Semiconductor) + +Hardware +******** + +nRF54H20 PDK has two crystal oscillators: + +* High-frequency 32 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +Supported Features +================== + +The nrf54h20pdk_nrf54h20_cpuapp board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIOTE | on-chip | gpio | ++-----------+------------+----------------------+ +| GRTC | on-chip | system clock | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ + +The nrf54h20pdk_nrf54h20_cpurad board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIOTE | on-chip | gpio | ++-----------+------------+----------------------+ +| GRTC | on-chip | system clock | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Connections and IOs +=================== + +LEDs +---- + +* LED1 (green) = P9.0 +* LED2 (green) = P9.1 +* LED3 (green) = P9.2 +* LED4 (green) = P9.3 + +Push buttons +------------ + +* BUTTON1 = P0.8 +* BUTTON2 = P0.9 +* BUTTON3 = P0.10 +* BUTTON4 = P0.11 +* RESET (SW1) + +Programming and Debugging +************************* + +Applications for both the ``nrf54h20pdk_nrf54h20_cpuapp`` and +``nrf54h20pdk_nrf54h20_cpurad`` targets 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 +======== + +As an example, this section shows how to build and flash the :ref:`hello_world` +application. + +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`. + +To build and program the sample to the nRF54H20 PDK, complete the following steps: + +First, connect the nRF54H20 PDK to you computer using the IMCU USB port on the PDK. +Next, build the sample by running the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf54h20pdk_nrf54h20_cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF54H20 PDK +************************************************ + +There are 2 samples that allow you to test that the buttons (switches) and LEDs +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/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts`. diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-ipc_conf.dtsi b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-ipc_conf.dtsi new file mode 100644 index 00000000000..9c3d971b9bc --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-ipc_conf.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + ipc { + cpusec_cpuapp_ipc: ipc-1-2 { + compatible = "zephyr,ipc-icmsg"; + status = "disabled"; + mboxes = <&cpusec_bellboard 12>, + <&cpuapp_bellboard 0>; + }; + + cpusec_cpurad_ipc: ipc-1-3 { + compatible = "zephyr,ipc-icmsg"; + status = "disabled"; + mboxes = <&cpusec_bellboard 18>, + <&cpurad_bellboard 0>; + }; + + cpuapp_cpurad_ipc: ipc-2-3 { + status = "disabled"; + mboxes = <&cpuapp_bellboard 18>, + <&cpurad_bellboard 12>; + }; + + cpuapp_cpuppr_ipc: ipc-2-13 { + compatible = "zephyr,ipc-icmsg"; + status = "disabled"; + mboxes = <&cpuapp_bellboard 13>, + <&cpuppr_vevif 12>; + }; + }; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi new file mode 100644 index 00000000000..560700b1756 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-memory_map.dtsi @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + reserved-memory { + cpuapp_ram0x_region: memory@2f000000 { + compatible = "nordic,owned-memory"; + reg = <0x2f000000 DT_SIZE_K(260)>; + status = "disabled"; + perm-read; + perm-write; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2f000000 0x41000>; + + cpusec_cpuapp_ipc_shm: memory@0 { + reg = <0x0 DT_SIZE_K(2)>; + }; + + cpuapp_cpusec_ipc_shm: memory@800 { + reg = <0x800 DT_SIZE_K(2)>; + }; + + cpuapp_data: memory@1000 { + reg = <0x1000 DT_SIZE_K(256)>; + }; + }; + + cpurad_ram0x_region: memory@2f041000 { + compatible = "nordic,owned-memory"; + reg = <0x2f041000 DT_SIZE_K(4)>; + status = "disabled"; + perm-read; + perm-write; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2f041000 0x1000>; + + cpusec_cpurad_ipc_shm: memory@0 { + reg = <0x0 DT_SIZE_K(2)>; + }; + + cpurad_cpusec_ipc_shm: memory@800 { + reg = <0x800 DT_SIZE_K(2)>; + }; + }; + + cpuapp_cpurad_ram0x_region: memory@2f0bf000 { + compatible = "nordic,owned-memory"; + reg = <0x2f0bf000 DT_SIZE_K(4)>; + status = "disabled"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2f0bf000 0x1000>; + + cpuapp_cpurad_ipc_shm: memory@0 { + reg = <0x0 DT_SIZE_K(2)>; + }; + + cpurad_cpuapp_ipc_shm: memory@800 { + reg = <0x800 DT_SIZE_K(2)>; + }; + }; + + shared_ram20_region: memory@2f88f000 { + compatible = "nordic,owned-memory"; + reg = <0x2f88f000 DT_SIZE_K(4)>; + status = "disabled"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2f88f000 0x1000>; + + cpuapp_cpusys_ipc_shm: memory@ce0 { + reg = <0xce0 0x80>; + }; + + cpusys_cpuapp_ipc_shm: memory@d60 { + reg = <0xd60 0x80>; + }; + + cpurad_cpusys_ipc_shm: memory@e00 { + reg = <0xe00 0x80>; + }; + + cpusys_cpurad_ipc_shm: memory@e80 { + reg = <0xe80 0x80>; + }; + }; + + cpuppr_ram3x_region: memory@2fc00000 { + compatible = "nordic,owned-memory"; + reg = <0x2fc00000 DT_SIZE_K(28)>; + status = "disabled"; + perm-read; + perm-write; + perm-execute; + }; + + shared_ram3x_region: memory@2fc07000 { + compatible = "nordic,owned-memory"; + reg = <0x2fc07000 DT_SIZE_K(4)>; + status = "disabled"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x2fc07000 0x1000>; + + cpuapp_cpuppr_ipc_shm: memory@0 { + reg = <0x0 0x340>; + }; + + cpuppr_cpuapp_ipc_shm: memory@340 { + reg = <0x340 0x340>; + }; + + cpuapp_dma_region: memory@680 { + compatible = "zephyr,memory-region"; + reg = <0x680 DT_SIZE_K(2)>; + status = "disabled"; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM3x_APP"; + }; + + cpurad_dma_region: memory@e80 { + compatible = "zephyr,memory-region"; + reg = <0xe80 0x80>; + status = "disabled"; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM3x_RAD"; + }; + }; + }; +}; + +&mram1x { + cpurad_rx_partitions: cpurad-rx-partitions { + compatible = "nordic,owned-partitions", "fixed-partitions"; + status = "disabled"; + perm-read; + perm-execute; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + + cpurad_slot0_partition: partition@66000 { + reg = <0x66000 DT_SIZE_K(256)>; + }; + }; + + cpuapp_rx_partitions: cpuapp-rx-partitions { + compatible = "nordic,owned-partitions", "fixed-partitions"; + status = "disabled"; + perm-read; + perm-execute; + perm-secure; + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_slot0_partition: partition@a6000 { + reg = <0xa6000 DT_SIZE_K(512)>; + }; + + cpuppr_code_partition: partition@126000 { + reg = <0x126000 DT_SIZE_K(64)>; + }; + }; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi new file mode 100644 index 00000000000..d3b79120322 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20-pinctrl.dtsi @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + /omit-if-no-ref/ uart135_default: uart135_default { + group1 { + psels = , + ; + }; + + group2 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart135_sleep: uart135_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; + + /omit-if-no-ref/ uart136_default: uart136_default { + group1 { + psels = , + ; + }; + + group2 { + bias-pull-up; + psels = , + ; + }; + }; + + /omit-if-no-ref/ uart136_sleep: uart136_sleep { + group1 { + low-power-enable; + psels = , + , + , + ; + }; + }; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts new file mode 100644 index 00000000000..b2db9e4b9b1 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.dts @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-ipc_conf.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/delete-node/ &cpusec_cpurad_ipc; + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpuapp"; + model = "Nordic nRF54H20 PDK nRF54H20 Application MCU"; + + chosen { + zephyr,console = &uart136; + zephyr,code-partition = &cpuapp_slot0_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpuapp_data; + }; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; + + buttons { + compatible = "gpio-keys"; + + button0: button_0 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + + button1: button_1 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + + button2: button_2 { + gpios = <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + + button3: button_3 { + gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio9 0 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + + led1: led_1 { + gpios = <&gpio9 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + + led2: led_2 { + gpios = <&gpio9 2 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + + led3: led_3 { + gpios = <&gpio9 3 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; +}; + +&cpuapp_ram0x_region { + status = "okay"; +}; + +&shared_ram3x_region { + status = "okay"; +}; + +&cpuapp_bellboard { + interrupts = <96 NRF_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "irq0"; + /* irq0: 0: cpuapp-cpusec, 13: cpuapp-cpuppr, 18: cpuapp-cpurad */ + nordic,interrupt-mapping = <0x00042001 0>; +}; + +&cpusec_cpuapp_ipc { + mbox-names = "tx", "rx"; + tx-region = <&cpuapp_cpusec_ipc_shm>; + rx-region = <&cpusec_cpuapp_ipc_shm>; +}; + +&cpuapp_cpurad_ipc { + compatible = "zephyr,ipc-icmsg-me-initiator"; + mbox-names = "rx", "tx"; + tx-region = <&cpuapp_cpurad_ipc_shm>; + rx-region = <&cpurad_cpuapp_ipc_shm>; +}; + +&cpuapp_cpuppr_ipc { + mbox-names = "rx", "tx"; + tx-region = <&cpuapp_cpuppr_ipc_shm>; + rx-region = <&cpuppr_cpuapp_ipc_shm>; +}; + +&cpuapp_dma_region { + status = "okay"; +}; + +&cpuapp_rx_partitions { + status = "okay"; +}; + +&cpuppr_vpr { + execution-memory = <&cpuppr_code_partition>; +}; + +&gpiote130 { + status = "okay"; + owned-channels = <0 1 2 3 4 5 6 7>; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio9 { + status = "okay"; +}; + +&grtc { + status = "okay"; + child-owned-channels = <5 6>; + nonsecure-channels = <5 6>; + owned-channels = <4 5 6>; +}; + +&uart135 { + current-speed = <115200>; + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + status = "okay"; + memory-regions = <&cpuapp_dma_region>; + current-speed = <115200>; + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml new file mode 100644 index 00000000000..a364c2863d3 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpuapp +name: nRF54H20-PDK-nRF54H20-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 32 +flash: 368 +supported: + - gpio diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig new file mode 100644 index 00000000000..1f7ef38a7fc --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuapp_defconfig @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPUAPP=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPUAPP=y + +CONFIG_USE_DT_CODE_PARTITION=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot be applied +# as the (0x0 - 0x400) region is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# Enable GPIO +CONFIG_GPIO=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts new file mode 100644 index 00000000000..8d2629df62e --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.dts @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-ipc_conf.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/delete-node/ &cpuapp_cpuppr_ipc; +/delete-node/ &cpusec_cpuapp_ipc; + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpurad"; + model = "Nordic nRF54H20 PDK nRF54H20 Radio MCU"; + + chosen { + zephyr,console = &uart135; + zephyr,code-partition = &cpurad_slot0_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpurad_ram0; + }; +}; + +&shared_ram3x_region { + status = "okay"; +}; + +&cpurad_bellboard { + interrupts = <96 NRF_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "irq0"; + /* irq0: 0: cpurad-cpusec, 12: cpurad-cpuapp */ + nordic,interrupt-mapping = <0x00001001 0>; +}; + +&cpusec_cpurad_ipc { + mbox-names = "tx", "rx"; + tx-region = <&cpurad_cpusec_ipc_shm>; + rx-region = <&cpusec_cpurad_ipc_shm>; +}; + +&cpuapp_cpurad_ipc { + compatible = "zephyr,ipc-icmsg-me-follower"; + mbox-names = "tx", "rx"; + tx-region = <&cpurad_cpuapp_ipc_shm>; + rx-region = <&cpuapp_cpurad_ipc_shm>; +}; + +&cpurad_dma_region { + status = "okay"; +}; + +&cpurad_rx_partitions { + status = "okay"; +}; + +&grtc { + status = "okay"; + child-owned-channels = <8 9 10 11 12>; + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>, + <108 NRF_DEFAULT_IRQ_PRIORITY>; + nonsecure-channels = <8 9 10 11 12>; + owned-channels = <7 8 9 10 11 12 13 14>; +}; + +&uart135 { + status = "okay"; + memory-regions = <&cpurad_dma_region>; + current-speed = <115200>; + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + current-speed = <115200>; + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml new file mode 100644 index 00000000000..d1c8548d07d --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpurad +name: nRF54H20-PDK-nRF54H20-Radio +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 32 +flash: 368 +supported: + - gpio diff --git a/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig new file mode 100644 index 00000000000..254d8656e61 --- /dev/null +++ b/boards/arm/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpurad_defconfig @@ -0,0 +1,30 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPURAD=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPURAD=y + +CONFIG_USE_DT_CODE_PARTITION=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot be applied +# as the (0x0 - 0x400) region is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board new file mode 100644 index 00000000000..d95fe51009f --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54L15PDK_NRF54L15_CPUAPP + bool "nRF54L15 PDK nRF54L15 Application MCU" + depends on SOC_NRF54L15_ENGA_CPUAPP diff --git a/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig new file mode 100644 index 00000000000..3e47a0bb583 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF54L15PDK_NRF54L15_CPUAPP + +config BOARD + default "nrf54l15pdk_nrf54l15_cpuapp" + +config BT_CTLR + default BT + +config ROM_START_OFFSET + hex + default 0x800 if BOOTLOADER_MCUBOOT + +endif # BOARD_NRF54L15PDK_NRF54L15_CPUAPP diff --git a/boards/arm/nrf54l15pdk_nrf54l15/board.cmake b/boards/arm/nrf54l15pdk_nrf54l15/board.cmake new file mode 100644 index 00000000000..378b7bcdb57 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/board.cmake @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp b/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp new file mode 100644 index 00000000000..80fb2060a07 Binary files /dev/null and b/boards/arm/nrf54l15pdk_nrf54l15/doc/img/nrf54l15pdk_nrf54l15.webp differ diff --git a/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst b/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst new file mode 100644 index 00000000000..fa896f98398 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/doc/index.rst @@ -0,0 +1,134 @@ +.. _nrf54l15pdk_nrf54l15: + +nRF54L15 PDK +############ + +Overview +******** + +The nRF54L15 Preview Development Kit hardware provides +support for the Nordic Semiconductor nRF54L15 Arm Cortex-M33 CPU and +the following devices: + +* :abbr:`SAADC (Successive Approximation Analog to Digital Converter)` +* CLOCK +* RRAM +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`TWIM (I2C-compatible two-wire interface master with EasyDMA)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* :abbr:`GRTC (Global real-time counter)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter)` +* :abbr:`WDT (Watchdog Timer)` + +.. figure:: img/nrf54l15pdk_nrf54l15.webp + :align: center + :alt: nRF54L15 PDK + + nRF54L15 PDK (Credit: Nordic Semiconductor) + +Hardware +******** + +nRF54L15 PDK has two crystal oscillators: + +* High-frequency 32 MHz crystal oscillator (HFXO) +* Low-frequency 32.768 kHz crystal oscillator (LFXO) + +The crystal oscillators can be configured to use either +internal or external capacitors. + +Supported Features +================== + +The nrf54l15pdk_nrf54l15 board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| SAADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| RRAM | on-chip | flash | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| TWIM | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| GRTC | on-chip | counter | ++-----------+------------+----------------------+ +| RTT | Segger | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Programming and Debugging +************************* + +Applications for the ``nrf54l15pdk_nrf54l15_cpuapp`` board 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 +======== + +As an example, this section shows how to build and flash the :ref:`hello_world` +application. + +.. warning:: + + When programming the device, you might get an error similar to the following message:: + + ERROR: The operation attempted is unavailable due to readback protection in + ERROR: your device. Please use --recover to unlock the device. + + This error occurs when readback protection is enabled. + To disable the readback protection, you must *recover* your device. + + Enter the following command to recover the core:: + + west flash --recover + + The ``--recover`` command erases the flash memory and then writes a small binary into + the recovered flash memory. + This binary prevents the readback protection from enabling itself again after a pin + reset or power cycle. + +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`. + +To build and program the sample to the nRF54L15 PDK, complete the following steps: + +First, connect the nRF54L15 PDK to you computer using the IMCU USB port on the PDK. +Next, build the sample by running the following command: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: nrf54l15pdk_nrf54l15_cpuapp + :goals: build flash + +Testing the LEDs and buttons in the nRF54L15 PDK +************************************************ + +Test the nRF54L15 PDK with a :zephyr:code-sample:`blinky` sample. diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi new file mode 100644 index 00000000000..02b02bc8171 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart20_default: uart20_default { + group1 { + psels = , + ; + }; + }; + + uart20_sleep: uart20_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart30_default: uart30_default { + group1 { + psels = , + ; + }; + }; + + uart30_sleep: uart30_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts new file mode 100644 index 00000000000..9876e3996e8 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.dts @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf54l15pdk_nrf54l15_cpuapp-pinctrl.dtsi" +#include + +/ { + model = "Nordic nRF54L15 PDK nRF54L15 Application MCU"; + compatible = "nordic,nrf54l15pdk_nrf54l15-cpuapp"; + + chosen { + zephyr,console = &uart20; + zephyr,shell-uart = &uart20; + zephyr,uart-mcumgr = &uart20; + zephyr,sram = &sram0; + zephyr,flash = &rram0; + zephyr,code-partition = &slot0_partition; + zephyr,ieee802154 = &ieee802154; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Green LED 0"; + }; + led1: led_1 { + gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led2: led_2 { + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led3: led_3 { + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio1 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 0"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpio1 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + button2: button_2 { + gpios = <&gpio2 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + button3: button_3 { + gpios = <&gpio2 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + }; + + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + watchdog0 = &wdt30; + sw0 = &button0; + sw1 = &button1; + sw2 = &button2; + sw3 = &button3; + }; +}; + +&lfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15500>; +}; + +&hfxo { + load-capacitors = "internal"; + load-capacitance-femtofarad = <15000>; +}; + +&uart20 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart20_default>; + pinctrl-1 = <&uart20_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart30 { + current-speed = <115200>; + pinctrl-0 = <&uart30_default>; + pinctrl-1 = <&uart30_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&grtc { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&gpio2 { + status = "okay"; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpiote30 { + status = "okay"; +}; + +&rram0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x0 DT_SIZE_K(64)>; + }; + slot0_partition: partition@10000 { + label = "image-0"; + reg = <0x10000 DT_SIZE_K(348)>; + }; + slot0_ns_partition: partition@67000 { + label = "image-0-nonsecure"; + reg = <0x67000 DT_SIZE_K(348)>; + }; + slot1_partition: partition@be000 { + label = "image-1"; + reg = <0xbe000 DT_SIZE_K(348)>; + }; + slot1_ns_partition: partition@115000 { + label = "image-1-nonsecure"; + reg = <0x115000 DT_SIZE_K(348)>; + }; + /* 32k from 0x16c000 to 0x173fff reserved for TF-M partitions */ + storage_partition: partition@174000 { + label = "storage"; + reg = <0x174000 DT_SIZE_K(36)>; + }; + }; +}; + +&clock { + status = "okay"; +}; diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml new file mode 100644 index 00000000000..de5ce29d162 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54l15pdk_nrf54l15_cpuapp +name: nRF54l15-PDK-nRF54l15-Application +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 256 +flash: 1536 +supported: + - gpio + - i2c + - spi + - watchdog + - i2s diff --git a/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig new file mode 100644 index 00000000000..bc74c3eeb33 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/nrf54l15pdk_nrf54l15_cpuapp_defconfig @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54LX=y +CONFIG_SOC_NRF54L15_ENGA_CPUAPP=y +CONFIG_BOARD_NRF54L15PDK_NRF54L15_CPUAPP=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot +# be applied as the (0x0 - 0x400) is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable Cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +CONFIG_UART_CONSOLE=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y + +# Enable GPIO +CONFIG_GPIO=y + +CONFIG_SOC_NRF_FORCE_CONSTLAT=y + +# Start SYSCOUNTER on driver init +CONFIG_NRF_GRTC_START_SYSCOUNTER=y diff --git a/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake b/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake new file mode 100644 index 00000000000..4fe5b260db3 --- /dev/null +++ b/boards/arm/nrf54l15pdk_nrf54l15/revision.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +board_check_revision(FORMAT MAJOR.MINOR.PATCH + VALID_REVISIONS 0.2.0 + DEFAULT_REVISION 0.2.0) 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- diff --git a/boards/arm/nrf9151dk_nrf9151/Kconfig.board b/boards/arm/nrf9151dk_nrf9151/Kconfig.board new file mode 100644 index 00000000000..92352ddc16f --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/Kconfig.board @@ -0,0 +1,14 @@ +# nRF9151 DK NRF9151 board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9151_LACA + +config BOARD_NRF9151DK_NRF9151 + bool "nRF9151 DK NRF9151" + +config BOARD_NRF9151DK_NRF9151_NS + bool "nRF9151 DK NRF9151 non-secure" + +endif # SOC_NRF9151_LACA diff --git a/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig b/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig new file mode 100644 index 00000000000..3cbff101d63 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/Kconfig.defconfig @@ -0,0 +1,47 @@ +# nRF9151 DK NRF9151 board configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_NRF9151DK_NRF9151 || BOARD_NRF9151DK_NRF9151_NS + +config BOARD + default "nrf9151dk_nrf9151" + +# 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_NRF9151DK_NRF9151 && TRUSTED_EXECUTION_SECURE + +if BOARD_NRF9151DK_NRF9151_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_NRF9151DK_NRF9151_NS + +config BT_HCI_VS + default y if BT + +config BT_WAIT_NOP + default BT && $(dt_nodelabel_enabled,nrf5340_reset) + +config I2C + default $(dt_compat_on_bus,$(DT_COMPAT_NXP_PCAL6408A),i2c) + +endif # BOARD_NRF9151DK_NRF9151 || BOARD_NRF9151DK_NRF9151_NS diff --git a/boards/arm/nrf9151dk_nrf9151/board.cmake b/boards/arm/nrf9151dk_nrf9151/board.cmake new file mode 100644 index 00000000000..a3126c941d9 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/board.cmake @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_BOARD_NRF9151DK_NRF9151_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 nRF9151_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/nrf9151dk_nrf9151/doc/index.rst b/boards/arm/nrf9151dk_nrf9151/doc/index.rst new file mode 100644 index 00000000000..91e9b75ad9c --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/doc/index.rst @@ -0,0 +1,200 @@ +.. _nrf9151dk_nrf9151: + +nRF9151 DK +########## + +Overview +******** + +The nRF9151 DK (PCA10171) is a single-board development kit for evaluation and +development on the nRF9151 SiP for DECT NR+ and LTE-M/NB-IoT with GNSS. The nrf9151dk_nrf9151 +board configuration provides support for the Nordic Semiconductor nRF9151 ARM +Cortex-M33F CPU with ARMv8-M Security Extension and the following devices: + +* :abbr:`ADC (Analog to Digital Converter)` +* CLOCK +* FLASH +* :abbr:`GPIO (General Purpose Input Output)` +* :abbr:`I2C (Inter-Integrated Circuit)` +* :abbr:`MPU (Memory Protection Unit)` +* :abbr:`NVIC (Nested Vectored Interrupt Controller)` +* :abbr:`PWM (Pulse Width Modulation)` +* :abbr:`RTC (nRF RTC System Clock)` +* Segger RTT (RTT Console) +* :abbr:`SPI (Serial Peripheral Interface)` +* :abbr:`UARTE (Universal asynchronous receiver-transmitter with EasyDMA)` +* :abbr:`WDT (Watchdog Timer)` +* :abbr:`IDAU (Implementation Defined Attribution Unit)` + +More information about the board can be found at the `nRF9151 website`_. + + +Hardware +******** + +nRF9151 DK has two external oscillators. The frequency of +the slow clock is 32.768 kHz. The frequency of the main clock +is 32 MHz. + +Supported Features +================== + +The nrf9151dk_nrf9151 board configuration supports the following +hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| ADC | on-chip | adc | ++-----------+------------+----------------------+ +| CLOCK | on-chip | clock_control | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash | ++-----------+------------+----------------------+ +| FLASH | external | spi | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| GPIO | external | i2c | ++-----------+------------+----------------------+ +| I2C(M) | on-chip | i2c | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PWM | on-chip | pwm | ++-----------+------------+----------------------+ +| RTC | on-chip | system clock | ++-----------+------------+----------------------+ +| RTT | nRF53 | console | ++-----------+------------+----------------------+ +| SPI(M/S) | on-chip | spi | ++-----------+------------+----------------------+ +| SPU | on-chip | system protection | ++-----------+------------+----------------------+ +| UARTE | on-chip | serial | ++-----------+------------+----------------------+ +| WDT | on-chip | watchdog | ++-----------+------------+----------------------+ + + +.. _nrf9151dk_additional_hardware: + +Other hardware features have not been enabled yet for this board. +See the `nRF9151 website`_ for more information. + +Connections and IOs +=================== + +LED +--- + +* LED1 (green) = P0.0 +* LED2 (green) = P0.1 +* LED3 (green) = P0.4 +* LED4 (green) = P0.5 + +Push buttons and Switches +------------------------- + +* BUTTON1 = P0.8 +* BUTTON2 = P0.9 +* SWITCH1 = P0.18 +* SWITCH2 = P0.19 +* BOOT = SW5 = boot/reset + +Security components +=================== + +- Implementation Defined Attribution Unit (`IDAU`_). 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 +************************* + +nrf9151dk_nrf9151 supports the Armv8m Security Extension, and by default boots +in the Secure state. + +Building Secure/Non-Secure Zephyr applications with Arm |reg| TrustZone |reg| +============================================================================= + +The process requires the following steps: + +1. Build the Secure Zephyr application using ``-DBOARD=nrf9151dk_nrf9151`` and + ``CONFIG_TRUSTED_EXECUTION_SECURE=y`` in the application project configuration file. +2. Build the Non-Secure Zephyr application using ``-DBOARD=nrf9151dk_nrf9151_ns``. +3. Merge the two binaries together. + +When building a Secure/Non-Secure application, the Secure application will +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. + +Building a Secure only application +================================== + +Build the Zephyr app in the usual way (see :ref:`build_an_application` +and :ref:`application_run`), using ``-DBOARD=nrf9151dk_nrf9151``. + +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. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ minicom -D -b 115200 + +Replace :code:`` with the port where the nRF9151 DK +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: nrf9151dk_nrf9151 + :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 nRF9151 DK +********************************************** + +There are 2 samples that allow you to test that the buttons (switches) and LEDs 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/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi`. + +References +********** + +.. target-notes:: + +.. _IDAU: + https://developer.arm.com/docs/100690/latest/attribution-units-sau-and-idau +.. _nRF9151 website: https://www.nordicsemi.com/Products/nRF9151 +.. _Nordic Semiconductor Infocenter: https://infocenter.nordicsemi.com +.. _Trusted Firmware M: https://www.trustedfirmware.org/projects/tf-m/ diff --git a/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml b/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml new file mode 100644 index 00000000000..2b51125312c --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/bindings/nordic,nrf9151dk-nrf5340-reset.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: GPIO used to reset nRF5340 on nRF9151 DK + +compatible: "nordic,nrf9151dk-nrf5340-reset" + +include: base.yaml + +properties: + status: + required: true + + gpios: + type: phandle-array + required: true + description: | + GPIO to use as nRF5340 reset line: output in nRF9151, input in nRF5340. diff --git a/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi new file mode 100644 index 00000000000..20f7d2406a5 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_buttons_on_io_expander.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pcal6408a { + status = "okay"; +}; + +&button0 { + gpios = <&pcal6408a 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button1 { + gpios = <&pcal6408a 1 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button2 { + gpios = <&pcal6408a 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; + +&button3 { + gpios = <&pcal6408a 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; +}; diff --git a/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi new file mode 100644 index 00000000000..d80c509d215 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/dts/nrf9151dk_leds_on_io_expander.dtsi @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pcal6408a { + status = "okay"; +}; + +&led0 { + gpios = <&pcal6408a 4 GPIO_ACTIVE_HIGH>; +}; + +&led1 { + gpios = <&pcal6408a 5 GPIO_ACTIVE_HIGH>; +}; + +&led2 { + gpios = <&pcal6408a 6 GPIO_ACTIVE_HIGH>; +}; + +&led3 { + gpios = <&pcal6408a 7 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts new file mode 100644 index 00000000000..8c3b4921434 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9151dk_nrf9151_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/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml new file mode 100644 index 00000000000..3ad90fea76d --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151.yaml @@ -0,0 +1,22 @@ +identifier: nrf9151dk_nrf9151 +name: nRF9151-DK-NRF9151 +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 88 +flash: 1024 +supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - gpio + - i2c + - pwm + - spi + - watchdog + - counter +vendor: nordic diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi new file mode 100644 index 00000000000..a1680e830f4 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common-pinctrl.dtsi @@ -0,0 +1,96 @@ +/* + * 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/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi new file mode 100644 index 00000000000..958e864c63c --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_common.dtsi @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "nrf9151dk_nrf9151_common-pinctrl.dtsi" +#include + +/ { + model = "Nordic nRF9151 DK NRF9151"; + compatible = "nordic,nrf9151-dk-nrf9151"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "Green LED 1"; + }; + led1: led_1 { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "Green LED 2"; + }; + led2: led_2 { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Green LED 3"; + }; + led3: led_3 { + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + label = "Green LED 4"; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + pwm_led0: pwm_led_0 { + pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>; + }; + }; + + buttons { + compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 8 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 1"; + zephyr,code = ; + }; + button1: button_1 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 2"; + zephyr,code = ; + }; + button2: button_2 { + gpios = <&gpio0 18 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 3"; + zephyr,code = ; + }; + button3: button_3 { + gpios = <&gpio0 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Push button 4"; + zephyr,code = ; + }; + }; + + nrf5340_reset: gpio-reset { + compatible = "nordic,nrf9151dk-nrf5340-reset"; + status = "disabled"; + gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; + }; + + 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 14 0>, /* A0 */ + <1 0 &gpio0 15 0>, /* A1 */ + <2 0 &gpio0 16 0>, /* A2 */ + <3 0 &gpio0 17 0>, /* A3 */ + <4 0 &gpio0 18 0>, /* A4 */ + <5 0 &gpio0 19 0>, /* A5 */ + <6 0 &gpio0 0 0>, /* D0 */ + <7 0 &gpio0 1 0>, /* D1 */ + <8 0 &gpio0 2 0>, /* D2 */ + <9 0 &gpio0 3 0>, /* D3 */ + <10 0 &gpio0 4 0>, /* D4 */ + <11 0 &gpio0 5 0>, /* D5 */ + <12 0 &gpio0 6 0>, /* D6 */ + <13 0 &gpio0 7 0>, /* D7 */ + <14 0 &gpio0 8 0>, /* D8 */ + <15 0 &gpio0 9 0>, /* D9 */ + <16 0 &gpio0 10 0>, /* D10 */ + <17 0 &gpio0 11 0>, /* D11 */ + <18 0 &gpio0 12 0>, /* D12 */ + <19 0 &gpio0 13 0>, /* D13 */ + <20 0 &gpio0 30 0>, /* D14 */ + <21 0 &gpio0 31 0>; /* D15 */ + }; + + arduino_adc: analog-connector { + compatible = "arduino,uno-adc"; + #io-channel-cells = <1>; + io-channel-map = <0 &adc 1>, /* A0 = P0.14 = AIN1 */ + <1 &adc 2>, /* A1 = P0.15 = AIN2 */ + <2 &adc 3>, /* A2 = P0.16 = AIN3 */ + <3 &adc 4>, /* A3 = P0.17 = AIN4 */ + <4 &adc 5>, /* A4 = P0.18 = AIN5 */ + <5 &adc 6>; /* A5 = P0.19 = AIN6 */ + }; + + /* 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; + 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"; +}; + +arduino_serial: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_default>; + pinctrl-1 = <&uart1_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_i2c: &i2c2 { + compatible = "nordic,nrf-twim"; + status = "okay"; + pinctrl-0 = <&i2c2_default>; + pinctrl-1 = <&i2c2_sleep>; + pinctrl-names = "default", "sleep"; + clock-frequency = ; + + pcal6408a: pcal6408a@21 { + compatible = "nxp,pcal6408a"; + status = "disabled"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + ngpios = <8>; + int-gpios = <&gpio0 19 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; +}; + +&pwm0 { + status = "okay"; + pinctrl-0 = <&pwm0_default>; + pinctrl-1 = <&pwm0_sleep>; + pinctrl-names = "default", "sleep"; +}; + +arduino_spi: &spi3 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>, /* D10 */ + <&gpio0 20 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi3_default>; + pinctrl-1 = <&spi3_sleep>; + pinctrl-names = "default", "sleep"; + + gd25wb256: gd25wb256e3ir@1 { + compatible = "jedec,spi-nor"; + status = "disabled"; + reg = <1>; + 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 "nrf9151dk_nrf9151_partition_conf.dtsi" diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig new file mode 100644 index 00000000000..7afe5ac7aa9 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_defconfig @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9151_LACA=y +CONFIG_BOARD_NRF9151DK_NRF9151=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 diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts new file mode 100644 index 00000000000..a41c4aad388 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.dts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "nrf9151dk_nrf9151_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/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml new file mode 100644 index 00000000000..c5d4fe92541 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns.yaml @@ -0,0 +1,20 @@ +identifier: nrf9151dk_nrf9151_ns +name: nRF9151-DK-NRF9151-Non-Secure +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +ram: 128 +flash: 192 +supported: + - arduino_gpio + - arduino_i2c + - arduino_serial + - arduino_spi + - i2c + - pwm + - watchdog + - netif:modem +vendor: nordic diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig new file mode 100644 index 00000000000..949ef39f856 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_ns_defconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF91X=y +CONFIG_SOC_NRF9151_LACA=y +CONFIG_BOARD_NRF9151DK_NRF9151_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 diff --git a/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi new file mode 100644 index 00000000000..b209608a725 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/nrf9151dk_nrf9151_partition_conf.dtsi @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Default Flash planning for nRF9151dk_nrf9151. + * + * Zephyr build for nRF9151 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 nRF9151 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/nrf9151dk_nrf9151/pre_dt_board.cmake b/boards/arm/nrf9151dk_nrf9151/pre_dt_board.cmake new file mode 100644 index 00000000000..c8267afd1b4 --- /dev/null +++ b/boards/arm/nrf9151dk_nrf9151/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/boards/arm/nucleo_l552ze_q/CMakeLists.txt b/boards/arm/nucleo_l552ze_q/CMakeLists.txt index d170d283e99..260ecca2707 100644 --- a/boards/arm/nucleo_l552ze_q/CMakeLists.txt +++ b/boards/arm/nucleo_l552ze_q/CMakeLists.txt @@ -10,6 +10,6 @@ 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} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst index 51675477af4..fbf77de1c44 100644 --- a/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst +++ b/boards/arm/nucleo_l552ze_q/doc/nucleol552ze_q.rst @@ -338,7 +338,7 @@ can be generated using ``nucleo_l552ze_q_ns`` as build target. $ west build -b nucleo_l552ze_q_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/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. diff --git a/boards/arm/nucleo_u575zi_q/doc/index.rst b/boards/arm/nucleo_u575zi_q/doc/index.rst index 0de2c364ecf..e7035dd497a 100644 --- a/boards/arm/nucleo_u575zi_q/doc/index.rst +++ b/boards/arm/nucleo_u575zi_q/doc/index.rst @@ -308,7 +308,7 @@ can be generated using ``nucleo_u575zi_q_ns`` as build target. $ west build -b nucleo_u575zi_q_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/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. diff --git a/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt index c79a4b7b4e7..7c2da293e20 100644 --- a/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt +++ b/boards/arm/nucleo_u5a5zj_q/CMakeLists.txt @@ -9,6 +9,6 @@ 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} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/nucleo_u5a5zj_q/doc/index.rst b/boards/arm/nucleo_u5a5zj_q/doc/index.rst index f877be5c168..154dbd32579 100644 --- a/boards/arm/nucleo_u5a5zj_q/doc/index.rst +++ b/boards/arm/nucleo_u5a5zj_q/doc/index.rst @@ -342,7 +342,7 @@ can be generated using ``nucleo_u5a5zj_q_ns`` as build target. $ 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 +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/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. diff --git a/boards/arm/stm32l562e_dk/CMakeLists.txt b/boards/arm/stm32l562e_dk/CMakeLists.txt index dde73804665..f6ca91f1a73 100644 --- a/boards/arm/stm32l562e_dk/CMakeLists.txt +++ b/boards/arm/stm32l562e_dk/CMakeLists.txt @@ -10,6 +10,6 @@ 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} + COMMAND $/api_ns/postbuild.sh ${COMPILER_FULL_PATH} ) endif() diff --git a/boards/arm/stm32l562e_dk/doc/index.rst b/boards/arm/stm32l562e_dk/doc/index.rst index 5a4f5845617..0eb2aa7630c 100644 --- a/boards/arm/stm32l562e_dk/doc/index.rst +++ b/boards/arm/stm32l562e_dk/doc/index.rst @@ -340,7 +340,7 @@ can be generated using ``stm32l562e_dk_ns`` as build target. $ west build -b stm32l562e_dk_ns path/to/source/directory -Note: When building the ``*_ns`` image with TF-M, ``build/tfm/postbuild.sh`` bash script +Note: When building the ``*_ns`` image with TF-M, ``build/tfm/api_ns/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. diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index 708d9a05d51..45869075487 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -8,6 +8,12 @@ if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS config BOARD default "thingy53_nrf5340_cpuapp" +config BOOTLOADER_MCUBOOT + default y if !MCUBOOT + +config BOARD_ENABLE_CPUNET + default y if !MCUBOOT + # Code Partition: # # For the secure version of the board the firmware is linked at the beginning @@ -135,6 +141,13 @@ endif # LOG endif # BOARD_SERIAL_BACKEND_CDC_ACM +# By default, a USB CDC ACM instance is already enabled in the board's DTS. +# It is not necessary for nRF Connect SDK to add another instance if MCUBoot +# bootloader is built as a child image. +config MCUBOOT_USB_SUPPORT + bool + default n + endif # BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS if BOARD_THINGY53_NRF5340_CPUNET diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml new file mode 100644 index 00000000000..7a48d51ec33 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml @@ -0,0 +1,55 @@ +app: + address: 0x10200 + region: flash_primary + size: 0xdfe00 +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml new file mode 100644 index 00000000000..70ffe6d9c12 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml @@ -0,0 +1,73 @@ +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +tfm_secure: + address: 0x10000 + size: 0xc000 + span: [mcuboot_pad, tfm] +tfm_nonsecure: + address: 0x1c000 + size: 0xd4000 + span: [app] +tfm: + address: 0x10200 + region: flash_primary + size: 0xbe00 +app: + address: 0x1c000 + region: flash_primary + size: 0xd4000 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - tfm + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - tfm + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +nonsecure_storage: + address: 0xf0000 + size: 0x10000 + span: [settings_storage] +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi index 694a6960584..54efd588cf7 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dtsi @@ -16,6 +16,7 @@ zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; + nordic,pm-ext-flash = &mx25r64; }; buttons { diff --git a/boards/posix/nrf_bsim/Kconfig b/boards/posix/nrf_bsim/Kconfig index 7d67c44d284..d85b497f671 100644 --- a/boards/posix/nrf_bsim/Kconfig +++ b/boards/posix/nrf_bsim/Kconfig @@ -6,7 +6,7 @@ if SOC_SERIES_BSIM_NRFXX # used by Nordic SoCs, so to make the symbols defined in this file available for # 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" +source "soc/common/nordic_nrf/Kconfig.peripherals" endif # SOC_SERIES_BSIM_NRFXX diff --git a/boards/posix/nrf_bsim/Kconfig.defconfig b/boards/posix/nrf_bsim/Kconfig.defconfig index 6993048248c..0ee4c6ee2c1 100644 --- a/boards/posix/nrf_bsim/Kconfig.defconfig +++ b/boards/posix/nrf_bsim/Kconfig.defconfig @@ -93,4 +93,7 @@ config UART_CONSOLE endif # CONSOLE +config UART_NRFX_UARTE_LEGACY_SHIM + default y + endif # SOC_SERIES_BSIM_NRFXX diff --git a/boards/posix/nrf_bsim/board_soc.h b/boards/posix/nrf_bsim/board_soc.h index 1b7e7a85c0c..d75a187aa61 100644 --- a/boards/posix/nrf_bsim/board_soc.h +++ b/boards/posix/nrf_bsim/board_soc.h @@ -29,6 +29,7 @@ #include #include #include "cmsis.h" +#include "soc_nrf_common.h" #if defined(CONFIG_BOARD_NRF52_BSIM) #define OFFLOAD_SW_IRQ SWI0_EGU0_IRQn diff --git a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts index 36cbf9691b3..c5ec3c95af5 100644 --- a/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts +++ b/boards/posix/nrf_bsim/nrf5340bsim_nrf5340_cpuapp.dts @@ -45,9 +45,11 @@ }; chosen { + zephyr,entropy = &rng_hci; zephyr,flash = &flash0; zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; + zephyr,ieee802154 = &ieee802154; }; soc { diff --git a/boards/posix/nrf_bsim/soc/pinctrl_soc.h b/boards/posix/nrf_bsim/soc/pinctrl_soc.h new file mode 100644 index 00000000000..f0be0443d5b --- /dev/null +++ b/boards/posix/nrf_bsim/soc/pinctrl_soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H +#define BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H + +/* We reuse the real SOC's header: */ +#include "../soc/common/nordic_nrf/pinctrl_soc.h" + +#endif /* BOARDS_POSIX_NRF_BSIM_SOC_PINCTRL_SOC_H */ diff --git a/boards/posix/nrf_bsim/soc/soc_nrf_common.h b/boards/posix/nrf_bsim/soc/soc_nrf_common.h new file mode 100644 index 00000000000..a77778de653 --- /dev/null +++ b/boards/posix/nrf_bsim/soc/soc_nrf_common.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H +#define BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H + +/* We reuse the real SOC's header: */ +#include "../soc/arm/nordic_nrf/common/soc_nrf_common.h" + +#endif /* BOARDS_POSIX_NRF_BSIM_SOC_SOC_NRF_COMMON_H */ diff --git a/boards/riscv/adp_xc7k_ae350/Kconfig.board b/boards/riscv/adp_xc7k_ae350/Kconfig.board index 085eb9696a8..5b58e01fbfd 100644 --- a/boards/riscv/adp_xc7k_ae350/Kconfig.board +++ b/boards/riscv/adp_xc7k_ae350/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_ADP_XC7K_AE350 bool "Andes ADP-XC7K AE350 Platform" - depends on SOC_RISCV_ANDES_AE350 + depends on SOC_ANDES_AE350 diff --git a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig index 3f7f1f727c6..edbe7118c64 100644 --- a/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig +++ b/boards/riscv/adp_xc7k_ae350/adp_xc7k_ae350_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_ANDES_V5=y -CONFIG_SOC_RISCV_ANDES_AE350=y +CONFIG_SOC_SERIES_ANDES_AE350=y +CONFIG_SOC_ANDES_AE350=y CONFIG_BOARD_ADP_XC7K_AE350=y CONFIG_XIP=n CONFIG_CONSOLE=y diff --git a/boards/riscv/beaglev_fire/Kconfig.board b/boards/riscv/beaglev_fire/Kconfig.board new file mode 100644 index 00000000000..55b59d4ac92 --- /dev/null +++ b/boards/riscv/beaglev_fire/Kconfig.board @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_BEAGLEV_FIRE + bool "Beagleboard BeagleV-Fire" + depends on SOC_POLARFIRE + select 64BIT + select SCHED_IPI_SUPPORTED + select CPU_HAS_FPU_DOUBLE_PRECISION diff --git a/boards/riscv/beaglev_fire/Kconfig.defconfig b/boards/riscv/beaglev_fire/Kconfig.defconfig new file mode 100644 index 00000000000..df89660bcb6 --- /dev/null +++ b/boards/riscv/beaglev_fire/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "beaglev_fire" + depends on BOARD_BEAGLEV_FIRE diff --git a/boards/riscv/beaglev_fire/beaglev_fire.dts b/boards/riscv/beaglev_fire/beaglev_fire.dts new file mode 100644 index 00000000000..df956f5c8f2 --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Microchip Technology Inc + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include +#include + +/ { + model = "BeagleV-Fire"; + compatible = "beagle,beaglev-fire", "microchip,mpfs"; + aliases { + }; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,sram = &sram1; + }; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + clock-frequency = <150000000>; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/boards/riscv/beaglev_fire/beaglev_fire.yaml b/boards/riscv/beaglev_fire/beaglev_fire.yaml new file mode 100644 index 00000000000..64d34b454f8 --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire.yaml @@ -0,0 +1,12 @@ +identifier: beaglev_fire +name: Beagleboard BeagleV-Fire +type: mcu +arch: riscv64 +toolchain: + - zephyr +ram: 3840 +testing: + ignore_tags: + - net + - bluetooth +vendor: beagle diff --git a/boards/riscv/beaglev_fire/beaglev_fire_defconfig b/boards/riscv/beaglev_fire/beaglev_fire_defconfig new file mode 100644 index 00000000000..3b264d6c288 --- /dev/null +++ b/boards/riscv/beaglev_fire/beaglev_fire_defconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2023 Microchip Technology Inc +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_POLARFIRE=y +CONFIG_SOC_POLARFIRE=y +CONFIG_MPFS_HAL=n +CONFIG_BASE64=y +CONFIG_INCLUDE_RESET_VECTOR=y +CONFIG_BOARD_BEAGLEV_FIRE=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_RISCV_SOC_INTERRUPT_INIT=y +CONFIG_RISCV_HAS_PLIC=y +CONFIG_XIP=n +CONFIG_INIT_STACKS=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +CONFIG_FPU=n diff --git a/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp b/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp new file mode 100644 index 00000000000..a4ba6b0d98e Binary files /dev/null and b/boards/riscv/beaglev_fire/doc/img/BeagleV-Fire-Front-Annotated-768x432.webp differ diff --git a/boards/riscv/beaglev_fire/doc/img/board-booting.png b/boards/riscv/beaglev_fire/doc/img/board-booting.png new file mode 100644 index 00000000000..5be27ddfbb1 Binary files /dev/null and b/boards/riscv/beaglev_fire/doc/img/board-booting.png differ diff --git a/boards/riscv/beaglev_fire/doc/index.rst b/boards/riscv/beaglev_fire/doc/index.rst new file mode 100644 index 00000000000..88808145c9b --- /dev/null +++ b/boards/riscv/beaglev_fire/doc/index.rst @@ -0,0 +1,85 @@ +.. _beaglev_fire: + +BeagleV®-Fire +############# + +Overview +******** + +BeagleV®-Fire is a revolutionary single-board computer (SBC) powered by the Microchip’s +PolarFire® MPFS025T 5x core RISC-V System on Chip (SoC) with FPGA fabric. BeagleV®-Fire opens up new +horizons for developers, tinkerers, and the open-source community to explore the vast potential of +RISC-V architecture and FPGA technology. It has the same P8 & P9 cape header pins as BeagleBone +Black allowing you to stack your favorite BeagleBone cape on top to expand it’s capability. +Built around the powerful and energy-efficient RISC-V instruction set architecture (ISA) along with +its versatile FPGA fabric, BeagleV®-Fire SBC offers unparalleled opportunities for developers, +hobbyists, and researchers to explore and experiment with RISC-V technology. + +.. image:: img/BeagleV-Fire-Front-Annotated-768x432.webp + :align: center + :alt: beaglev_fire + +Building +======== + +Applications for the ``beaglev_fire`` board configuration can be built as usual: + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: beaglev_fire + :goals: build + +Debugging +========= + +In order to upload the application to the device, you'll need OpenOCD and GDB +with RISC-V support. +You can get them as a part of SoftConsole SDK. +Download and installation instructions can be found on +`Microchip's SoftConsole website +`_. + +You will also require a Debugger such as Microchip's FlashPro5/6. + +Connect to BeagleV-Fire UART debug port using a 3.3v USB to UART bridge. +Now you can run ``tio `` in a terminal window to access the UART debug port connection. Once you +are connected properly you can press the Reset button which will show you a progress bar like: + +.. image:: img/board-booting.png + :align: center + :alt: beaglev_fire + +Once you see that progress bar on your screen you can start pressing any button (0-9/a-z) which +will interrupt the Hart Software Services from booting its payload. + +With the necessary tools installed, you can connect to the board using OpenOCD. +from a different terminal, run: + +.. code-block:: bash + + /openocd/bin/openocd --file \ + /openocd/share/openocd/scripts/board/microsemi-riscv.cfg + + +Leave it running, and in a different terminal, use GDB to upload the binary to +the board. You can use the RISC-V GDB from the Zephyr SDK. +launch GDB: + +.. code-block:: bash + + /riscv64-zephyr-elf/bin/riscv64-zephyr-elf-gdb + + + +Here is the GDB terminal command to connect to the device +and load the binary: + +.. code-block:: bash + + set arch riscv:rv64 + set mem inaccessible-by-default off + file + target extended-remote localhost:3333 + load + break main + continue diff --git a/boards/riscv/esp32c3_devkitm/doc/index.rst b/boards/riscv/esp32c3_devkitm/doc/index.rst index 6d21b2918c3..26f1521e087 100644 --- a/boards/riscv/esp32c3_devkitm/doc/index.rst +++ b/boards/riscv/esp32c3_devkitm/doc/index.rst @@ -18,7 +18,7 @@ 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 +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh - Various peripherals: - 12-bit ADC with up to 6 channels diff --git a/boards/riscv/esp32c3_luatos_core/doc/index.rst b/boards/riscv/esp32c3_luatos_core/doc/index.rst index c943931a9e6..fae8e2eb178 100644 --- a/boards/riscv/esp32c3_luatos_core/doc/index.rst +++ b/boards/riscv/esp32c3_luatos_core/doc/index.rst @@ -18,7 +18,7 @@ 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 +- A Bluetooth LE subsystem that supports features of Bluetooth 5 and Bluetooth Mesh - Various peripherals: - 12-bit ADC with up to 6 channels diff --git a/boards/riscv/hifive1/Kconfig.board b/boards/riscv/hifive1/Kconfig.board index b5b32649441..d2f40472f24 100644 --- a/boards/riscv/hifive1/Kconfig.board +++ b/boards/riscv/hifive1/Kconfig.board @@ -2,4 +2,4 @@ config BOARD_HIFIVE1 bool "HiFive1 target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/hifive1/hifive1_defconfig b/boards/riscv/hifive1/hifive1_defconfig index d37ded2bb25..8e4e8e21c1a 100644 --- a/boards/riscv/hifive1/hifive1_defconfig +++ b/boards/riscv/hifive1/hifive1_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_HIFIVE1=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/hifive1_revb/Kconfig.board b/boards/riscv/hifive1_revb/Kconfig.board index d4c5b99ce72..b0bf1edd156 100644 --- a/boards/riscv/hifive1_revb/Kconfig.board +++ b/boards/riscv/hifive1_revb/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE1_REVB bool "HiFive1 Rev B target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/hifive1_revb/hifive1_revb_defconfig b/boards/riscv/hifive1_revb/hifive1_revb_defconfig index 4f691bd9435..b2119eecae9 100644 --- a/boards/riscv/hifive1_revb/hifive1_revb_defconfig +++ b/boards/riscv/hifive1_revb/hifive1_revb_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_HIFIVE1_REVB=y CONFIG_GPIO=y CONFIG_PINCTRL=y diff --git a/boards/riscv/hifive_unleashed/Kconfig.board b/boards/riscv/hifive_unleashed/Kconfig.board index 4766e0ea792..f6c623e9928 100644 --- a/boards/riscv/hifive_unleashed/Kconfig.board +++ b/boards/riscv/hifive_unleashed/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE_UNLEASHED bool "HiFive Unleashed target" - depends on SOC_RISCV_SIFIVE_FU540 + depends on SOC_SIFIVE_FREEDOM_U540 diff --git a/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig b/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig index 15c9e60d552..51d324d457d 100644 --- a/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig +++ b/boards/riscv/hifive_unleashed/hifive_unleashed_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FU540=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_U500=y +CONFIG_SOC_SIFIVE_FREEDOM_U540=y CONFIG_BOARD_HIFIVE_UNLEASHED=y CONFIG_CONSOLE=y CONFIG_GPIO=y diff --git a/boards/riscv/hifive_unmatched/Kconfig.board b/boards/riscv/hifive_unmatched/Kconfig.board index cf6ac1c8392..bb303cc3aac 100644 --- a/boards/riscv/hifive_unmatched/Kconfig.board +++ b/boards/riscv/hifive_unmatched/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_HIFIVE_UNMATCHED bool "HiFive Unmatched target" - depends on SOC_RISCV_SIFIVE_FU740 + depends on SOC_SIFIVE_FREEDOM_U740 diff --git a/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig b/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig index 654fdc1bf2a..be13ed10358 100644 --- a/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig +++ b/boards/riscv/hifive_unmatched/hifive_unmatched_defconfig @@ -1,5 +1,5 @@ -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FU740=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_U700=y +CONFIG_SOC_SIFIVE_FREEDOM_U740=y CONFIG_BOARD_HIFIVE_UNMATCHED=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig b/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig index f082e4a7bad..6866e3f633b 100644 --- a/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig +++ b/boards/riscv/it82xx2_evb/it82xx2_evb_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2023 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_SERIES_ITE_IT8XXX2=y CONFIG_SOC_IT8XXX2=y CONFIG_SOC_IT82202_AX=y CONFIG_BOARD_IT82XX2_EVB=y diff --git a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig index 21967527f8e..38a44d6f8f3 100644 --- a/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig +++ b/boards/riscv/it8xxx2_evb/it8xxx2_evb_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_IT8XXX2=y +CONFIG_SOC_SERIES_ITE_IT8XXX2=y CONFIG_SOC_IT8XXX2=y CONFIG_BOARD_IT8XXX2_EVB=y CONFIG_BOOT_DELAY=1 diff --git a/boards/riscv/m2gl025_miv/Kconfig.board b/boards/riscv/m2gl025_miv/Kconfig.board index 51c2f9d8de3..9f81fad406f 100644 --- a/boards/riscv/m2gl025_miv/Kconfig.board +++ b/boards/riscv/m2gl025_miv/Kconfig.board @@ -2,4 +2,4 @@ config BOARD_M2GL025_MIV bool "Microchip M2GL025 IGLOO2 dev board with Mi-V CPU" - depends on SOC_RISCV32_MIV + depends on SOC_MIV diff --git a/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig b/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig index 8c944a10a74..e33765680d5 100644 --- a/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig +++ b/boards/riscv/m2gl025_miv/m2gl025_miv_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV32_MIV=y -CONFIG_SOC_RISCV32_MIV=y +CONFIG_SOC_SERIES_MIV=y +CONFIG_SOC_MIV=y CONFIG_BOARD_M2GL025_MIV=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/mpfs_icicle/Kconfig.board b/boards/riscv/mpfs_icicle/Kconfig.board index 297f4ce4bc7..e772b82d7f5 100644 --- a/boards/riscv/mpfs_icicle/Kconfig.board +++ b/boards/riscv/mpfs_icicle/Kconfig.board @@ -3,7 +3,7 @@ config BOARD_MPFS_ICICLE bool "Microchip PolarFire SoC ICICLE kit" - depends on SOC_MPFS + depends on SOC_POLARFIRE select 64BIT select SCHED_IPI_SUPPORTED select CPU_HAS_FPU_DOUBLE_PRECISION diff --git a/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig b/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig index 5c41649cb3e..00b44f7a6d5 100644 --- a/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig +++ b/boards/riscv/mpfs_icicle/mpfs_icicle_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2020-2021 Microchip Technology Inc # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV64_MIV=y -CONFIG_SOC_MPFS=y +CONFIG_SOC_SERIES_POLARFIRE=y +CONFIG_SOC_POLARFIRE=y CONFIG_MPFS_HAL=n CONFIG_BASE64=y CONFIG_INCLUDE_RESET_VECTOR=y diff --git a/boards/riscv/neorv32/Kconfig.board b/boards/riscv/neorv32/Kconfig.board index eee37f4a8c3..6d85ebb2e40 100644 --- a/boards/riscv/neorv32/Kconfig.board +++ b/boards/riscv/neorv32/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_NEORV32 bool "NEORV32 Processor (SoC)" - depends on SOC_SERIES_NEORV32 + depends on SOC_NEORV32 diff --git a/boards/riscv/neorv32/neorv32_defconfig b/boards/riscv/neorv32/neorv32_defconfig index 17e9b8038ce..7dc8a74ffff 100644 --- a/boards/riscv/neorv32/neorv32_defconfig +++ b/boards/riscv/neorv32/neorv32_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_NEORV32=y +CONFIG_SOC_NEORV32=y CONFIG_SOC_NEORV32_ISA_C=y CONFIG_BOARD_NEORV32=y CONFIG_SERIAL=y diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board new file mode 100644 index 00000000000..9bbbba60dd4 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_NRF54H20PDK_NRF54H20_CPUPPR + bool "nRF54H20 PDK nRF54H20 PPR MCU" + depends on SOC_NRF54H20_ENGA_CPUPPR diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig new file mode 100644 index 00000000000..256976d6519 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "nrf54h20pdk_nrf54h20_cpuppr" + depends on BOARD_NRF54H20PDK_NRF54H20_CPUPPR diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake b/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake new file mode 100644 index 00000000000..4c63f1dd05e --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/board.cmake @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts new file mode 100644 index 00000000000..f98abb9e44b --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.dts @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "nrf54h20pdk_nrf54h20-memory_map.dtsi" +#include "nrf54h20pdk_nrf54h20-ipc_conf.dtsi" +#include "nrf54h20pdk_nrf54h20-pinctrl.dtsi" + +/delete-node/ &cpuapp_cpurad_ipc; +/delete-node/ &cpusec_cpuapp_ipc; +/delete-node/ &cpusec_cpurad_ipc; + +/ { + compatible = "nordic,nrf54h20pdk_nrf54h20-cpuppr"; + model = "Nordic nRF54H20 PDK nRF54H20 Peripheral Processor MCU"; + #address-cells = <1>; + #size-cells = <1>; + + chosen { + zephyr,console = &uart135; + zephyr,code-partition = &cpuppr_code_partition; + zephyr,flash = &mram1x; + zephyr,sram = &cpuppr_ram3x_region; + }; +}; + +&cpuapp_cpuppr_ipc { + mbox-names = "tx", "rx"; + tx-region = <&cpuppr_cpuapp_ipc_shm>; + rx-region = <&cpuapp_cpuppr_ipc_shm>; +}; + +&grtc { + status = "okay"; + owned-channels = <5>; +}; + +&uart135 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart135_default>; + pinctrl-1 = <&uart135_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&uart136 { + current-speed = <115200>; + pinctrl-0 = <&uart136_default>; + pinctrl-1 = <&uart136_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml new file mode 100644 index 00000000000..274be865c36 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20pdk_nrf54h20_cpuppr +name: nRF54H20-PDK-nRF54H20-PPR +type: mcu +arch: riscv +toolchain: + - zephyr +ram: 28 +flash: 28 +supported: + - gpio diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig new file mode 100644 index 00000000000..112140693ef --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/nrf54h20pdk_nrf54h20_cpuppr_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF54HX=y +CONFIG_SOC_NRF54H20=y +CONFIG_SOC_NRF54H20_ENGA_CPUPPR=y +CONFIG_BOARD_NRF54H20PDK_NRF54H20_CPUPPR=y + +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake b/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake new file mode 100644 index 00000000000..5e0fecebdc8 --- /dev/null +++ b/boards/riscv/nrf54h20pdk_nrf54h20/pre_dt_board.cmake @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Allow common DTS files to be included from the other board directory. +# To be removed after HWMv2 (#51831), once both directories can be merged into one. +string(REGEX REPLACE "/riscv/(.*$)" "/arm/\\1" BOARD_DIR_ARM "${BOARD_DIR}") +list(APPEND DTS_EXTRA_CPPFLAGS -isystem "${BOARD_DIR_ARM}") diff --git a/boards/riscv/opentitan_earlgrey/Kconfig.board b/boards/riscv/opentitan_earlgrey/Kconfig.board index ec7f735b442..544c02b1b2a 100644 --- a/boards/riscv/opentitan_earlgrey/Kconfig.board +++ b/boards/riscv/opentitan_earlgrey/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_OPENTITAN_EARLGREY bool "OpenTitan Earl Grey Target" - depends on SOC_RISCV_OPENTITAN + depends on SOC_OPENTITAN diff --git a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig index 79299c3892f..886e439b88a 100644 --- a/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig +++ b/boards/riscv/opentitan_earlgrey/opentitan_earlgrey_defconfig @@ -1,8 +1,7 @@ # Copyright (c) 2023 by Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_OPENTITAN=y -CONFIG_SOC_RISCV_OPENTITAN=y +CONFIG_SOC_OPENTITAN=y CONFIG_BOARD_OPENTITAN_EARLGREY=y CONFIG_XIP=y CONFIG_SERIAL=y diff --git a/boards/riscv/qemu_riscv32/Kconfig.board b/boards/riscv/qemu_riscv32/Kconfig.board index 989fa13b453..7c94b59455c 100644 --- a/boards/riscv/qemu_riscv32/Kconfig.board +++ b/boards/riscv/qemu_riscv32/Kconfig.board @@ -22,7 +22,7 @@ config BOARD_QEMU_RISCV32_SMP config BOARD_QEMU_RISCV32_XIP bool "QEMU RISCV32 XIP target" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 select QEMU_TARGET select HAS_COVERAGE_SUPPORT select CPU_HAS_FPU diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig index f50d82dcb76..946e679a6e8 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig index eef7d03e356..90f87ef6b98 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_smp_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32_SMP=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig b/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig index 2cd0b2cbecb..948fa909a08 100644 --- a/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig +++ b/boards/riscv/qemu_riscv32/qemu_riscv32_xip_defconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_QEMU_RISCV32_XIP=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig b/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig index ef4d6273cfb..1f1c46acb10 100644 --- a/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig +++ b/boards/riscv/qemu_riscv32e/qemu_riscv32e_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV32E=y CONFIG_CONSOLE=y diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig index 6f51da3c592..6bfc46ac907 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV64=y CONFIG_PRIVILEGED_STACK_SIZE=2048 diff --git a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig index 78b5b74de9a..265d84a1ded 100644 --- a/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig +++ b/boards/riscv/qemu_riscv64/qemu_riscv64_smp_defconfig @@ -1,6 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_VIRT=y CONFIG_SOC_RISCV_VIRT=y CONFIG_BOARD_QEMU_RISCV64_SMP=y CONFIG_PRIVILEGED_STACK_SIZE=2048 diff --git a/boards/riscv/riscv32_virtual/Kconfig.board b/boards/riscv/riscv32_virtual/Kconfig.board new file mode 100644 index 00000000000..c8722acb384 --- /dev/null +++ b/boards/riscv/riscv32_virtual/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RISCV32_VIRTUAL + bool "riscv32_virtual" + depends on SOC_RISCV32_VIRTUAL_RENODE diff --git a/boards/riscv/riscv32_virtual/Kconfig.defconfig b/boards/riscv/riscv32_virtual/Kconfig.defconfig new file mode 100644 index 00000000000..840b10fd594 --- /dev/null +++ b/boards/riscv/riscv32_virtual/Kconfig.defconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config BOARD + default "riscv32_virtual" + depends on BOARD_RISCV32_VIRTUAL diff --git a/boards/riscv/riscv32_virtual/board.cmake b/boards/riscv/riscv32_virtual/board.cmake new file mode 100644 index 00000000000..cc177a69ce9 --- /dev/null +++ b/boards/riscv/riscv32_virtual/board.cmake @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +set(SUPPORTED_EMU_PLATFORMS renode) +set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/riscv32_virtual.resc) +set(RENODE_UART sysbus.uart0) diff --git a/boards/riscv/riscv32_virtual/doc/index.rst b/boards/riscv/riscv32_virtual/doc/index.rst new file mode 100644 index 00000000000..a53384f5331 --- /dev/null +++ b/boards/riscv/riscv32_virtual/doc/index.rst @@ -0,0 +1,56 @@ +.. _riscv32-virtual: + +RISCV32 Virtual +############### + +Overview +******** + +The RISCV32 Virtual board is a virtual platform made with Renode as an alternative to QEMU. +Contrary to QEMU, the peripherals of this platform can be easily configured by editing the +``riscv32_virtual.repl`` script and the devicetree files accordingly, this allows certain hardware +configurations that only exist in proprietary boards/SoCs to be tested in upstream CI. + +Programming and debugging +************************* + +Building +======== + +Applications for the ``riscv32_virtual`` board configuration can be built as usual +(see :ref:`build_an_application`): + +.. zephyr-app-commands:: + :board: riscv32_virtual + :goals: build + +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 Renode +emulated environment. For example, with the :zephyr:code-sample:`synchronization` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/synchronization + :host-os: unix + :board: riscv32_virtual + :goals: run + +This will build an image with the synchronization sample app, boot it using +Renode, and display the following console output: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.5.0-1511-g56f73bde0fb0 *** + thread_a: Hello World from cpu 0 on riscv32_virtual! + thread_b: Hello World from cpu 0 on riscv32_virtual! + thread_a: Hello World from cpu 0 on riscv32_virtual! + thread_b: Hello World from cpu 0 on riscv32_virtual! + +Exit Renode by pressing :kbd:`CTRL+C`. + +Debugging +========= + +Refer to the detailed overview about :ref:`application_debugging`. diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual.dts b/boards/riscv/riscv32_virtual/riscv32_virtual.dts new file mode 100644 index 00000000000..326b9757518 --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include + +/ { + model = "Renode RISCV32 Virtual target"; + compatible = "renode,riscv32-virtual"; + + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,flash = &flash0; + zephyr,sram = &sram0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual.yaml b/boards/riscv/riscv32_virtual/riscv32_virtual.yaml new file mode 100644 index 00000000000..11cefb035df --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual.yaml @@ -0,0 +1,16 @@ +identifier: riscv32_virtual +name: Renode RISC-V 32-bit Virtual Board +type: mcu +arch: riscv32 +toolchain: + - zephyr +ram: 4096 +flash: 4096 +simulation: renode +simulation_exec: renode +testing: + ignore_tags: + - net + - bluetooth +supported: + - uart diff --git a/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig b/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig new file mode 100644 index 00000000000..4dcad0a7ea1 --- /dev/null +++ b/boards/riscv/riscv32_virtual/riscv32_virtual_defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_RISCV32_VIRTUAL_RENODE=y +CONFIG_BOARD_RISCV32_VIRTUAL=y +CONFIG_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_GPIO=n +CONFIG_XIP=y + +# Workaround for incorrect SYS_CLOCK_HW_CYCLES_PER_SEC +CONFIG_SYS_CLOCK_TICKS_PER_SEC=100 diff --git a/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl b/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl new file mode 100644 index 00000000000..e0df808631b --- /dev/null +++ b/boards/riscv/riscv32_virtual/support/riscv32_virtual.repl @@ -0,0 +1,33 @@ +// Copyright (c) 2023 Meta +// SPDX-License-Identifier: Apache-2.0 + +flash: Memory.MappedMemory @ sysbus 0x80000000 + size: 0x400000 + +ddr: Memory.MappedMemory @ sysbus 0x80400000 + size: 0x400000 + +uart0: UART.NS16550 @ sysbus 0x10000000 + IRQ -> plic0@10 + +uart1: UART.NS16550 @ sysbus 0x10000100 + IRQ -> plic1@10 + +cpu: CPU.RiscV32 @ sysbus + cpuType: "rv32imac_zicsr_zifencei" + privilegeArchitecture: PrivilegeArchitecture.Priv1_10 + timeProvider: clint + +plic0: IRQControllers.PlatformLevelInterruptController @ sysbus 0x0C000000 + 0 -> cpu@11 + numberOfSources: 1023 + numberOfContexts: 1 + +plic1: IRQControllers.PlatformLevelInterruptController @ sysbus 0x08000000 + 0 -> cpu@4 + numberOfSources: 1023 + numberOfContexts: 1 + +clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x02000000 + [0,1] -> cpu@[3,7] + frequency: 4000000 diff --git a/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc b/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc new file mode 100644 index 00000000000..87e327287b6 --- /dev/null +++ b/boards/riscv/riscv32_virtual/support/riscv32_virtual.resc @@ -0,0 +1,17 @@ +:name: RISCV32-Virtual +:description: This script is prepared to run Zephyr on a Renode RISCV32 board. + +$name?="RISCV32-Virtual" + +using sysbus +mach create $name +machine LoadPlatformDescription $ORIGIN/riscv32_virtual.repl + +showAnalyzer uart0 +cpu PerformanceInMips 4 + +macro reset +""" + sysbus LoadELF $bin +""" +runMacro $reset diff --git a/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board b/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board index 34f852dc0ec..cc9e7b4f935 100644 --- a/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board +++ b/boards/riscv/sparkfun_red_v_things_plus/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_SPARKFUN_RED_V_THINGS_PLUS bool "SparkFun RED-V Things Plus board" - depends on SOC_RISCV_SIFIVE_FREEDOM + depends on SOC_SIFIVE_FREEDOM_E340 diff --git a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig index de3d18bcfde..8cf24ffbe09 100644 --- a/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig +++ b/boards/riscv/sparkfun_red_v_things_plus/sparkfun_red_v_things_plus_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2022 TOKITA Hiroshi # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y -CONFIG_SOC_RISCV_SIFIVE_FREEDOM=y +CONFIG_SOC_SERIES_SIFIVE_FREEDOM_E300=y +CONFIG_SOC_SIFIVE_FREEDOM_E340=y CONFIG_BOARD_SPARKFUN_RED_V_THINGS_PLUS=y CONFIG_GPIO=y CONFIG_PINCTRL=y diff --git a/boards/riscv/titanium_ti60_f225/Kconfig.board b/boards/riscv/titanium_ti60_f225/Kconfig.board index d6ed41ffc79..bac70816b20 100644 --- a/boards/riscv/titanium_ti60_f225/Kconfig.board +++ b/boards/riscv/titanium_ti60_f225/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_TITANIUM_TI60_F225 bool "Board with Efinix Sapphire riscv SoC" - depends on SOC_SERIES_EFINIX_SAPPHIRE + depends on SOC_EFINIX_SAPPHIRE diff --git a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig index 096980b864e..0608a8e8953 100644 --- a/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig +++ b/boards/riscv/titanium_ti60_f225/titanium_ti60_f225_defconfig @@ -1,7 +1,7 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_EFINIX_SAPPHIRE=y +CONFIG_SOC_EFINIX_SAPPHIRE=y CONFIG_BOARD_TITANIUM_TI60_F225=y CONFIG_CONSOLE=y CONFIG_SERIAL=y diff --git a/boards/riscv/tlsr9518adk80d/Kconfig.board b/boards/riscv/tlsr9518adk80d/Kconfig.board index bd36cb0e481..971b34dc13b 100644 --- a/boards/riscv/tlsr9518adk80d/Kconfig.board +++ b/boards/riscv/tlsr9518adk80d/Kconfig.board @@ -3,4 +3,4 @@ config BOARD_TLSR9518ADK80D bool "Telink B91 Platform" - depends on SOC_RISCV_TELINK_B91 + depends on SOC_TELINK_TLSR9518 diff --git a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig index fe5cfbe8c2e..c4cfdfea718 100644 --- a/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig +++ b/boards/riscv/tlsr9518adk80d/tlsr9518adk80d_defconfig @@ -1,8 +1,8 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -CONFIG_SOC_SERIES_RISCV_TELINK_B91=y -CONFIG_SOC_RISCV_TELINK_B91=y +CONFIG_SOC_SERIES_TELINK_TLSR951X=y +CONFIG_SOC_TELINK_TLSR9518=y CONFIG_BOARD_TLSR9518ADK80D=y CONFIG_GPIO=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 diff --git a/cmake/bintools/gnu/target.cmake b/cmake/bintools/gnu/target.cmake index 86c66b4825c..612f6de79b2 100644 --- a/cmake/bintools/gnu/target.cmake +++ b/cmake/bintools/gnu/target.cmake @@ -5,8 +5,13 @@ find_program(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_AS ${CROSS_COMPILE}as PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_AR ${CROSS_COMPILE}ar PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) -find_program(CMAKE_RANLIB ${CROSS_COMPILE}ranlib PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +if(CONFIG_LTO) + find_program(CMAKE_AR ${CROSS_COMPILE}gcc-ar PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + find_program(CMAKE_RANLIB ${CROSS_COMPILE}gcc-ranlib PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +else() + find_program(CMAKE_AR ${CROSS_COMPILE}ar PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) + find_program(CMAKE_RANLIB ${CROSS_COMPILE}ranlib PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +endif() find_program(CMAKE_READELF ${CROSS_COMPILE}readelf PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_NM ${CROSS_COMPILE}nm PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) find_program(CMAKE_STRIP ${CROSS_COMPILE}strip PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index 5b1dbde49c6..8e79d32387f 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -21,6 +21,9 @@ endif() set_compiler_property(PROPERTY optimization_speed -O2) set_compiler_property(PROPERTY optimization_size -Os) +set_compiler_property(PROPERTY optimization_lto -flto) +set_compiler_property(PROPERTY prohibit_lto -fno-lto) + ####################################################### # This section covers flags related to warning levels # ####################################################### diff --git a/cmake/linker/ld/linker_flags.cmake b/cmake/linker/ld/linker_flags.cmake index 8209f4dfbdc..5660b410760 100644 --- a/cmake/linker/ld/linker_flags.cmake +++ b/cmake/linker/ld/linker_flags.cmake @@ -12,6 +12,8 @@ endif() set_property(TARGET linker PROPERTY partial_linking "-r") +set_property(TARGET linker PROPERTY lto_arguments -flto -fno-ipa-sra -ffunction-sections -fdata-sections) + # Some linker flags might not be purely ld specific, but a combination of # linker and compiler, such as: # --coverage for clang diff --git a/cmake/linker_script/arm/linker.cmake b/cmake/linker_script/arm/linker.cmake index 0c7310ab905..332d44b2435 100644 --- a/cmake/linker_script/arm/linker.cmake +++ b/cmake/linker_script/arm/linker.cmake @@ -16,10 +16,17 @@ math(EXPR FLASH_ADDR OUTPUT_FORMAT HEXADECIMAL ) -math(EXPR FLASH_SIZE - "(${CONFIG_FLASH_SIZE} + 0) * 1024 - (${CONFIG_FLASH_LOAD_OFFSET} + 0)" - OUTPUT_FORMAT HEXADECIMAL -) +if(CONFIG_FLASH_LOAD_SIZE GREATER 0) + math(EXPR FLASH_SIZE + "(${CONFIG_FLASH_LOAD_SIZE} + 0) - (${CONFIG_ROM_END_OFFSET} + 0)" + OUTPUT_FORMAT HEXADECIMAL + ) +else() + math(EXPR FLASH_SIZE + "(${CONFIG_FLASH_SIZE} + 0) * 1024 - (${CONFIG_FLASH_LOAD_OFFSET} + 0) - (${CONFIG_ROM_END_OFFSET} + 0)" + OUTPUT_FORMAT HEXADECIMAL + ) +endif() set(RAM_ADDR ${CONFIG_SRAM_BASE_ADDRESS}) math(EXPR RAM_SIZE "(${CONFIG_SRAM_SIZE} + 0) * 1024" OUTPUT_FORMAT HEXADECIMAL) diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index a116977ce8c..7e639043bce 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -128,3 +128,7 @@ if(CONFIG_USB_HOST_STACK) zephyr_iterable_section(NAME usbh_contex GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME usbh_class_data GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) endif() + +if(CONFIG_DEVICE_MUTABLE) + zephyr_iterable_section(NAME device_mutable GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +endif() diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 632e9a72422..51dd9a0bed0 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -133,6 +133,8 @@ set(COMMON_KCONFIG_ENV_SETTINGS srctree=${ZEPHYR_BASE} KERNELVERSION=${KERNELVERSION} APPVERSION=${APP_VERSION_STRING} + APP_VERSION_EXTENDED_STRING=${APP_VERSION_EXTENDED_STRING} + APP_VERSION_TWEAK_STRING=${APP_VERSION_TWEAK_STRING} CONFIG_=${KCONFIG_NAMESPACE}_ KCONFIG_CONFIG=${DOTCONFIG} # Set environment variables so that Kconfig can prune Kconfig source @@ -147,6 +149,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} 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/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 550d236a2f4..6f8950c5f64 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -59,6 +59,7 @@ function(zephyr_process_snippets) # Set SNIPPET_ROOT. list(APPEND SNIPPET_ROOT ${APPLICATION_SOURCE_DIR}) list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) + list(APPEND SNIPPET_ROOT ${ZEPHYR_NRF_MODULE_DIR}) unset(real_snippet_root) foreach(snippet_dir ${SNIPPET_ROOT}) # The user might have put a symbolic link in here, for example. diff --git a/cmake/modules/version.cmake b/cmake/modules/version.cmake index 49d172871e7..4c80c5fcdc9 100644 --- a/cmake/modules/version.cmake +++ b/cmake/modules/version.cmake @@ -11,8 +11,10 @@ # # Outputs with examples:: # -# PROJECT_VERSION 1.14.99.07 -# KERNEL_VERSION_STRING "1.14.99-extraver" +# PROJECT_VERSION 1.14.99.07 +# KERNEL_VERSION_STRING "1.14.99-extraver" +# KERNEL_VERSION_EXTENDED_STRING "1.14.99-extraver+7" +# KERNEL_VERSION_TWEAK_STRING "1.14.99+7" # # KERNEL_VERSION_MAJOR 1 # KERNEL_VERSION_MINOR 14 @@ -62,9 +64,9 @@ foreach(type file IN ZIP_LISTS VERSION_TYPE VERSION_FILE) string(REGEX MATCH "EXTRAVERSION = ([a-z0-9]*)" _ ${ver}) set(${type}_VERSION_EXTRA ${CMAKE_MATCH_1}) - # Temporary convenience variable + # Temporary convenience variables set(${type}_VERSION_WITHOUT_TWEAK ${${type}_VERSION_MAJOR}.${${type}_VERSION_MINOR}.${${type}_PATCHLEVEL}) - + set(${type}_VERSION_WITH_TWEAK ${${type}_VERSION_MAJOR}.${${type}_VERSION_MINOR}.${${type}_PATCHLEVEL}+${${type}_VERSION_TWEAK}) set(MAJOR ${${type}_VERSION_MAJOR}) # Temporary convenience variable set(MINOR ${${type}_VERSION_MINOR}) # Temporary convenience variable @@ -82,6 +84,8 @@ foreach(type file IN ZIP_LISTS VERSION_TYPE VERSION_FILE) else() set(${type}_VERSION_STRING "${${type}_VERSION_WITHOUT_TWEAK}") endif() + set(${type}_VERSION_TWEAK_STRING "${${type}_VERSION_WITH_TWEAK}") + set(${type}_VERSION_EXTENDED_STRING "${${type}_VERSION_STRING}+${${type}_VERSION_TWEAK}") if(type STREQUAL KERNEL) set(PROJECT_VERSION_MAJOR ${${type}_VERSION_MAJOR}) @@ -118,5 +122,7 @@ foreach(type file IN ZIP_LISTS VERSION_TYPE VERSION_FILE) unset(MAJOR) unset(MINOR) unset(PATCH) + unset(TWEAK) unset(${type}_VERSION_WITHOUT_TWEAK) + unset(${type}_VERSION_WITH_TWEAK) endforeach() diff --git a/doc/_extensions/zephyr/domain.py b/doc/_extensions/zephyr/domain.py index 8c395142818..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 @@ -249,7 +255,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 +273,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, @@ -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/_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" diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 57dd7828978..cc7658a1664 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -7,8 +7,7 @@ The :ref:`menuconfig and guiconfig interfaces ` can be used to test out configurations during application development. This page explains how to make settings permanent. -All Kconfig options can be searched in the :ref:`Kconfig search page -`. +All Kconfig options can be searched in the Kconfig search page. .. note:: @@ -115,8 +114,7 @@ Assignments in configuration files are only respected if the dependencies for the symbol are satisfied. A warning is printed otherwise. To figure out what the dependencies of a symbol are, use one of the :ref:`interactive configuration interfaces ` (you can jump directly to a symbol with -:kbd:`/`), or look up the symbol in the :ref:`Kconfig search page -`. +:kbd:`/`), or look up the symbol in the Kconfig search page. .. _initial-conf: diff --git a/doc/build/version/index.rst b/doc/build/version/index.rst index 8d169a85bf5..2106a65e169 100644 --- a/doc/build/version/index.rst +++ b/doc/build/version/index.rst @@ -73,85 +73,120 @@ To use the version information in application code, the version file must be inc fields can be freely used. The include file name is :file:`app_version.h` (no path is needed), the following defines are available: -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| Define | Type | Field(s) | Example | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APPVERSION | Numerical | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | -| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | -| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | -| | | ``VERSION_TWEAK`` | | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_NUMBER | Numerical | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | -| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | -| | | ``PATCHLEVEL`` | | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_VERSION_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable" | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` |br| | | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ -| APP_BUILD_VERSION | String (unquoted) | None (value of ``git describe --abbrev=12 --always`` | v3.3.0-18-g2c85d9224fca | -| | | from application repository) | | -+--------------------+-------------------+------------------------------------------------------+-------------------------+ ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| Define | Type | Field(s) | Example | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APPVERSION | Numerical | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_NUMBER | Numerical | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_EXTENDED_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable+4" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` |br| | | +| | | ``VERSION_TWEAK`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_TWEAK_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3+4" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` |br| | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_BUILD_VERSION | String (unquoted) | None (value of ``git describe --abbrev=12 --always`` | v3.3.0-18-g2c85d9224fca | +| | | from application repository) | | ++-----------------------------+-------------------+------------------------------------------------------+-------------------------+ Use in Kconfig ============== The following variables are available for usage in Kconfig files: -+------------------+-----------+-------------------------+----------------+ -| Variable | Type | Field(s) | Example | -+------------------+-----------+-------------------------+----------------+ -| $(VERSION_MAJOR) | Numerical | ``VERSION_MAJOR`` | 1 | -+------------------+-----------+-------------------------+----------------+ -| $(VERSION_MINOR) | Numerical | ``VERSION_MINOR`` | 2 | -+------------------+-----------+-------------------------+----------------+ -| $(PATCHLEVEL) | Numerical | ``PATCHLEVEL`` | 3 | -+------------------+-----------+-------------------------+----------------+ -| $(VERSION_TWEAK) | Numerical | ``VERSION_TWEAK`` | 4 | -+------------------+-----------+-------------------------+----------------+ -| $(APPVERSION) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` | | -+------------------+-----------+-------------------------+----------------+ ++--------------------------------+-----------+--------------------------+------------------+ +| Variable | Type | Field(s) | Example | ++--------------------------------+-----------+--------------------------+------------------+ +| $(VERSION_MAJOR) | Numerical | ``VERSION_MAJOR`` | 1 | ++--------------------------------+-----------+--------------------------+------------------+ +| $(VERSION_MINOR) | Numerical | ``VERSION_MINOR`` | 2 | ++--------------------------------+-----------+--------------------------+------------------+ +| $(PATCHLEVEL) | Numerical | ``PATCHLEVEL`` | 3 | ++--------------------------------+-----------+--------------------------+------------------+ +| $(VERSION_TWEAK) | Numerical | ``VERSION_TWEAK`` | 4 | ++--------------------------------+-----------+--------------------------+------------------+ +| $(APPVERSION) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++--------------------------------+-----------+--------------------------+------------------+ +| $(APP_VERSION_EXTENDED_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION``, |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------------------+-----------+--------------------------+------------------+ +| $(APP_VERSION_TWEAK_STRING) | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------------------+-----------+--------------------------+------------------+ Use in CMake ============ The following variable are available for usage in CMake files: -+--------------------+-----------------+---------------------------------------------------+----------------+ -| Variable | Type | Field(s) | Example | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APPVERSION | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | -| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | -| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | -| | | ``VERSION_TWEAK`` | | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_VERSION_NUMBER | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | -| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | -| | | ``PATCHLEVEL`` | | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | -+--------------------+-----------------+---------------------------------------------------+----------------+ -| APP_VERSION_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | -| | | ``VERSION_MINOR``, |br| | | -| | | ``PATCHLEVEL``, |br| | | -| | | ``EXTRAVERSION`` | | -+--------------------+-----------------+---------------------------------------------------+----------------+ ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| Variable | Type | Field(s) | Example | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APPVERSION | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_NUMBER | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_EXTENDED_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION``, |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ +| APP_VERSION_TWEAK_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3+4 | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``VERSION_TWEAK`` | | ++-----------------------------+-----------------+---------------------------------------------------+------------------+ Use in MCUboot-supported applications ===================================== @@ -159,6 +194,3 @@ Use in MCUboot-supported applications No additional configuration needs to be done to the target application so long as it is configured to support MCUboot and a signed image is generated, the version information will be automatically included in the image data. - -The format used for signing is ``VERSION_MAJOR`` . ``VERSION_MINOR`` . ``PATCHLEVEL``, the tweak -version field is not currently used. 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") diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index 457aa5b6895..358ba3dc62e 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -3,14 +3,11 @@ Bluetooth Mesh Profile ###################### -The Bluetooth mesh profile adds secure wireless multi-hop communication for +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 Protocol Specification v1.1 `_. -Implementation of the `Bluetooth Mesh Protocol Specification v1.1 `_ -is in experimental state. - -Read more about Bluetooth mesh on the +Read more about Bluetooth Mesh on the `Bluetooth SIG Website `_. .. toctree:: diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 2af8e6a03b8..7af8ca7ec68 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -3,7 +3,7 @@ Access layer ############ -The access layer is the application's interface to the Bluetooth mesh network. +The access layer is the application's interface to the Bluetooth Mesh network. The access layer provides mechanisms for compartmentalizing the node behavior into elements and models, which are implemented by the application. @@ -113,7 +113,7 @@ number within one publication interval. Extended models =============== -The Bluetooth mesh specification allows the mesh models to extend each other. +The Bluetooth Mesh specification allows the mesh models to extend each other. When a model extends another, it inherits that model's functionality, and extension can be used to construct complex models out of simple ones, leveraging the existing model functionality to avoid defining new opcodes. @@ -168,15 +168,6 @@ needs to be stored. 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 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 @@ -222,6 +213,54 @@ They are used to represent the new content of the mirrored pages when the Compos change after a firmware update. See :ref:`bluetooth_mesh_dfu_srv_comp_data_and_models_metadata` for details. +Delayable messages +================== + +The delayable message functionality is enabled with Kconfig option +:kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG`. +This is an optional functionality that implements specification recommendations for +messages that are transmitted by a model in a response to a received message, also called +response messages. + +Response messages should be sent with the following random delays: + +* Between 20 and 50 milliseconds if the received message was sent + to a unicast address +* Between 20 and 500 milliseconds if the received message was sent + to a group or virtual address + +The delayable message functionality is triggered if the :c:member:`bt_mesh_msg_ctx.rnd_delay` +flag is set. +The delayable message functionality stores messages in the local memory while they are +waiting for the random delay expiration. + +If the transport layer doesn't have sufficient memory to send a message at the moment +the random delay expires, the message is postponed for another 10 milliseconds. +If the transport layer cannot send a message for any other reason, the delayable message +functionality raises the :c:member:`bt_mesh_send_cb.start` callback with a transport layer +error code. + +If the delayable message functionality cannot find enough free memory to store an incoming +message, it will send messages with delay close to expiration to free memory. + +When the mesh stack is suspended or reset, messages not yet sent are removed and +the :c:member:`bt_mesh_send_cb.start` callback is raised with an error code. + +Delayable publications +====================== + +The delayable publication functionality implements the specification recommendations for message +publication delays in the following cases: + +* Between 20 to 500 milliseconds when the Bluetooth Mesh stack starts or when the publication is + triggered by the :c:func:`bt_mesh_model_publish` function +* Between 20 to 50 milliseconds for periodically published messages + +This feature is optional and enabled with the :kconfig:option:`CONFIG_BT_MESH_DELAYABLE_PUBLICATION` +Kconfig option. When enabled, each model can enable or disable the delayable publication by setting +the :c:member:`bt_mesh_model_pub.delayable` bit field to ``1`` or ``0`` correspondingly. This bit +field can be changed at any time. + API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/blob.rst b/doc/connectivity/bluetooth/api/mesh/blob.rst index 31f45289560..8395026afe4 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob.rst @@ -5,7 +5,7 @@ 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 +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. @@ -50,7 +50,7 @@ structure of the BLOB, and applications are free to define any encoding or compr 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 +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. @@ -68,7 +68,7 @@ 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 +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 diff --git a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst index 25b90c281c4..b4193d50334 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_cli.rst @@ -67,7 +67,7 @@ Target nodes having the BLOB Transfer Server model subscribe to this group addre 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 +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 diff --git a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst index 918b9493ff9..0d13e92148e 100644 --- a/doc/connectivity/bluetooth/api/mesh/blob_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/blob_srv.rst @@ -77,7 +77,7 @@ 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 +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 diff --git a/doc/connectivity/bluetooth/api/mesh/cfg.rst b/doc/connectivity/bluetooth/api/mesh/cfg.rst index 01d3c9ca2e5..e178984210d 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg.rst @@ -6,7 +6,7 @@ Runtime Configuration The runtime configuration API allows applications to change their runtime configuration directly, without going through the Configuration models. -Bluetooth mesh nodes should generally be configured by a central network +Bluetooth Mesh nodes should generally be configured by a central network configurator device with a :ref:`bluetooth_mesh_models_cfg_cli` model. Each mesh node instantiates a :ref:`bluetooth_mesh_models_cfg_srv` model that the Configuration Client can communicate with to change the node configuration. In some diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst index bf84edc6b86..300c8ee3bc1 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_cli.rst @@ -3,7 +3,7 @@ Configuration Client #################### -The Configuration Client model is a foundation model defined by the Bluetooth mesh +The Configuration Client model is a foundation model defined by the Bluetooth Mesh specification. It provides functionality for configuring most parameters of a mesh node, including encryption keys, model configuration and feature enabling. diff --git a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst index 84f174df88b..8f595bf9b11 100644 --- a/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/cfg_srv.rst @@ -3,7 +3,7 @@ Configuration Server #################### -The Configuration Server model is a foundation model defined by the Bluetooth mesh +The Configuration Server model is a foundation model defined by the Bluetooth Mesh 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. @@ -14,7 +14,7 @@ mesh node. It does not have an API of its own, but relies on a should be set through Kconfig, and the Heartbeat feature should be controlled through the :ref:`bluetooth_mesh_heartbeat` API. -The Configuration Server model is mandatory on all Bluetooth mesh nodes, and +The Configuration Server model is mandatory on all Bluetooth Mesh nodes, and must only be instantiated on the primary element. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/core.rst b/doc/connectivity/bluetooth/api/mesh/core.rst index b9fdd164257..94e2b8a6e5e 100644 --- a/doc/connectivity/bluetooth/api/mesh/core.rst +++ b/doc/connectivity/bluetooth/api/mesh/core.rst @@ -3,7 +3,7 @@ Core #### -The core provides functionality for managing the general Bluetooth mesh +The core provides functionality for managing the general Bluetooth Mesh state. .. _bluetooth_mesh_lpn: @@ -117,7 +117,7 @@ Advertisement identity All mesh stack bearers advertise data with the :c:macro:`BT_ID_DEFAULT` local identity. The value is preset in the mesh stack implementation. When Bluetooth® Low Energy (LE) -and Bluetooth mesh coexist on the same device, the application should allocate and +and Bluetooth Mesh coexist on the same device, the application should allocate and configure another local identity for Bluetooth LE purposes before starting the communication. API reference diff --git a/doc/connectivity/bluetooth/api/mesh/dfu.rst b/doc/connectivity/bluetooth/api/mesh/dfu.rst index 9cf55e244d6..6718b3ea0ce 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu.rst @@ -3,16 +3,16 @@ Device Firmware Update (DFU) ############################ -Bluetooth mesh supports the distribution of firmware images across a mesh network. The Bluetooth +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 +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, +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 +The DFU specification is implemented in the Zephyr Bluetooth Mesh DFU subsystem as three separate models: .. toctree:: @@ -28,7 +28,7 @@ Overview DFU roles ========= -The Bluetooth mesh DFU subsystem defines three different roles the mesh nodes have to assume in the +The Bluetooth Mesh DFU subsystem defines three different roles the mesh nodes have to assume in the distribution of firmware images: Target node @@ -47,20 +47,20 @@ Distributor image to the Target nodes. Initiator - The Initiator role is typically implemented by the same device that implements the Bluetooth mesh + 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. + 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 - DFU roles and the associated Bluetooth mesh models + 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 +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. @@ -76,7 +76,7 @@ Firmware Update Client model directly, e.g. over a serial protocol. Stages ====== -The Bluetooth mesh DFU process is designed to act in three 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 @@ -131,7 +131,7 @@ Firmware metadata 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 + 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 @@ -299,7 +299,7 @@ following steps: 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 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 diff --git a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst index 2642dec8cc9..105bdecb86c 100644 --- a/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/dfu_srv.rst @@ -16,7 +16,7 @@ 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 +: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. @@ -33,9 +33,9 @@ application is described below: .. figure:: images/dfu_srv.svg :align: center - :alt: Bluetooth mesh Firmware Update Server transfer + :alt: Bluetooth Mesh Firmware Update Server transfer - Bluetooth mesh Firmware Update Server transfer + Bluetooth Mesh Firmware Update Server transfer Transfer check ============== @@ -118,7 +118,7 @@ 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. +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 diff --git a/doc/connectivity/bluetooth/api/mesh/health_srv.rst b/doc/connectivity/bluetooth/api/mesh/health_srv.rst index 84c543b4766..6f7b1fc3f33 100644 --- a/doc/connectivity/bluetooth/api/mesh/health_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/health_srv.rst @@ -21,7 +21,7 @@ necessarily damaging to the device. Errors indicate conditions that are outside of the node's design limits, and may have caused invalid behavior or permanent damage to the device. -Fault values ``0x01`` to ``0x7f`` are reserved for the Bluetooth mesh +Fault values ``0x01`` to ``0x7f`` are reserved for the Bluetooth Mesh specification, and the full list of specification defined faults are available in :ref:`bluetooth_mesh_health_faults`. Fault values ``0x80`` to ``0xff`` are vendor specific. The list of faults are always reported with a company ID to @@ -57,6 +57,6 @@ API reference Health faults ============= -Fault values defined by the Bluetooth mesh specification. +Fault values defined by the Bluetooth Mesh specification. .. doxygengroup:: bt_mesh_health_faults diff --git a/doc/connectivity/bluetooth/api/mesh/heartbeat.rst b/doc/connectivity/bluetooth/api/mesh/heartbeat.rst index 16c2bfa7840..706625849c1 100644 --- a/doc/connectivity/bluetooth/api/mesh/heartbeat.rst +++ b/doc/connectivity/bluetooth/api/mesh/heartbeat.rst @@ -3,7 +3,7 @@ Heartbeat ######### -The Heartbeat feature provides functionality for monitoring Bluetooth mesh nodes +The Heartbeat feature provides functionality for monitoring Bluetooth Mesh nodes and determining the distance between nodes. The Heartbeat feature is configured through the :ref:`bluetooth_mesh_models_cfg_srv` model. diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst index 0eca28f1b2a..96189e21dd3 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_cli.rst @@ -3,7 +3,7 @@ Large Composition Data Client ############################# -The Large Composition Data Client model is a foundation model defined by the Bluetooth mesh +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. diff --git a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst index f96436138b7..f67b31c27f8 100644 --- a/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/lcd_srv.rst @@ -3,7 +3,7 @@ Large Composition Data Server ############################# -The Large Composition Data Server model is a foundation model defined by the Bluetooth mesh +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. diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index 3f5f94152ce..94c3914ca53 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -6,7 +6,7 @@ Mesh models Foundation models ***************** -The Bluetooth mesh specification defines foundation models that can be +The Bluetooth Mesh specification defines foundation models that can be used by network administrators to configure and diagnose mesh nodes. .. toctree:: @@ -34,7 +34,7 @@ used by network administrators to configure and diagnose mesh nodes. Model specification models ************************** -In addition to the foundation models defined in the Bluetooth mesh specification, the Bluetooth Mesh +In addition to the foundation models defined in the Bluetooth Mesh specification, the Bluetooth Mesh Model Specification defines several models, some of which are implemented in Zephyr: .. toctree:: diff --git a/doc/connectivity/bluetooth/api/mesh/msg.rst b/doc/connectivity/bluetooth/api/mesh/msg.rst index ae8b968198a..614d2604d90 100644 --- a/doc/connectivity/bluetooth/api/mesh/msg.rst +++ b/doc/connectivity/bluetooth/api/mesh/msg.rst @@ -3,7 +3,7 @@ Message ####### -The Bluetooth mesh message provides set of structures, macros and functions used +The Bluetooth Mesh message provides set of structures, macros and functions used for preparing message buffers, managing message and acknowledged message contexts. diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index 5fc841716ce..e419acb7572 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -3,7 +3,7 @@ On-Demand Private Proxy Client ############################## -The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth mesh +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. diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 700517e4283..3c2f993bb30 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -3,7 +3,7 @@ On-Demand Private Proxy Server ############################## -The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth mesh +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 diff --git a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst index 148557a4e81..4648b4495cd 100644 --- a/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/op_agg_cli.rst @@ -3,7 +3,7 @@ Opcodes Aggregator Client ######################### -The Opcodes Aggregator Client model is a foundation model defined by the Bluetooth mesh +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. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst index cb531a4c3c8..c9bcc8e5eb1 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_cli.rst @@ -11,7 +11,7 @@ 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. -The Private Beacons feature adds privacy to the different Bluetooth mesh +The Private Beacons feature adds privacy to the different Bluetooth Mesh beacons by periodically randomizing the beacon input data. This protects the mesh node from being tracked by devices outside the mesh network, and hides the network's IV index, IV update and the Key Refresh state. diff --git a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst index 3c17cc44675..62450634a31 100644 --- a/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/priv_beacon_srv.rst @@ -11,7 +11,7 @@ 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. -The Private Beacons feature adds privacy to the different Bluetooth mesh +The Private Beacons feature adds privacy to the different Bluetooth Mesh beacons by periodically randomizing the beacon input data. This protects the mesh node from being tracked by devices outside the mesh network, and hides the network's IV index, IV update and the Key Refresh state. The Private Beacon Server diff --git a/doc/connectivity/bluetooth/api/mesh/provisioning.rst b/doc/connectivity/bluetooth/api/mesh/provisioning.rst index 36fa38927a3..685c9dda455 100644 --- a/doc/connectivity/bluetooth/api/mesh/provisioning.rst +++ b/doc/connectivity/bluetooth/api/mesh/provisioning.rst @@ -12,15 +12,15 @@ two devices operating in the following roles: Provisioning process. Before the provisioning process starts, the provisionee is an *unprovisioned device*. -The Provisioning module in the Zephyr Bluetooth mesh stack supports both the +The Provisioning module in the Zephyr Bluetooth Mesh stack supports both the Advertising and GATT Provisioning bearers for the provisionee role, as well as the Advertising Provisioning bearer for the provisioner role. The Provisioning process ************************ -All Bluetooth mesh nodes must be provisioned before they can participate in a -Bluetooth mesh network. The Provisioning API provides all the functionality +All Bluetooth Mesh nodes must be provisioned before they can participate in a +Bluetooth Mesh network. The Provisioning API provides all the functionality necessary for a device to become a provisioned mesh node. Provisioning is a five-step process, involving the following steps: @@ -176,7 +176,7 @@ Depending on the choice of public key exchange mechanism and authentication meth the provisioning process can be secure or insecure. On May 24th 2021, ANSSI `disclosed `_ -a set of vulnerabilities in the Bluetooth mesh provisioning protocol that showcased +a set of vulnerabilities in the Bluetooth Mesh provisioning protocol that showcased 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 diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index 823401c9571..5e905f2c9ef 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -3,7 +3,7 @@ Proxy ##### -The Proxy feature allows legacy devices like phones to access the Bluetooth mesh network through +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`. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst index a0aa2b46a3e..76bd0330a98 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg.rst @@ -4,7 +4,7 @@ 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 +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 @@ -23,7 +23,7 @@ required. Set the ``send rel`` flag (see :c:struct:`bt_mesh_msg_ctx`) to use the 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 +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. @@ -43,36 +43,8 @@ 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(&\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 -====================================================== +****************************************************** 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 @@ -139,7 +111,7 @@ of the `SAR Acknowledgment Retransmissions Count`_ state. .. _bt_mesh_sar_cfg_states: SAR states -========== +********** There are two states defined related to segmentation and reassembly: @@ -168,7 +140,7 @@ the following states: * 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. @@ -182,7 +154,7 @@ value. Segment transmission interval is then calculated using the following form 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 @@ -190,7 +162,7 @@ of a segmented message to a unicast destination. Use the 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 @@ -199,7 +171,7 @@ an acknowledgment with already confirmed segments was received. Use the Kconfig 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 @@ -214,7 +186,7 @@ default value. This value is then used to calculate the interval step using the 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 @@ -230,7 +202,7 @@ formula: 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 @@ -238,7 +210,7 @@ a multicast address. Use the Kconfig option 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. @@ -252,7 +224,7 @@ default value that is used to calculate the interval 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 @@ -265,7 +237,7 @@ timeout will be calculated using the following formula: 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 @@ -276,7 +248,7 @@ 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 @@ -287,7 +259,7 @@ additionally retransmit every acknowledgment message the number of times given b :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 @@ -300,7 +272,7 @@ value for this state. The maximum number of transmissions of a Segment Acknowle :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 diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst index b017b53a01a..1e2ab6c47a1 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_cli.rst @@ -3,7 +3,7 @@ SAR Configuration Client ######################## -The SAR Configuration Client model is a foundation model defined by the Bluetooth mesh +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. diff --git a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst index 2ea1446c9ea..4280fae1350 100644 --- a/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/sar_cfg_srv.rst @@ -3,13 +3,13 @@ SAR Configuration Server ######################## -The SAR Configuration Server model is a foundation model defined by the Bluetooth mesh +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. +: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. diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 66bfcdf6168..3d925f29a3e 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -3,32 +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 +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 +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 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 +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. +interact with the Bluetooth Mesh shell application. Basic usage *********** -The Bluetooth mesh shell subsystem adds a single ``mesh`` command, which holds a set of +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:: +other Bluetooth Mesh shell commands can be called:: uart:~$ mesh init @@ -82,7 +82,7 @@ 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. +the Bluetooth Mesh shell can send raw mesh messages through the network. For example, to send a Generic OnOff Set message, call:: @@ -107,7 +107,7 @@ configured network and application keys will receive and process the messages we 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 +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. @@ -115,7 +115,7 @@ incoming message to the shell in the handler callback. Parameter formats ***************** -The Bluetooth mesh shell commands are parsed with a variety of formats: +The Bluetooth Mesh shell commands are parsed with a variety of formats: .. list-table:: Parameter formats :widths: 1 4 2 @@ -139,12 +139,12 @@ 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, +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: +The Bluetooth Mesh shell commands are divided into the following groups: .. contents:: :depth: 1 @@ -282,7 +282,7 @@ 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_PROVISIONEE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_GATT` option. ``mesh prov pb-gatt `` @@ -295,7 +295,7 @@ To allow a device to broadcast connectable unprovisioned beacons, the * ``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_PROVISIONEE` configuration option must be enabled, along with the :kconfig:option:`CONFIG_BT_MESH_PB_ADV` option. ``mesh prov pb-adv `` @@ -500,10 +500,10 @@ application. This shell module can be used for configuring itself and other node 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 +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 +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 @@ -1645,7 +1645,7 @@ 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 +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. @@ -1675,7 +1675,7 @@ nodes supporting the Opcodes Aggregator Server model. Remote Provisioning Client -------------------------- -The Remote Provisioning Client is an optional Bluetooth mesh model enabled through the +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. diff --git a/doc/connectivity/bluetooth/bluetooth-arch.rst b/doc/connectivity/bluetooth/bluetooth-arch.rst index 9b455e680d0..ed0cf1ea9f6 100644 --- a/doc/connectivity/bluetooth/bluetooth-arch.rst +++ b/doc/connectivity/bluetooth/bluetooth-arch.rst @@ -248,7 +248,7 @@ Each role comes with its own build-time configuration option: connection-oriented roles central implicitly enables observer role, and peripheral implicitly enables broadcaster role. Usually the first step when creating an application is to decide which roles are needed and go -from there. Bluetooth mesh is a slightly special case, requiring at +from there. Bluetooth Mesh is a slightly special case, requiring at least the observer and broadcaster roles, and possibly also the Peripheral role. This will be described in more detail in a later section. diff --git a/doc/connectivity/bluetooth/overview.rst b/doc/connectivity/bluetooth/overview.rst index fece4ade496..1f727736b2d 100644 --- a/doc/connectivity/bluetooth/overview.rst +++ b/doc/connectivity/bluetooth/overview.rst @@ -76,7 +76,7 @@ Bluetooth stack. * Non-volatile storage support for permanent storage of Bluetooth-specific settings and data - * Bluetooth mesh support + * Bluetooth Mesh support * Relay, Friend Node, Low-Power Node (LPN) and GATT Proxy features * Both Provisioning roles and bearers supported (PB-ADV & PB-GATT) diff --git a/doc/connectivity/networking/api/coap_server.rst b/doc/connectivity/networking/api/coap_server.rst index 9a91081f449..bd53630ad6c 100644 --- a/doc/connectivity/networking/api/coap_server.rst +++ b/doc/connectivity/networking/api/coap_server.rst @@ -97,7 +97,7 @@ The following is an example of a CoAP resource registered with our service: 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); + return coap_resource_send(resource, &response, addr, addr_len, NULL); } static int my_put(struct coap_resource *resource, struct coap_packet *request, @@ -189,7 +189,7 @@ and send state updates. An example using a temperature sensor can look like: 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); + return coap_resource_send(resource, &response, addr, addr_len, NULL); } static int temp_get(struct coap_resource *resource, struct coap_packet *request, @@ -245,3 +245,4 @@ API Reference ************* .. doxygengroup:: coap_service +.. doxygengroup:: coap_mgmt diff --git a/doc/connectivity/networking/api/mqtt.rst b/doc/connectivity/networking/api/mqtt.rst index 973b61860e3..16ba69e1288 100644 --- a/doc/connectivity/networking/api/mqtt.rst +++ b/doc/connectivity/networking/api/mqtt.rst @@ -149,6 +149,7 @@ additional configuration information: tls_config->sec_tag_list = m_sec_tags; tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags); tls_config->hostname = MQTT_BROKER_HOSTNAME; + tls_config->set_native_tls = true; In this sample code, the ``m_sec_tags`` array holds a list of tags, referencing TLS credentials that the MQTT library should use for authentication. We do not specify @@ -161,6 +162,8 @@ Note, that TLS credentials referenced by the ``m_sec_tags`` array must be registered in the system first. For more information on how to do that, refer to :ref:`secure sockets documentation `. +Finally, ``set_native_tls`` can be optionally set to enable native TLS support instead of offloading TLS operations to the modem. + An example of how to use TLS with MQTT is also present in :zephyr:code-sample:`mqtt-publisher` sample application. diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index f2be0d8b551..2cd96b3252b 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -641,9 +641,8 @@ started. See :ref:`setting_configuration_values` for detailed documentation on setting Kconfig configuration values. The :ref:`initial-conf` section on the same page -explains how the initial configuration is derived. See :ref:`kconfig-search` -for a complete list of configuration options. -See :ref:`hardening` for security information related with Kconfig options. +explains how the initial configuration is derived. See :ref:`hardening` for +security information related with Kconfig options. The other pages in the :ref:`Kconfig section of the manual ` are also worth going through, especially if you planning to add new configuration diff --git a/doc/develop/test/pytest.rst b/doc/develop/test/pytest.rst index e644882191e..f6ba54fa52e 100644 --- a/doc/develop/test/pytest.rst +++ b/doc/develop/test/pytest.rst @@ -56,6 +56,18 @@ 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' + + +Note that ``--pytest-args`` can be passed multiple times to pass several arguments to the pytest. Helpers & fixtures ================== diff --git a/doc/introduction/index.rst b/doc/introduction/index.rst index 85968ca456a..13204e6bb7d 100644 --- a/doc/introduction/index.rst +++ b/doc/introduction/index.rst @@ -123,7 +123,7 @@ Zephyr offers a large and ever growing number of features including: **Bluetooth Low Energy 5.0 support** Bluetooth 5.0 compliant (ESR10) and Bluetooth Low Energy Controller support - (LE Link Layer). Includes Bluetooth mesh and a Bluetooth qualification-ready + (LE Link Layer). Includes Bluetooth Mesh and a Bluetooth qualification-ready Bluetooth controller. * Generic Access Profile (GAP) with all possible LE roles diff --git a/doc/kconfig.rst b/doc/kconfig.rst deleted file mode 100644 index 1123de2adbd..00000000000 --- a/doc/kconfig.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -.. _kconfig-search: - -Kconfig Search -============== - -.. kconfig:search:: diff --git a/doc/kernel/services/interrupts.rst b/doc/kernel/services/interrupts.rst index 849e614a562..7af101a40d1 100644 --- a/doc/kernel/services/interrupts.rst +++ b/doc/kernel/services/interrupts.rst @@ -457,6 +457,38 @@ Interrupt tables are set up at build time using some special build tools. The details laid out here apply to all architectures except x86, which are covered in the `x86 Details`_ section below. +The invocation of :c:macro:`IRQ_CONNECT` will declare an instance of +struct _isr_list wich is placed in a special .intList section. +This section is placed in compiled code on precompilation stages only. +It is meant to be used by Zephyr script to generate interrupt tables +and is removed from the final build. +The script implements different parsers to process the data from .intList section +and produce the required output. + +The default parser generates C arrays filled with arguments and interrupt +handlers in a form of addresses directly taken from .intList section entries. +It works with all the architectures and compillers (with the exception mentioned above). +The limitation of this parser is the fact that after the arrays are generated +it is expected for the code not to relocate. +Any relocation on this stage may lead to the situation where the entry in the interrupt array +is no longer pointing to the function that was expected. +It means that this parser, being more compatible is limiting us from using Link Time Optimization. + +The local isr declaration parser uses different approach to construct +the same arrays at binnary level. +All the entries to the arrays are declared and defined locally, +directly in the file where :c:macro:`IRQ_CONNECT` is used. +They are placed in a section with the unique, synthetized name. +The name of the section is then placed in .intList section and it is used to create linker script +to properly place the created entry in the right place in the memory. +This parser is now limited to the supported architectures and toolchains but in reward it keeps +the information about object relations for linker thus allowing the Link Time Optimization. + +Implementation using C arrays +----------------------------- + +This is the default configuration available for all Zephyr supported architectures. + Any invocation of :c:macro:`IRQ_CONNECT` will declare an instance of struct _isr_list which is placed in a special .intList section: @@ -500,7 +532,7 @@ do not support the notion of interrupt priority, in which case the priority argument is ignored. Vector Table ------------- +~~~~~~~~~~~~ A vector table is generated when :kconfig:option:`CONFIG_GEN_IRQ_VECTOR_TABLE` is enabled. This data structure is used natively by the CPU and is simply an array of function pointers, where each element n corresponds to the IRQ handler @@ -527,7 +559,7 @@ CONFIG_GEN_IRQ_START_VECTOR needs to be set to properly offset the indices in the table. SW ISR Table ------------- +~~~~~~~~~~~~ This is an array of struct _isr_table_entry: .. code-block:: c @@ -542,14 +574,14 @@ 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]; + struct _isr_table_entry clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS]; size_t client_num; }; @@ -558,15 +590,88 @@ 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: +Implementation using linker script +---------------------------------- + +This way of prepare and parse .isrList section to implement interrupt vectors arrays +is called local isr declaration. +The name comes from the fact that all the entries to the arrays that would create +interrupt vectors are created locally in place of invocation of :c:macro:`IRQ_CONNECT` macro. +Then automatically generated linker scripts are used to place it in the right place in the memory. + +This option requires enabling by the choose of :kconfig:option:`ISR_TABLES_LOCAL_DECLARATION`. +If this configuration is supported by the used architecture and toolchaing the +:kconfig:option:`ISR_TABLES_LOCAL_DECLARATION_SUPPORTED` is set. +See defails of this option for the information about currently supported configurations. + +Any invocation of :c:macro:`IRQ_CONNECT` or `IRQ_DIRECT_CONNECT` will declare an instance of struct +_isr_list_sname which is placde in a special .intList section: + +.. code-block:: c + + struct _isr_list_sname { + /** IRQ line number */ + int32_t irq; + /** Flags for this IRQ, see ISR_FLAG_* definitions */ + int32_t flags; + /** The section name */ + const char sname[]; + }; + +Note that the section name is placed in flexible array member. +It means that the size of the initialized structure will warry depending on the +structure name length. +The whole entry is used by the script during the build of the application +and has all the information needed for proper interrupt placement. + +Beside of the _isr_list_sname the :c:macro:`IRQ_CONNECT` macro generates an entry +that would be the part of the interrupt array: .. code-block:: c - struct z_shared_isr_client { - void (*isr)(const void *arg); + struct _isr_table_entry { const void *arg; + void (*isr)(const void *); }; +This array is placed in a section with the name saved in _isr_list_sname structure. + +The values created by :c:macro:`IRQ_DIRECT_CONNECT` macro depends on the architecture. +It can be changed to variable that points to a interrupt handler: + +.. code-block:: c + + static uintptr_t = ((uintptr_t)func); + +Or to actuall naked function that implements a jump to the interrupt handler: + +.. code-block:: c + + static void (void) + { + __asm(ARCH_IRQ_VECTOR_JUMP_CODE(func)); + } + +Simillar like for :c:macro:`IRQ_CONNECT`, the created variable or function is placed +in a section, saved in _isr_list_sname section. + +Files generated by the script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The interrupt tables generator script creates 3 files: +isr_tables.c, isr_tables_swi.ld, and isr_tables_vt.ld. + +The isr_tables.c will contain all the structures for interrupts, direct interrupts and +shared interrupts (if enabled). This file implements only all the structures that +are not implemented by the application, leaving a comment where the interrupt +not implemented here can be found. + +Then two linker files are used. The isr_tables_vt.ld file is included in place +where the interrupt vectors are required to be placed in the selected architecture. +The isr_tables_swi.ld file describes the placement of the software interrupt table +elements. The separated file is required as it might be placed in writable on nonwritable +section, depending on the current configuration. + x86 Details ----------- diff --git a/doc/kernel/timeutil.rst b/doc/kernel/timeutil.rst index d41c5b48b89..203d52ea9af 100644 --- a/doc/kernel/timeutil.rst +++ b/doc/kernel/timeutil.rst @@ -223,7 +223,7 @@ include: - GPS time: epoch of 1980-01-06T00:00:00Z, continuous following TAI with an offset of TAI-GPS=19 s. -- Bluetooth mesh time: epoch of 2000-01-01T00:00:00Z, continuous following TAI +- Bluetooth Mesh time: epoch of 2000-01-01T00:00:00Z, continuous following TAI with an offset of -32. - UNIX Leap Time: epoch of 1970-01-01T00:00:00Z, continuous following TAI with an offset of -8. diff --git a/doc/releases/migration-guide-3.6.rst b/doc/releases/migration-guide-3.6.rst index c4b93e5f150..8428e2a4645 100644 --- a/doc/releases/migration-guide-3.6.rst +++ b/doc/releases/migration-guide-3.6.rst @@ -55,6 +55,10 @@ Device Drivers and Device Tree (:github:`62994`) +* Runtime configuration is now disabled by default for Nordic UART drivers. The motivation for the + change is that this feature is rarely used and disabling it significantly reduces the memory + footprint. + Power Management ================ @@ -113,13 +117,43 @@ 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. (: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. (: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`) +* The Bluetooth UUID has been modified to rodata in ``BT_UUID_DECLARE_16``, ``BT_UUID_DECLARE_32` + and ``BT_UUID_DECLARE_128`` as the return value has been changed to `const`. + Any pointer to a UUID must be prefixed with `const`, otherwise there will be a compilation warning. + For example change ``struct bt_uuid *uuid = BT_UUID_DECLARE_16(xx)`` to + ``const struct bt_uuid *uuid = BT_UUID_DECLARE_16(xx)``. (:github:`66136`) + +* Mesh + + * 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. (: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`) + * Deprecated :kconfig:option:`CONFIG_BT_MESH_PROV_DEVICE`. This option is + replaced by new option :kconfig:option:`CONFIG_BT_MESH_PROVISIONEE` to + be aligned with Mesh Protocol Specification v1.1, section 5.4. (:github:`64252`) + * Removed the ``CONFIG_BT_MESH_V1d1`` Kconfig option. + * Removed the ``CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT``, + ``CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST``, + ``CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP``, ``CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT``, + ``CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT``, ``BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT`` + Kconfig options. They are superseded by the + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT`, + :kconfig:option:`CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT`, + :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD`, + :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC`, + :kconfig:option:`CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP`, + :kconfig:option:`CONFIG_BT_MESH_SAR_RX_DISCARD_TIMEOUT`, + :kconfig:option:`CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT` Kconfig options. + LoRaWAN ======= @@ -139,6 +173,32 @@ Networking ``request`` argument for :c:func:`coap_well_known_core_get` is made ``const``. (:github:`64265`) +* CoAP observer events have moved from a callback function in a CoAP resource to the Network Events + subsystem. The ``CONFIG_COAP_OBSERVER_EVENTS`` configuration option has been removed. + (:github:`65936`) + +* The CoAP public API function :c:func:`coap_pending_init` has changed. The parameter + ``retries`` is replaced with a pointer to :c:struct:`coap_transmission_parameters`. This allows to + specify retransmission parameters of the confirmable message. It is safe to pass a NULL pointer to + use default values. + (:github:`66482`) + +* The CoAP public API functions :c:func:`coap_service_send` and :c:func:`coap_resource_send` have + changed. An additional parameter pointer to :c:struct:`coap_transmission_parameters` has been + added. It is safe to pass a NULL pointer to use default values. (:github:`66540`) + +* The IGMP multicast library now supports IGMPv3. This results in a minor change to the existing + api. The :c:func:`net_ipv4_igmp_join` now takes an additional argument of the type + ``const struct igmp_param *param``. This allows IGMPv3 to exclude/include certain groups of + addresses. If this functionality is not used or available (when using IGMPv2), you can safely pass + a NULL pointer. IGMPv3 can be enabled using the Kconfig ``CONFIG_NET_IPV4_IGMPV3``. + (:github:`65293`) + +* The network stack now uses a separate IPv4 TTL (time-to-live) value for multicast packets. + Before, the same TTL value was used for unicast and multicast packets. + The IPv6 hop limit value is also changed so that unicast and multicast packets can have a + different one. (:github:`65886`) + Other Subsystems ================ diff --git a/doc/releases/release-notes-3.6.rst b/doc/releases/release-notes-3.6.rst index 676e16fa77c..31dcb4c8dcd 100644 --- a/doc/releases/release-notes-3.6.rst +++ b/doc/releases/release-notes-3.6.rst @@ -52,6 +52,12 @@ Bluetooth * Mesh + * Added the delayable messages functionality to apply random delays for + the transmitted responses on the Access layer. + The functionality is enabled by the :kconfig:option:`CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG` + Kconfig option. + * The Bluetooth Mesh Protocol 1.1 is now supported by default. + * Controller Boards & SoC Support @@ -149,6 +155,8 @@ Drivers and Sensors * IEEE 802.15.4 + * Removed :kconfig:option:`CONFIG_IEEE802154_SELECTIVE_TXPOWER` Kconfig option. + * Interrupt Controller * Input @@ -188,6 +196,11 @@ Networking * CoAP: + * Added new API functions: + + * :c:func:`coap_get_transmission_parameters` + * :c:func:`coap_set_transmission_parameters` + * Connection Manager: * DHCP: diff --git a/doc/security/vulnerabilities.rst b/doc/security/vulnerabilities.rst index 61d0d25f618..fde156983d3 100644 --- a/doc/security/vulnerabilities.rst +++ b/doc/security/vulnerabilities.rst @@ -1176,7 +1176,7 @@ This has been fixed in main for v3.0.0 CVE-2022-1041 -------------- -Out-of-bound write vulnerability in the Bluetooth mesh core stack can be triggered during provisioning +Out-of-bound write vulnerability in the Bluetooth Mesh core stack can be triggered during provisioning This has been fixed in main for v3.1.0 @@ -1195,7 +1195,7 @@ This has been fixed in main for v3.1.0 CVE-2022-1042 -------------- -Out-of-bound write vulnerability in the Bluetooth mesh core stack can be triggered during provisioning +Out-of-bound write vulnerability in the Bluetooth Mesh core stack can be triggered during provisioning This has been fixed in main for v3.1.0 diff --git a/drivers/adc/adc_nrfx_saadc.c b/drivers/adc/adc_nrfx_saadc.c index 72a20f47fc9..6d1973ca0aa 100644 --- a/drivers/adc/adc_nrfx_saadc.c +++ b/drivers/adc/adc_nrfx_saadc.c @@ -170,7 +170,7 @@ static void adc_context_update_buffer_pointer(struct adc_context *ctx, if (!repeat) { nrf_saadc_buffer_pointer_set( NRF_SAADC, - nrf_saadc_buffer_pointer_get(NRF_SAADC) + + (uint16_t *)nrf_saadc_buffer_pointer_get(NRF_SAADC) + nrf_saadc_amount_get(NRF_SAADC)); } } @@ -256,7 +256,7 @@ static int check_buffer_size(const struct adc_sequence *sequence, { size_t needed_buffer_size; - needed_buffer_size = active_channels * sizeof(nrf_saadc_value_t); + needed_buffer_size = active_channels * sizeof(uint16_t); if (sequence->options) { needed_buffer_size *= (1 + sequence->options->extra_samplings); } diff --git a/drivers/cache/CMakeLists.txt b/drivers/cache/CMakeLists.txt index 47c790f0a89..23cb11afb6a 100644 --- a/drivers/cache/CMakeLists.txt +++ b/drivers/cache/CMakeLists.txt @@ -7,3 +7,4 @@ zephyr_library_property(ALLOW_EMPTY TRUE) zephyr_library_sources_ifdef(CONFIG_CACHE_ASPEED cache_aspeed.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE cache_handlers.c) +zephyr_library_sources_ifdef(CONFIG_CACHE_NRF_CACHE cache_nrf.c) diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index 834cc49e181..4dcb64f488a 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -19,5 +19,6 @@ source "subsys/logging/Kconfig.template.log_config" comment "Device Drivers" source "drivers/cache/Kconfig.aspeed" +source "drivers/cache/Kconfig.nrf" endif # CACHE diff --git a/drivers/cache/Kconfig.nrf b/drivers/cache/Kconfig.nrf new file mode 100644 index 00000000000..820445db432 --- /dev/null +++ b/drivers/cache/Kconfig.nrf @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Carlo Caione +# SPDX-License-Identifier: Apache-2.0 + +config CACHE_NRF_CACHE + bool "nRF cache driver" + select CACHE_HAS_DRIVER + depends on HAS_NRFX && CACHE_MANAGEMENT + help + Enable support for the nRF cache driver. diff --git a/drivers/cache/cache_nrf.c b/drivers/cache/cache_nrf.c new file mode 100644 index 00000000000..63d76a47d6e --- /dev/null +++ b/drivers/cache/cache_nrf.c @@ -0,0 +1,390 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +LOG_MODULE_REGISTER(cache_nrfx, CONFIG_CACHE_LOG_LEVEL); + +#if !defined(NRF_ICACHE) && defined(NRF_CACHE) +#define NRF_ICACHE NRF_CACHE +#endif + +#define CACHE_LINE_SIZE 32 +#define CACHE_BUSY_RETRY_INTERVAL_US 10 + +static struct k_spinlock lock; + +enum k_nrf_cache_op { + /* + * Sequentially loop through all dirty lines and write those data units to + * memory. + * + * This is FLUSH in Zephyr nomenclature. + */ + K_NRF_CACHE_CLEAN, + + /* + * Mark all lines as invalid, ignoring any dirty data. + * + * This is INVALIDATE in Zephyr nomenclature. + */ + K_NRF_CACHE_INVD, + + /* + * Clean followed by invalidate + * + * This is FLUSH_AND_INVALIDATE in Zephyr nomenclature. + */ + K_NRF_CACHE_FLUSH, +}; + +static inline bool is_cache_busy(NRF_CACHE_Type *cache) +{ +#if NRF_CACHE_HAS_STATUS + return nrf_cache_busy_check(cache); +#else + return false; +#endif +} + +static inline void wait_for_cache(NRF_CACHE_Type *cache) +{ + while (is_cache_busy(cache)) { + k_busy_wait(CACHE_BUSY_RETRY_INTERVAL_US); + } +} + +static inline int _cache_all(NRF_CACHE_Type *cache, enum k_nrf_cache_op op) +{ + /* + * We really do not want to invalidate the whole cache. + */ + if (op == K_NRF_CACHE_INVD) { + return -ENOTSUP; + } + + k_spinlock_key_t key = k_spin_lock(&lock); + + /* + * Invalidating the whole cache is dangerous. For good measure + * disable the cache. + */ + nrf_cache_disable(cache); + + wait_for_cache(cache); + + switch (op) { + +#if NRF_CACHE_HAS_TASK_CLEAN + case K_NRF_CACHE_CLEAN: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANCACHE); + break; +#endif + + case K_NRF_CACHE_INVD: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATECACHE); + break; + +#if NRF_CACHE_HAS_TASK_FLUSH + case K_NRF_CACHE_FLUSH: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHCACHE); + break; +#endif + + default: + break; + } + + wait_for_cache(cache); + + nrf_cache_enable(cache); + + k_spin_unlock(&lock, key); + + return 0; +} + +static inline void _cache_line(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, uintptr_t line_addr) +{ + wait_for_cache(cache); + + nrf_cache_lineaddr_set(cache, line_addr); + + switch (op) { + +#if NRF_CACHE_HAS_TASK_CLEAN + case K_NRF_CACHE_CLEAN: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_CLEANLINE); + break; +#endif + + case K_NRF_CACHE_INVD: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_INVALIDATELINE); + break; + +#if NRF_CACHE_HAS_TASK_FLUSH + case K_NRF_CACHE_FLUSH: + nrf_cache_task_trigger(cache, NRF_CACHE_TASK_FLUSHLINE); + break; +#endif + + default: + break; + } + + wait_for_cache(cache); +} + +static inline int _cache_range(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, void *addr, + size_t size) +{ + uintptr_t line_addr = (uintptr_t)addr; + uintptr_t end_addr = line_addr + size; + + /* + * Align address to line size + */ + line_addr &= ~(CACHE_LINE_SIZE - 1); + + do { + k_spinlock_key_t key = k_spin_lock(&lock); + + _cache_line(cache, op, line_addr); + + k_spin_unlock(&lock, key); + + line_addr += CACHE_LINE_SIZE; + + } while (line_addr < end_addr); + + return 0; +} + +static inline int _cache_checks(NRF_CACHE_Type *cache, enum k_nrf_cache_op op, void *addr, + size_t size, bool is_range) +{ + /* Check if the cache is enabled */ + if (!(cache->ENABLE & CACHE_ENABLE_ENABLE_Enabled)) { + return -EAGAIN; + } + + if (!is_range) { + return _cache_all(cache, op); + } + + /* Check for invalid address or size */ + if ((!addr) || (!size)) { + return -EINVAL; + } + + return _cache_range(cache, op, addr, size); +} + +#if defined(NRF_DCACHE) && NRF_CACHE_HAS_TASKS + +void cache_data_enable(void) +{ + nrf_cache_enable(NRF_DCACHE); +} + +void cache_data_disable(void) +{ + nrf_cache_disable(NRF_DCACHE); +} + +int cache_data_flush_all(void) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_CLEAN, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_data_invd_all(void) +{ + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_INVD, NULL, 0, false); +} + +int cache_data_flush_and_invd_all(void) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_FLUSH, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_data_flush_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_CLEAN, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +int cache_data_invd_range(void *addr, size_t size) +{ + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_INVD, addr, size, true); +} + +int cache_data_flush_and_invd_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_DCACHE, K_NRF_CACHE_FLUSH, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +#else + +void cache_data_enable(void) +{ + /* Nothing */ +} + +void cache_data_disable(void) +{ + /* Nothing */ +} + +int cache_data_flush_all(void) +{ + return -ENOTSUP; +} + +int cache_data_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_data_flush_and_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_data_flush_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_data_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_data_flush_and_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +#endif /* NRF_DCACHE */ + +#if defined(NRF_ICACHE) && NRF_CACHE_HAS_TASKS + +void cache_instr_enable(void) +{ + nrf_cache_enable(NRF_ICACHE); +} + +void cache_instr_disable(void) +{ + nrf_cache_disable(NRF_ICACHE); +} + +int cache_instr_flush_all(void) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_CLEAN, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_invd_all(void) +{ + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_INVD, NULL, 0, false); +} + +int cache_instr_flush_and_invd_all(void) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_FLUSH, NULL, 0, false); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_flush_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_CLEAN + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_CLEAN, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +int cache_instr_invd_range(void *addr, size_t size) +{ + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_INVD, addr, size, true); +} + +int cache_instr_flush_and_invd_range(void *addr, size_t size) +{ +#if NRF_CACHE_HAS_TASK_FLUSH + return _cache_checks(NRF_ICACHE, K_NRF_CACHE_FLUSH, addr, size, true); +#else + return -ENOTSUP; +#endif +} + +#else + +void cache_instr_enable(void) +{ + /* Nothing */ +} + +void cache_instr_disable(void) +{ + /* Nothing */ +} + +int cache_instr_flush_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_flush_and_invd_all(void) +{ + return -ENOTSUP; +} + +int cache_instr_flush_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_instr_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +int cache_instr_flush_and_invd_range(void *addr, size_t size) +{ + return -ENOTSUP; +} + +#endif /* NRF_ICACHE */ diff --git a/drivers/console/uart_mux.c b/drivers/console/uart_mux.c index ca445a1f5b7..8ade93ef0bb 100644 --- a/drivers/console/uart_mux.c +++ b/drivers/console/uart_mux.c @@ -481,24 +481,6 @@ static int uart_mux_err_check(const struct device *dev) return -ENOTSUP; } -static int uart_mux_configure(const struct device *dev, - const struct uart_config *cfg) -{ - ARG_UNUSED(dev); - ARG_UNUSED(cfg); - - return -ENOTSUP; -} - -static int uart_mux_config_get(const struct device *dev, - struct uart_config *cfg) -{ - ARG_UNUSED(dev); - ARG_UNUSED(cfg); - - return -ENOTSUP; -} - static int uart_mux_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len) { @@ -714,8 +696,6 @@ static struct uart_mux_driver_api uart_mux_driver_api = { .uart_api.poll_in = uart_mux_poll_in, .uart_api.poll_out = uart_mux_poll_out, .uart_api.err_check = uart_mux_err_check, - .uart_api.configure = uart_mux_configure, - .uart_api.config_get = uart_mux_config_get, .uart_api.fifo_fill = uart_mux_fifo_fill, .uart_api.fifo_read = uart_mux_fifo_read, .uart_api.irq_tx_enable = uart_mux_irq_tx_enable, diff --git a/drivers/disk/flashdisk.c b/drivers/disk/flashdisk.c index 6336ad4dfd0..3e43716c2b3 100644 --- a/drivers/disk/flashdisk.c +++ b/drivers/disk/flashdisk.c @@ -420,6 +420,8 @@ static const struct disk_operations flash_disk_ops = { .ioctl = disk_flash_access_ioctl, }; +#ifndef USE_PARTITION_MANAGER +/* The non-Partition manager, DTS based generators below */ #define DT_DRV_COMPAT zephyr_flash_disk #define PARTITION_PHANDLE(n) DT_PHANDLE_BY_IDX(DT_DRV_INST(n), partition, 0) @@ -461,6 +463,82 @@ DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) "Devicetree node " DT_NODE_PATH(DT_DRV_INST(n)) \ " has cache size which is not a multiple of its sector size"); DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#else /* ifndef USE_PARTITION_MANAGER */ +/* Partition Manager based generators below */ + +/* Gets the PM_..._EXTRA_PARAM_##param value */ +#define PM_FLASH_DISK_ENTRY_EXTRA_PARAM(name, param) PM_##name##_EXTRA_PARAM_disk_##param + +/* Gets the PM_..._NAME value which is originally cased, as in yaml, partition name */ +#define PM_FLASH_DISK_ENTRY_PARTITION_NAME(name) PM_##name##_NAME + +/* Generates flashdiskN_cache variable name, where N is partition ID */ +#define PM_FLASH_DISK_CACHE_VARIABLE(n) UTIL_CAT(flashdisk, UTIL_CAT(FIXED_PARTITION_ID(n), _cache)) + +/* Generate cache buffers */ +#define CACHE_SIZE(n) (COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), (0), (1)) * \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size)) +#define DEFINE_FLASHDISKS_CACHE(n) \ + static uint8_t __aligned(4) PM_FLASH_DISK_CACHE_VARIABLE(n)[CACHE_SIZE(n)]; + +PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE) + +/* Generated single Flash Disk device data from Partition Manager partition. + * Partition is required to have type set to disk in partition definitions: + * type: disk + * and following extra params can be provided: + * extra_params: { + * name = "", + * cache_size = , + * sector_size = , + * read_only = + * } + * where: + * is mandatory device name that will be used by Disk Access and FAT FS to mount device; + * is cache r/w cache size, which is mandatory if read_only = 0 or not present, + * and should be multiple of ; + * is mandatory device sector size information, usually should be erase page size, + * for flash devices, for example 4096 bytes; + * read_only is optional, if not present then assumed false; can be 0(false) or 1(true). + */ +#define DEFINE_FLASHDISKS_DEVICE(n) \ +{ \ + .info = { \ + .ops = &flash_disk_ops, \ + .name = STRINGIFY(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, name)), \ + }, \ + .area_id = FIXED_PARTITION_ID(n), \ + .offset = FIXED_PARTITION_OFFSET(n), \ + .cache = PM_FLASH_DISK_CACHE_VARIABLE(n), \ + .cache_size = sizeof(PM_FLASH_DISK_CACHE_VARIABLE(n)), \ + .size = FIXED_PARTITION_SIZE(n), \ + .sector_size = PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size), \ +}, + +/* The bellow used PM_FOREACH_TYPE_disk is generated by Partition Manager foreach + * loop macro. The lower case _disk is type name for which the macro has been generated; + * partition entry can have multiple types set and foreach macro will be generated + * for every type found across partition definitions. + */ +static struct flashdisk_data flash_disks[] = { + PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_DEVICE) +}; + +#define VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY(n) \ + COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), \ + (/* cache-size is not used for read-only disks */), \ + (BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) != 0, \ + "Flash disk partition " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n))\ + " must have non-zero cache-size");)) +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) + +#define VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE(n) \ + BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) % \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size) == 0, \ + "Devicetree node " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n)) \ + " has cache size which is not a multiple of its sector size"); +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#endif /* USE_PARTITION_MANAGER */ static int disk_flash_init(void) { diff --git a/drivers/display/display_nrf_led_matrix.c b/drivers/display/display_nrf_led_matrix.c index dd36126a7ce..e27fb76a92a 100644 --- a/drivers/display/display_nrf_led_matrix.c +++ b/drivers/display/display_nrf_led_matrix.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #ifdef PWM_PRESENT #include @@ -89,6 +90,8 @@ struct display_drv_config { NRF_TIMER_Type *timer; #if USE_PWM NRF_PWM_Type *pwm; +#else + nrfx_gpiote_t gpiote; #endif uint8_t rows[ROW_COUNT]; uint8_t cols[COL_COUNT]; @@ -340,7 +343,7 @@ static void prepare_pixel_pulse(const struct device *dev, /* First timer channel is used for timing the period of pulses. */ nrf_timer_cc_set(dev_config->timer, 1 + channel_idx, pulse); - NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; + dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[channel_idx]] = gpiote_cfg; #endif /* USE_PWM */ } @@ -370,7 +373,7 @@ static void timer_irq_handler(void *arg) } #else for (int i = 0; i < GROUP_SIZE; ++i) { - NRF_GPIOTE->CONFIG[dev_data->gpiote_ch[i]] = 0; + dev_config->gpiote.p_reg->CONFIG[dev_data->gpiote_ch[i]] = 0; } #endif @@ -466,7 +469,7 @@ static int instance_init(const struct device *dev) return -ENOMEM; } - err = nrfx_gpiote_channel_alloc(gpiote_ch); + err = nrfx_gpiote_channel_alloc(&dev_config->gpiote, gpiote_ch); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate GPIOTE channel."); /* Do not bother with freeing resources allocated @@ -479,7 +482,7 @@ static int instance_init(const struct device *dev) nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, nrf_timer_event_address_get(dev_config->timer, nrf_timer_compare_event_get(1 + i)), - nrf_gpiote_event_address_get(NRF_GPIOTE, + nrf_gpiote_event_address_get(dev_config->gpiote.p_reg, nrf_gpiote_out_task_get(*gpiote_ch))); nrf_ppi_channel_enable(NRF_PPI, ppi_ch); } @@ -530,6 +533,14 @@ static struct display_drv_data instance_data = { .blanking = true, }; +#if !USE_PWM +#define CHECK_GPIOTE_INST(node_id, prop, idx) \ + BUILD_ASSERT(NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) == \ + NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0), \ + "All column GPIOs must use the same GPIOTE instance"); +DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, CHECK_GPIOTE_INST) +#endif + #define GET_PIN_INFO(node_id, pha, idx) \ (DT_GPIO_PIN_BY_IDX(node_id, pha, idx) | \ (DT_PROP_BY_PHANDLE_IDX(node_id, pha, idx, port) << 5) | \ @@ -546,6 +557,9 @@ static const struct display_drv_config instance_config = { .timer = (NRF_TIMER_Type *)DT_REG_ADDR(TIMER_NODE), #if USE_PWM .pwm = (NRF_PWM_Type *)DT_REG_ADDR(PWM_NODE), +#else + .gpiote = NRFX_GPIOTE_INSTANCE( + NRF_DT_GPIOTE_INST_BY_IDX(MATRIX_NODE, col_gpios, 0)), #endif .rows = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, row_gpios, GET_PIN_INFO) }, .cols = { DT_FOREACH_PROP_ELEM(MATRIX_NODE, col_gpios, GET_PIN_INFO) }, diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 99184f3b1e5..7ca87d60944 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -28,6 +28,6 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypt if (CONFIG_BUILD_WITH_TFM) target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/drivers/entropy/Kconfig.psa_crypto b/drivers/entropy/Kconfig.psa_crypto index d06001225b0..18514a071d1 100644 --- a/drivers/entropy/Kconfig.psa_crypto +++ b/drivers/entropy/Kconfig.psa_crypto @@ -7,6 +7,7 @@ config ENTROPY_PSA_CRYPTO_RNG bool "PSA Crypto Random source Entropy driver" depends on DT_HAS_ZEPHYR_PSA_CRYPTO_RNG_ENABLED select ENTROPY_HAS_DRIVER + select PSA_WANT_GENERATE_RANDOM default y help Enable the PSA Crypto source Entropy driver. diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index 4a02268a2b4..7426b43b089 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -118,3 +118,4 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_SHELL flash_shell.c) zephyr_library_sources_ifdef(CONFIG_FLASH_JESD216 jesd216.c) zephyr_library_sources_ifdef(CONFIG_FLASH_INFINEON_CAT1 flash_ifx_cat1.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NUMAKER soc_flash_numaker.c) +zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_NRF_RRAM soc_flash_nrf_rram.c) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index 698190e7780..03d4d07a193 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -160,4 +160,6 @@ source "drivers/flash/Kconfig.andes" source "drivers/flash/Kconfig.ambiq" +source "drivers/flash/Kconfig.nrf_rram" + endif # FLASH diff --git a/drivers/flash/Kconfig.nordic_qspi_nor b/drivers/flash/Kconfig.nordic_qspi_nor index aac9830835a..ff652f60822 100644 --- a/drivers/flash/Kconfig.nordic_qspi_nor +++ b/drivers/flash/Kconfig.nordic_qspi_nor @@ -50,4 +50,13 @@ config NORDIC_QSPI_NOR_XIP QSPI NOR flash chip is executed until the driver has been setup. This will also disable power management for the QSPI NOR flash chip. +config NORDIC_QSPI_NOR_TIMEOUT_MS + int "Timeout for QSPI operations (ms)" + default 500 + help + The QSPI peripheral operation timeout in milliseconds. + Primarily intended for long running operations such as + a flash sector erase. The 500 ms default allows for + most typical NOR flash chips to erase a sector. + endif # NORDIC_QSPI_NOR diff --git a/drivers/flash/Kconfig.nrf_rram b/drivers/flash/Kconfig.nrf_rram new file mode 100644 index 00000000000..68efde1ab30 --- /dev/null +++ b/drivers/flash/Kconfig.nrf_rram @@ -0,0 +1,69 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig SOC_FLASH_NRF_RRAM + bool "Nordic Semiconductor flash driver for nRF RRAM" + default y + depends on DT_HAS_NORDIC_RRAM_CONTROLLER_ENABLED + select FLASH_HAS_DRIVER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + select FLASH_NRF_FORCE_ALT + select MPU_ALLOW_FLASH_WRITE if ARM_MPU + help + Enables Nordic Semiconductor flash driver for nRF RRAM controllers. + The entire contiguous block of RRAM gets logically divided into pages, + but partial erase is always supported. + +if SOC_FLASH_NRF_RRAM + +config NRF_RRAM_WRITE_BUFFER_SIZE + int "Internal write-buffer size" + default 32 if !SOC_FLASH_NRF_RADIO_SYNC_NONE + default 0 + range 0 32 + help + Number of 128-bit words. + Maximum buffer size can be configured to the value of 32 (128-bit words). + Set 0 to disable write-buffer. + +config NRF_RRAM_READYNEXT_TIMEOUT_VALUE + int "Preload timeout value for waiting for a next write in RRAMC clock cycles" + default 128 + range 0 4095 + help + Set 0 to disable ready next timeout counter. + +choice SOC_FLASH_NRF_RADIO_SYNC_CHOICE + prompt "Nordic nRFx flash driver synchronization" + default SOC_FLASH_NRF_RADIO_SYNC_TICKER if BT_LL_SW_SPLIT + default SOC_FLASH_NRF_RADIO_SYNC_NONE + help + synchronization between flash memory driver and radio. + +config SOC_FLASH_NRF_RADIO_SYNC_TICKER + bool "Nordic nRFx flash driver synchronized with radio" + depends on BT_LL_SW_SPLIT + help + Enable synchronization between flash memory driver and radio using + BLE LL controller ticker API. + +config SOC_FLASH_NRF_RADIO_SYNC_NONE + bool "none" + help + disable synchronization between flash memory driver and radio. +endchoice + +config SOC_FLASH_NRF_TIMEOUT_MULTIPLIER + int "Multiplier for flash operation timeouts [x0.1]" + depends on !SOC_FLASH_NRF_RADIO_SYNC_NONE + default 1 + help + This is a multiplier that will be divided by 10 that is applied + to the flash erase and write operations timeout. The base for + the multiplication would allow erasing all nRF flash pages in + blocking mode. + +endif # SOC_FLASH_NRF_RRAM diff --git a/drivers/flash/nrf_qspi_nor.c b/drivers/flash/nrf_qspi_nor.c index 28c705f6707..c0e8c397d8e 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 ret = 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); - ret = qspi_get_zephyr_ret_code(res); - qspi_initialized = (ret == 0); - } - - qspi_unlock(dev); - - return ret; -#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 ret = pm_device_runtime_put(dev); - - if (ret < 0) { - LOG_ERR("Failed to schedule device sleep: %d", ret); - } -#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); } @@ -526,27 +461,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 +494,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 +509,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,46 +535,30 @@ 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) */ /* 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; - } - - int rv = 0; const struct qspi_nor_config *params = dev->config; + int rc, rc2; - rv = qspi_device_init(dev); - if (rv != 0) { - goto out; - } - qspi_trans_lock(dev); - rv = qspi_nor_write_protection_set(dev, false); - if (rv != 0) { - goto out_trans_unlock; + rc = qspi_nor_write_protection_set(dev, false); + if (rc != 0) { + return rc; } - qspi_lock(dev); while (size > 0) { nrfx_err_t res = !NRFX_SUCCESS; uint32_t adj = 0; @@ -670,76 +589,20 @@ 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); - - if (!rv) { - rv = rv2; - } -out_trans_unlock: - qspi_trans_unlock(dev); + rc2 = qspi_nor_write_protection_set(dev, true); -out: - qspi_device_uninit(dev); - return rv; + 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; - -#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 - - 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 - - int ret = qspi_get_zephyr_ret_code(res); - if (ret < 0) { - return ret; - } - -#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. - */ - ret = exit_dpd(dev); - if (ret < 0) { - return ret; - } + 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 @@ -769,28 +632,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,20 +665,19 @@ 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, - uint8_t *id) +static int qspi_rdid(const struct device *dev, uint8_t *id) { const struct qspi_buf rx_buf = { .buf = id, @@ -826,18 +688,24 @@ static int qspi_read_jedec_id(const struct device *dev, .rx_buf = &rx_buf, }; - int ret = qspi_device_init(dev); - - if (ret == 0) { - ret = qspi_send_cmd(dev, &cmd, false); - } - qspi_device_uninit(dev); - - return ret; + return qspi_send_cmd(dev, &cmd, false); } #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; +} + static int qspi_sfdp_read(const struct device *dev, off_t offset, void *data, size_t len) { @@ -855,17 +723,10 @@ static int qspi_sfdp_read(const struct device *dev, off_t offset, .io2_level = true, .io3_level = true, }; + nrfx_err_t res; - int ret = qspi_device_init(dev); - nrfx_err_t res = NRFX_SUCCESS; - - if (ret != 0) { - LOG_DBG("qspi_device_init: %d", ret); - qspi_device_uninit(dev); - return ret; - } + qspi_acquire(dev); - qspi_lock(dev); res = nrfx_qspi_lfm_start(&cinstr_cfg); if (res != NRFX_SUCCESS) { LOG_DBG("lfm_start: %x", res); @@ -885,40 +746,13 @@ 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); } #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 ret = qspi_read_jedec_id(dev, id); - - if (ret != 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) @@ -993,6 +827,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 +839,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 +848,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); + qspi_acquire(dev); - nrfx_err_t res = read_non_aligned(dev, addr, dest, size); + res = read_non_aligned(dev, addr, dest, size); - qspi_unlock(dev); + qspi_release(dev); - rc = qspi_get_zephyr_ret_code(res); - -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 +919,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,8 +936,6 @@ static int qspi_nor_write(const struct device *dev, off_t addr, return -EINVAL; } - const struct qspi_nor_config *params = dev->config; - /* affected region should be within device */ if (addr < 0 || (addr + size) > params->size) { @@ -1119,18 +945,12 @@ 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); + qspi_acquire(dev); - if (rc != 0) { - goto out; - } + rc = qspi_nor_write_protection_set(dev, false); + if (rc == 0) { + nrfx_err_t res; - qspi_trans_lock(dev); - res = qspi_nor_write_protection_set(dev, false); - qspi_lock(dev); - if (!res) { if (size < 4U) { res = write_sub_word(dev, addr, src, size); } else if (!nrfx_is_in_ram(src) || @@ -1140,25 +960,31 @@ 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; - } + qspi_release(dev); - rc = qspi_get_zephyr_ret_code(res); -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 || @@ -1169,83 +995,117 @@ static int qspi_nor_erase(const struct device *dev, off_t addr, size_t size) return -EINVAL; } - int ret = qspi_erase(dev, addr, size); + qspi_acquire(dev); - return ret; + rc = qspi_erase(dev, addr, size); + + qspi_release(dev); + + 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; } -/** - * @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 ret = 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 (ret != 0) { - return ret; + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + rc = qspi_get_zephyr_ret_code(res); + 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); - } else { - LOG_DBG("Runtime power management enabled"); +#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)); } -#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) { + /* 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; + } + + 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) { - 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), nrfx_isr, nrfx_qspi_irq_handler, 0); - rc = qspi_nor_configure(dev); + qspi_clock_div_change(); + + rc = qspi_init(dev); + + qspi_clock_div_restore(); + + if (!IS_ENABLED(CONFIG_NORDIC_QSPI_NOR_XIP) && nrfx_qspi_init_check()) { + (void)nrfx_qspi_deactivate(); + } + +#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 */ @@ -1317,11 +1177,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) { @@ -1339,15 +1199,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; + + 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; + } - 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_exit_dpd) { @@ -1362,108 +1241,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 ret; - nrfx_err_t err; + 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 */ - ret = qspi_device_init(dev); - if (ret < 0) { - return ret; - } -#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); +} - ret = enter_dpd(dev); - if (ret < 0) { - return ret; - } +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(); - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_SLEEP); - if (ret < 0) { - return ret; - } - break; + rc = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); + if (rc < 0) { + return rc; + } - case PM_DEVICE_ACTION_RESUME: - ret = pinctrl_apply_state(dev_config->pcfg, - PINCTRL_STATE_DEFAULT); - if (ret < 0) { - return ret; - } - err = nrfx_qspi_init(&dev_config->nrfx_cfg, - qspi_handler, - dev_data); - if (err != NRFX_SUCCESS) { - return -EIO; - } + res = nrfx_qspi_init(&dev_config->nrfx_cfg, qspi_handler, dev->data); + if (res != NRFX_SUCCESS) { + return -EIO; + } - ret = exit_dpd(dev); - if (ret < 0) { - return ret; - } + 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 ret; if (dev_data->xip_enabled == enable) { return; } - ret = qspi_device_init(dev); - - if (ret != 0) { - LOG_ERR("NRF QSPI NOR XIP %s failed with %d\n", enable ? "enable" : "disable", ret); - 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 @@ -1481,11 +1349,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 */ }; @@ -1517,6 +1386,7 @@ static const struct qspi_nor_config qspi_nor_dev_config = { .sck_delay = DT_INST_PROP(0, sck_delay), .spi_mode = INST_0_SPI_MODE, }, + .nrfx_cfg.timeout = CONFIG_NORDIC_QSPI_NOR_TIMEOUT_MS, .size = INST_0_BYTES, .id = DT_INST_PROP(0, jedec_id), 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/drivers/flash/soc_flash_nrf_rram.c b/drivers/flash/soc_flash_nrf_rram.c new file mode 100644 index 00000000000..4930eb31697 --- /dev/null +++ b/drivers/flash/soc_flash_nrf_rram.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_rram_controller + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(flash_nrf_rram, CONFIG_FLASH_LOG_LEVEL); + +#define RRAM DT_INST(0, soc_nv_flash) + +#define RRAM_START DT_REG_ADDR(RRAM) +#define RRAM_SIZE DT_REG_SIZE(RRAM) + +#define PAGE_SIZE DT_PROP(RRAM, erase_block_size) +#define PAGE_COUNT ((RRAM_SIZE) / (PAGE_SIZE)) + +#define WRITE_BLOCK_SIZE_FROM_DT DT_PROP(RRAM, write_block_size) +#define ERASE_VALUE 0xFF + +#ifdef CONFIG_MULTITHREADING +static struct k_sem sem_lock; +#define SYNC_INIT() k_sem_init(&sem_lock, 1, 1) +#define SYNC_LOCK() k_sem_take(&sem_lock, K_FOREVER) +#define SYNC_UNLOCK() k_sem_give(&sem_lock) +#else +#define SYNC_INIT() +#define SYNC_LOCK() +#define SYNC_UNLOCK() +#endif /* CONFIG_MULTITHREADING */ + +#if CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE > 0 +#define WRITE_BUFFER_ENABLE 1 +#define WRITE_BUFFER_SIZE CONFIG_NRF_RRAM_WRITE_BUFFER_SIZE +#define WRITE_LINE_SIZE 16 /* In bytes, one line is 128 bits. */ +#define WRITE_BUFFER_MAX_SIZE (WRITE_BUFFER_SIZE * WRITE_LINE_SIZE) +BUILD_ASSERT((PAGE_SIZE % (WRITE_LINE_SIZE) == 0), "erase-block-size must be a multiple of 16"); +BUILD_ASSERT((WRITE_BLOCK_SIZE_FROM_DT % (WRITE_LINE_SIZE) == 0), + "if NRF_RRAM_WRITE_BUFFER_SIZE > 0, then write-block-size must be a multiple of 16"); +#else +#define WRITE_BUFFER_ENABLE 0 +#define WRITE_BUFFER_SIZE 0 +#define WRITE_LINE_SIZE WRITE_BLOCK_SIZE_FROM_DT +#define WRITE_BUFFER_MAX_SIZE 16 /* In bytes, one line is 128 bits. */ +BUILD_ASSERT((PAGE_SIZE % (WRITE_LINE_SIZE) == 0), + "erase-block-size must be a multiple of write-block-size"); +#endif + +#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE + +#if (WRITE_BUFFER_SIZE < 2) +#define FLASH_SLOT_WRITE 500 +#elif (WRITE_BUFFER_SIZE < 4) +#define FLASH_SLOT_WRITE 1000 +#elif (WRITE_BUFFER_SIZE < 9) +#define FLASH_SLOT_WRITE 2000 +#elif (WRITE_BUFFER_SIZE < 17) +#define FLASH_SLOT_WRITE 4000 +#else +#define FLASH_SLOT_WRITE 8000 /* longest write takes 7107 us */ +#endif + +static int write_op(void *context); /* instance of flash_op_handler_t */ +static int write_synchronously(off_t addr, const void *data, size_t len); + +#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ + +static inline bool is_within_bounds(off_t addr, size_t len, off_t boundary_start, + size_t boundary_size) +{ + return (addr >= boundary_start && (addr < (boundary_start + boundary_size)) && + (len <= (boundary_start + boundary_size - addr))); +} + +#if WRITE_BUFFER_ENABLE +static void commit_changes(size_t len) +{ + if (nrf_rramc_empty_buffer_check(NRF_RRAMC)) { + /* The internal write-buffer has been committed to RRAM and is now empty. */ + return; + } + + if ((len % (WRITE_BUFFER_MAX_SIZE)) == 0) { + /* Our last operation was buffer size-aligned, so we're done. */ + return; + } + + nrf_rramc_task_trigger(NRF_RRAMC, NRF_RRAMC_TASK_COMMIT_WRITEBUF); + + barrier_dmem_fence_full(); +} +#endif + +static void rram_write(off_t addr, const void *data, size_t len) +{ + nrf_rramc_config_t config = {.mode_write = true, .write_buff_size = WRITE_BUFFER_SIZE}; + + nrf_rramc_config_set(NRF_RRAMC, &config); + + if (data) { + memcpy((void *)addr, data, len); + } else { + memset((void *)addr, ERASE_VALUE, len); + } + + barrier_dmem_fence_full(); /* Barrier following our last write. */ + +#if WRITE_BUFFER_ENABLE + commit_changes(len); +#endif + + config.mode_write = false; + nrf_rramc_config_set(NRF_RRAMC, &config); +} + +#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE +static void shift_write_context(uint32_t shift, struct flash_context *w_ctx) +{ + w_ctx->flash_addr += shift; + + /* NULL data_addr => erase emulation request*/ + if (w_ctx->data_addr) { + w_ctx->data_addr += shift; + } + + w_ctx->len -= shift; +} + +static int write_op(void *context) +{ + struct flash_context *w_ctx = context; + size_t len; + + uint32_t i = 0U; + + if (w_ctx->enable_time_limit) { + nrf_flash_sync_get_timestamp_begin(); + } + + while (w_ctx->len > 0) { + len = (w_ctx->len > WRITE_BUFFER_MAX_SIZE) ? WRITE_BUFFER_MAX_SIZE : w_ctx->len; + + rram_write(w_ctx->flash_addr, (const void *)w_ctx->data_addr, len); + + shift_write_context(len, w_ctx); + + if (w_ctx->len > 0) { + i++; + + if (w_ctx->enable_time_limit) { + if (nrf_flash_sync_check_time_limit(i)) { + return FLASH_OP_ONGOING; + } + } + } + } + + return FLASH_OP_DONE; +} + +static int write_synchronously(off_t addr, const void *data, size_t len) +{ + struct flash_context context = { + .data_addr = (uint32_t)data, + .flash_addr = addr, + .len = len, + .enable_time_limit = 1 /* enable time limit */ + }; + + struct flash_op_desc flash_op_desc = {.handler = write_op, .context = &context}; + + nrf_flash_sync_set_context(FLASH_SLOT_WRITE); + return nrf_flash_sync_exe(&flash_op_desc); +} + +#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ + +static int nrf_write(off_t addr, const void *data, size_t len) +{ + int ret = 0; + + if (!is_within_bounds(addr, len, 0, RRAM_SIZE)) { + return -EINVAL; + } + addr += RRAM_START; + + if (!len) { + return 0; + } + + LOG_DBG("Write: %p:%zu", (void *)addr, len); + + SYNC_LOCK(); + +#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE + if (nrf_flash_sync_is_required()) { + ret = write_synchronously(addr, data, len); + } else +#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ + { + rram_write(addr, data, len); + } + + SYNC_UNLOCK(); + + return ret; +} + +static int nrf_rram_read(const struct device *dev, off_t addr, void *data, size_t len) +{ + ARG_UNUSED(dev); + + if (!is_within_bounds(addr, len, 0, RRAM_SIZE)) { + return -EINVAL; + } + addr += RRAM_START; + + memcpy(data, (void *)addr, len); + + return 0; +} + +static int nrf_rram_write(const struct device *dev, off_t addr, const void *data, size_t len) +{ + ARG_UNUSED(dev); + + if (data == NULL) { + return -EINVAL; + } + + return nrf_write(addr, data, len); +} + +static int nrf_rram_erase(const struct device *dev, off_t addr, size_t len) +{ + ARG_UNUSED(dev); + + return nrf_write(addr, NULL, len); +} + +static const struct flash_parameters *nrf_rram_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + static const struct flash_parameters parameters = { + .write_block_size = WRITE_LINE_SIZE, + .erase_value = ERASE_VALUE, + }; + + return ¶meters; +} + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +static void nrf_rram_page_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size) +{ + ARG_UNUSED(dev); + + static const struct flash_pages_layout pages_layout = { + .pages_count = PAGE_COUNT, + .pages_size = PAGE_SIZE, + }; + + *layout = &pages_layout; + *layout_size = 1; +} +#endif + +static const struct flash_driver_api nrf_rram_api = { + .read = nrf_rram_read, + .write = nrf_rram_write, + .erase = nrf_rram_erase, + .get_parameters = nrf_rram_get_parameters, +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + .page_layout = nrf_rram_page_layout, +#endif +}; + +static int nrf_rram_init(const struct device *dev) +{ + ARG_UNUSED(dev); + + SYNC_INIT(); + +#ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE + nrf_flash_sync_init(); +#endif /* !CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE */ + +#if CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE > 0 + nrf_rramc_ready_next_timeout_t params = { + .value = CONFIG_NRF_RRAM_READYNEXT_TIMEOUT_VALUE, + .enable = true, + }; + nrf_rramc_ready_next_timeout_set(NRF_RRAMC, ¶ms); +#endif + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, nrf_rram_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_FLASH_INIT_PRIORITY, + &nrf_rram_api); diff --git a/drivers/gnss/CMakeLists.txt b/drivers/gnss/CMakeLists.txt index 6c24df4903e..cfa5c6ed210 100644 --- a/drivers/gnss/CMakeLists.txt +++ b/drivers/gnss/CMakeLists.txt @@ -7,4 +7,5 @@ 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_NMEA_GENERIC gnss_nmea_generic.c) zephyr_library_sources_ifdef(CONFIG_GNSS_QUECTEL_LCX6G gnss_quectel_lcx6g.c) diff --git a/drivers/gnss/Kconfig b/drivers/gnss/Kconfig index 5bdc0f530d8..2ff552940a3 100644 --- a/drivers/gnss/Kconfig +++ b/drivers/gnss/Kconfig @@ -64,6 +64,7 @@ module = GNSS module-str = gnss source "subsys/logging/Kconfig.template.log_config" +rsource "Kconfig.generic" rsource "Kconfig.quectel_lcx6g" endif diff --git a/drivers/gnss/Kconfig.generic b/drivers/gnss/Kconfig.generic new file mode 100644 index 00000000000..47fbd4a7c6c --- /dev/null +++ b/drivers/gnss/Kconfig.generic @@ -0,0 +1,26 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +config GNSS_NMEA_GENERIC + bool "Generic GNSS NMEA device" + default y + depends on GNSS + depends on DT_HAS_GNSS_NMEA_GENERIC_ENABLED + select MODEM_MODULES + select MODEM_BACKEND_UART + select MODEM_CHAT + select GNSS_PARSE + select GNSS_NMEA0183 + select GNSS_NMEA0183_MATCH + help + Generic NMEA based GNSS device. + +config GNSS_NMEA_GENERIC_SATELLITES_COUNT + int "Maximum satellite count" + depends on GNSS_SATELLITES + default 24 + help + Maximum number of satellite that the driver that can be decoded from + the GNSS device. This does not affect the number of devices that the + device is actually tracking, just how many of those can be reported + in the satellites callback. diff --git a/drivers/gnss/Kconfig.quectel_lcx6g b/drivers/gnss/Kconfig.quectel_lcx6g index 6736015aed7..3036f76d05b 100644 --- a/drivers/gnss/Kconfig.quectel_lcx6g +++ b/drivers/gnss/Kconfig.quectel_lcx6g @@ -15,3 +15,23 @@ config GNSS_QUECTEL_LCX6G select GNSS_NMEA0183_MATCH help Enable quectel LCX6G series GNSS modem driver. + +if GNSS_QUECTEL_LCX6G + +config GNSS_QUECTEL_LCX6G_UART_RX_BUF_SIZE + int "Size of UART backend receive buffer" + default 256 + +config GNSS_QUECTEL_LCX6G_UART_TX_BUF_SIZE + int "Size of UART backend transmit buffer" + default 64 + +if GNSS_SATELLITES + +config GNSS_QUECTEL_LCX6G_SAT_ARRAY_SIZE + int "Size of GNSS satellites array" + default 24 + +endif # GNSS_SATELLITES + +endif # GNSS_QUECTEL_LCX6G diff --git a/drivers/gnss/gnss_dump.c b/drivers/gnss/gnss_dump.c index 1946d65ea2e..f87b64a4946 100644 --- a/drivers/gnss/gnss_dump.c +++ b/drivers/gnss/gnss_dump.c @@ -5,6 +5,7 @@ */ #include "gnss_dump.h" +#include #include #include @@ -94,20 +95,22 @@ int gnss_dump_info(char *str, uint16_t strsize, const struct gnss_info *info) 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); + const char *fmt = "navigation_data: {latitude: %s%lli.%09lli, longitude : %s%lli.%09lli, " + "bearing %u.%03u, speed %u.%03u, altitude: %s%i.%03i}"; + char *lat_sign = nav_data->latitude < 0 ? "-" : ""; + char *lon_sign = nav_data->longitude < 0 ? "-" : ""; + char *alt_sign = nav_data->altitude < 0 ? "-" : ""; + + ret = snprintk(str, strsize, fmt, + lat_sign, + llabs(nav_data->latitude) / 1000000000, + llabs(nav_data->latitude) % 1000000000, + lon_sign, + llabs(nav_data->longitude) / 1000000000, + llabs(nav_data->longitude) % 1000000000, + nav_data->bearing / 1000, nav_data->bearing % 1000, + nav_data->speed / 1000, nav_data->speed % 1000, + alt_sign, abs(nav_data->altitude) / 1000, abs(nav_data->altitude) % 1000); return (strsize < ret) ? -ENOMEM : 0; } diff --git a/drivers/gnss/gnss_nmea0183_match.c b/drivers/gnss/gnss_nmea0183_match.c index 3fe3b159fdb..cd82c552ee4 100644 --- a/drivers/gnss/gnss_nmea0183_match.c +++ b/drivers/gnss/gnss_nmea0183_match.c @@ -4,22 +4,28 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include +#include "gnss_parse.h" #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) +static int gnss_nmea0183_match_parse_utc(char **argv, uint16_t argc, uint32_t *utc) { - int64_t delta; + int64_t i64; - delta = k_uptime_delta(&data->timestamp); - data->timestamp = k_uptime_get(); - return ((uint16_t)delta) > data->timeout_ms; + if ((gnss_parse_dec_to_milli(argv[1], &i64) < 0) || + (i64 < 0) || + (i64 > UINT32_MAX)) { + return -EINVAL; + } + + *utc = (uint32_t)i64; + return 0; } #if CONFIG_GNSS_SATELLITES @@ -30,10 +36,15 @@ static void gnss_nmea0183_match_reset_gsv(struct gnss_nmea0183_match_data *data) } #endif -static void gnss_nmea0183_match_reset(struct gnss_nmea0183_match_data *data) +static void gnss_nmea0183_match_publish(struct gnss_nmea0183_match_data *data) { - data->gga_received = false; - data->rmc_received = false; + if ((data->gga_utc == 0) || (data->rmc_utc == 0)) { + return; + } + + if (data->gga_utc == data->rmc_utc) { + gnss_publish_data(data->gnss, &data->data); + } } void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint16_t argc, @@ -41,19 +52,15 @@ void gnss_nmea0183_match_gga_callback(struct modem_chat *chat, char **argv, uint { 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); + if (gnss_nmea0183_match_parse_utc(argv, argc, &data->gga_utc) < 0) { + return; } + + gnss_nmea0183_match_publish(data); } void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint16_t argc, @@ -61,19 +68,15 @@ void gnss_nmea0183_match_rmc_callback(struct modem_chat *chat, char **argv, uint { 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 (gnss_nmea0183_match_parse_utc(argv, argc, &data->rmc_utc) < 0) { + return; } + + gnss_nmea0183_match_publish(data); } #if CONFIG_GNSS_SATELLITES @@ -84,10 +87,6 @@ void gnss_nmea0183_match_gsv_callback(struct modem_chat *chat, char **argv, uint 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; } @@ -124,7 +123,7 @@ 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"); + __ASSERT(config != NULL, "config argument must be provided"); memset(data, 0, sizeof(struct gnss_nmea0183_match_data)); data->gnss = config->gnss; @@ -132,6 +131,5 @@ int gnss_nmea0183_match_init(struct gnss_nmea0183_match_data *data, 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 index 65104e1dc8a..28ed395320b 100644 --- a/drivers/gnss/gnss_nmea0183_match.h +++ b/drivers/gnss/gnss_nmea0183_match.h @@ -49,11 +49,9 @@ struct gnss_nmea0183_match_data { 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; + uint32_t gga_utc; + uint32_t rmc_utc; + uint8_t gsv_message_number; }; /** GNSS NMEA0183 match configuration structure */ @@ -66,8 +64,6 @@ struct gnss_nmea0183_match_config { /** 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; }; /** diff --git a/drivers/gnss/gnss_nmea_generic.c b/drivers/gnss/gnss_nmea_generic.c new file mode 100644 index 00000000000..2f23f4d7353 --- /dev/null +++ b/drivers/gnss/gnss_nmea_generic.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * Copyright (c) 2023 Bjarki Arge Andreasen + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gnss_nmea0183.h" +#include "gnss_nmea0183_match.h" +#include "gnss_parse.h" + +#include +LOG_MODULE_REGISTER(gnss_nmea_generic, CONFIG_GNSS_LOG_LEVEL); + +#define DT_DRV_COMPAT gnss_nmea_generic + +#define UART_RECV_BUF_SZ 128 +#define CHAT_RECV_BUF_SZ 256 +#define CHAT_ARGV_SZ 32 + +struct gnss_nmea_generic_config { + const struct device *uart; +}; + +struct gnss_nmea_generic_data { + struct gnss_nmea0183_match_data match_data; +#if CONFIG_GNSS_SATELLITES + struct gnss_satellite satellites[CONFIG_GNSS_NMEA_GENERIC_SATELLITES_COUNT]; +#endif + + /* UART backend */ + struct modem_pipe *uart_pipe; + struct modem_backend_uart uart_backend; + uint8_t uart_backend_receive_buf[UART_RECV_BUF_SZ]; + + /* Modem chat */ + struct modem_chat chat; + uint8_t chat_receive_buf[CHAT_RECV_BUF_SZ]; + uint8_t *chat_argv[CHAT_ARGV_SZ]; + + struct k_spinlock lock; +}; + +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 gnss_nmea_generic_resume(const struct device *dev) +{ + struct gnss_nmea_generic_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; + } + + return ret; +} + +static struct gnss_driver_api gnss_api = { +}; + +static int gnss_nmea_generic_init_nmea0183_match(const struct device *dev) +{ + struct gnss_nmea_generic_data *data = dev->data; + + const struct gnss_nmea0183_match_config match_config = { + .gnss = dev, +#if CONFIG_GNSS_SATELLITES + .satellites = data->satellites, + .satellites_size = ARRAY_SIZE(data->satellites), +#endif + }; + + return gnss_nmea0183_match_init(&data->match_data, &match_config); +} + +static void gnss_nmea_generic_init_pipe(const struct device *dev) +{ + const struct gnss_nmea_generic_config *cfg = dev->config; + struct gnss_nmea_generic_data *data = dev->data; + + const struct modem_backend_uart_config uart_backend_config = { + .uart = cfg->uart, + .receive_buf = data->uart_backend_receive_buf, + .receive_buf_size = sizeof(data->uart_backend_receive_buf), + }; + + data->uart_pipe = modem_backend_uart_init(&data->uart_backend, &uart_backend_config); +} + +static uint8_t gnss_nmea_generic_char_delimiter[] = {'\r', '\n'}; + +static int gnss_nmea_generic_init_chat(const struct device *dev) +{ + struct gnss_nmea_generic_data *data = dev->data; + + const struct modem_chat_config chat_config = { + .user_data = data, + .receive_buf = data->chat_receive_buf, + .receive_buf_size = sizeof(data->chat_receive_buf), + .delimiter = gnss_nmea_generic_char_delimiter, + .delimiter_size = ARRAY_SIZE(gnss_nmea_generic_char_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), + }; + + return modem_chat_init(&data->chat, &chat_config); +} + +static int gnss_nmea_generic_init(const struct device *dev) +{ + int ret; + + ret = gnss_nmea_generic_init_nmea0183_match(dev); + if (ret < 0) { + return ret; + } + + gnss_nmea_generic_init_pipe(dev); + + ret = gnss_nmea_generic_init_chat(dev); + if (ret < 0) { + return ret; + } + + ret = gnss_nmea_generic_resume(dev); + if (ret < 0) { + return ret; + } + + return 0; +} + +#define GNSS_NMEA_GENERIC(inst) \ + static struct gnss_nmea_generic_config gnss_nmea_generic_cfg_##inst = { \ + .uart = DEVICE_DT_GET(DT_INST_BUS(inst)), \ + }; \ + \ + static struct gnss_nmea_generic_data gnss_nmea_generic_data_##inst; \ + \ + DEVICE_DT_INST_DEFINE(inst, gnss_nmea_generic_init, NULL, \ + &gnss_nmea_generic_data_##inst, \ + &gnss_nmea_generic_cfg_##inst, \ + POST_KERNEL, CONFIG_GNSS_INIT_PRIORITY, &gnss_api); + +DT_INST_FOREACH_STATUS_OKAY(GNSS_NMEA_GENERIC) diff --git a/drivers/gnss/gnss_publish.c b/drivers/gnss/gnss_publish.c index 98e3a2e5e19..7ddfa5e09fe 100644 --- a/drivers/gnss/gnss_publish.c +++ b/drivers/gnss/gnss_publish.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "gnss_publish.h" +#include #include #include diff --git a/drivers/gnss/gnss_quectel_lcx6g.c b/drivers/gnss/gnss_quectel_lcx6g.c index 0ca7f5203ac..09fa8fd8e4a 100644 --- a/drivers/gnss/gnss_quectel_lcx6g.c +++ b/drivers/gnss/gnss_quectel_lcx6g.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,7 +15,6 @@ #include #include -#include "gnss_publish.h" #include "gnss_nmea0183.h" #include "gnss_nmea0183_match.h" #include "gnss_parse.h" @@ -22,20 +22,18 @@ #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_PM_TIMEOUT_MS 500U +#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_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) +#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; @@ -46,14 +44,14 @@ struct quectel_lcx6g_config { struct quectel_lcx6g_data { struct gnss_nmea0183_match_data match_data; #if CONFIG_GNSS_SATELLITES - struct gnss_satellite satellites[24]; + struct gnss_satellite satellites[CONFIG_GNSS_QUECTEL_LCX6G_SAT_ARRAY_SIZE]; #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]; + uint8_t uart_backend_receive_buf[CONFIG_GNSS_QUECTEL_LCX6G_UART_RX_BUF_SIZE]; + uint8_t uart_backend_transmit_buf[CONFIG_GNSS_QUECTEL_LCX6G_UART_TX_BUF_SIZE]; /* Modem chat */ struct modem_chat chat; @@ -77,6 +75,7 @@ struct quectel_lcx6g_data { }; struct k_spinlock lock; + k_timeout_t pm_timeout; }; #define MODEM_CHAT_SCRIPT_NO_ABORT_DEFINE(_sym, _script_chats, _callback, _timeout) \ @@ -173,35 +172,60 @@ static int quectel_lcx6g_configure_pps(const struct device *dev) return modem_chat_run_script(&data->chat, &data->dynamic_script); } +static void quectel_lcx6g_pm_changed(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + uint32_t pm_ready_at_ms; + + pm_ready_at_ms = k_uptime_get() + QUECTEL_LCX6G_PM_TIMEOUT_MS; + data->pm_timeout = K_TIMEOUT_ABS_MS(pm_ready_at_ms); +} + +static void quectel_lcx6g_await_pm_ready(const struct device *dev) +{ + struct quectel_lcx6g_data *data = dev->data; + + LOG_INF("Waiting until PM ready"); + k_sleep(data->pm_timeout); +} + static int quectel_lcx6g_resume(const struct device *dev) { struct quectel_lcx6g_data *data = dev->data; int ret; + LOG_INF("Resuming"); + + quectel_lcx6g_await_pm_ready(dev); + ret = modem_pipe_open(data->uart_pipe); if (ret < 0) { + LOG_ERR("Failed to open pipe"); return ret; } ret = modem_chat_attach(&data->chat, data->uart_pipe); if (ret < 0) { + LOG_ERR("Failed to attach chat"); modem_pipe_close(data->uart_pipe); return ret; } ret = modem_chat_run_script(&data->chat, &resume_script); if (ret < 0) { + LOG_ERR("Failed to initialize GNSS"); modem_pipe_close(data->uart_pipe); return ret; } - k_msleep(1000); - ret = quectel_lcx6g_configure_pps(dev); if (ret < 0) { + LOG_ERR("Failed to configure PPS"); modem_pipe_close(data->uart_pipe); + return ret; } + LOG_INF("Resumed"); return ret; } @@ -211,18 +235,32 @@ 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); + LOG_INF("Suspending"); + + quectel_lcx6g_await_pm_ready(dev); + + ret = modem_chat_run_script(&data->chat, &suspend_script); if (ret < 0) { - modem_pipe_close(data->uart_pipe); + LOG_ERR("Failed to suspend GNSS"); + } else { + LOG_INF("Suspended"); } + modem_pipe_close(data->uart_pipe); return ret; } +static void quectel_lcx6g_turn_on(const struct device *dev) +{ + LOG_INF("Powered on"); +} + static int quectel_lcx6g_turn_off(const struct device *dev) { struct quectel_lcx6g_data *data = dev->data; + LOG_INF("Powered off"); + return modem_pipe_close(data->uart_pipe); } @@ -244,6 +282,7 @@ static int quectel_lcx6g_pm_action(const struct device *dev, enum pm_device_acti break; case PM_DEVICE_ACTION_TURN_ON: + quectel_lcx6g_turn_on(dev); ret = 0; break; @@ -255,6 +294,8 @@ static int quectel_lcx6g_pm_action(const struct device *dev, enum pm_device_acti break; } + quectel_lcx6g_pm_changed(dev); + k_spin_unlock(&data->lock, key); return ret; } @@ -649,7 +690,6 @@ static int quectel_lcx6g_init_nmea0183_match(const struct device *dev) .satellites = data->satellites, .satellites_size = ARRAY_SIZE(data->satellites), #endif - .timeout_ms = 50, }; return gnss_nmea0183_match_init(&data->match_data, &config); @@ -687,7 +727,6 @@ static int quectel_lcx6g_init_chat(const struct device *dev) .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); @@ -721,7 +760,6 @@ 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; @@ -736,18 +774,19 @@ static int quectel_lcx6g_init(const struct device *dev) 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; + quectel_lcx6g_pm_changed(dev); + + if (pm_device_is_powered(dev)) { + ret = quectel_lcx6g_resume(dev); + if (ret < 0) { + return ret; + } + quectel_lcx6g_pm_changed(dev); + } else { + pm_device_init_off(dev); } -#endif - LOG_INF("Quectel LCX6G initialized"); - return 0; + + return pm_device_runtime_enable(dev); } #define LCX6G_INST_NAME(inst, name) \ diff --git a/drivers/gpio/Kconfig.nrfx b/drivers/gpio/Kconfig.nrfx index 356c43cb5fa..760a45204fd 100644 --- a/drivers/gpio/Kconfig.nrfx +++ b/drivers/gpio/Kconfig.nrfx @@ -5,7 +5,12 @@ menuconfig GPIO_NRFX bool "nRF GPIO driver" default y depends on DT_HAS_NORDIC_NRF_GPIO_ENABLED - select NRFX_GPIOTE + select NRFX_GPIOTE0 if HAS_HW_NRF_GPIOTE0 + select NRFX_GPIOTE1 if HAS_HW_NRF_GPIOTE1 + select NRFX_GPIOTE20 if HAS_HW_NRF_GPIOTE20 + select NRFX_GPIOTE30 if HAS_HW_NRF_GPIOTE30 + select NRFX_GPIOTE130 if HAS_HW_NRF_GPIOTE130 + select NRFX_GPIOTE131 if HAS_HW_NRF_GPIOTE131 help Enable GPIO driver for nRF line of MCUs. diff --git a/drivers/gpio/gpio_b91.c b/drivers/gpio/gpio_b91.c index bc73f9db9f5..4c4c14dc909 100644 --- a/drivers/gpio/gpio_b91.c +++ b/drivers/gpio/gpio_b91.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Driver dts compatibility: telink,b91_gpio */ diff --git a/drivers/gpio/gpio_nrfx.c b/drivers/gpio/gpio_nrfx.c index 0aa282dda37..d89c964cc90 100644 --- a/drivers/gpio/gpio_nrfx.c +++ b/drivers/gpio/gpio_nrfx.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ + #define DT_DRV_COMPAT nordic_nrf_gpio #include @@ -25,6 +26,7 @@ struct gpio_nrfx_cfg { NRF_GPIO_Type *port; uint32_t edge_sense; uint8_t port_num; + nrfx_gpiote_t gpiote; }; static inline struct gpio_nrfx_data *get_port_data(const struct device *port) @@ -37,131 +39,139 @@ static inline const struct gpio_nrfx_cfg *get_port_cfg(const struct device *port return port->config; } -static int get_drive(gpio_flags_t flags, nrf_gpio_pin_drive_t *drive) +static bool has_gpiote(const struct gpio_nrfx_cfg *cfg) +{ + return cfg->gpiote.p_reg != NULL; +} + +static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) +{ + if (flags & GPIO_PULL_UP) { + return NRF_GPIO_PIN_PULLUP; + } else if (flags & GPIO_PULL_DOWN) { + return NRF_GPIO_PIN_PULLDOWN; + } + + return NRF_GPIO_PIN_NOPULL; +} + +static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, + gpio_flags_t flags) { + nrfx_err_t err = NRFX_SUCCESS; + uint8_t 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); + nrf_gpio_pin_pull_t pull = get_pull(flags); + nrf_gpio_pin_drive_t drive; + switch (flags & (NRF_GPIO_DRIVE_MSK | GPIO_OPEN_DRAIN)) { case NRF_GPIO_DRIVE_S0S1: - *drive = NRF_GPIO_PIN_S0S1; + drive = NRF_GPIO_PIN_S0S1; break; case NRF_GPIO_DRIVE_S0H1: - *drive = NRF_GPIO_PIN_S0H1; + drive = NRF_GPIO_PIN_S0H1; break; case NRF_GPIO_DRIVE_H0S1: - *drive = NRF_GPIO_PIN_H0S1; + drive = NRF_GPIO_PIN_H0S1; break; case NRF_GPIO_DRIVE_H0H1: - *drive = NRF_GPIO_PIN_H0H1; + drive = NRF_GPIO_PIN_H0H1; break; case NRF_GPIO_DRIVE_S0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_S0D1; + drive = NRF_GPIO_PIN_S0D1; break; case NRF_GPIO_DRIVE_H0 | GPIO_OPEN_DRAIN: - *drive = NRF_GPIO_PIN_H0D1; + drive = NRF_GPIO_PIN_H0D1; break; case NRF_GPIO_DRIVE_S1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0S1; + drive = NRF_GPIO_PIN_D0S1; break; case NRF_GPIO_DRIVE_H1 | GPIO_OPEN_SOURCE: - *drive = NRF_GPIO_PIN_D0H1; + drive = NRF_GPIO_PIN_D0H1; break; default: return -EINVAL; } - return 0; -} - -static nrf_gpio_pin_pull_t get_pull(gpio_flags_t flags) -{ - if (flags & GPIO_PULL_UP) { - return NRF_GPIO_PIN_PULLUP; - } else if (flags & GPIO_PULL_DOWN) { - return NRF_GPIO_PIN_PULLDOWN; + if (flags & GPIO_OUTPUT_INIT_HIGH) { + nrf_gpio_port_out_set(cfg->port, BIT(pin)); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + nrf_gpio_port_out_clear(cfg->port, BIT(pin)); } - return NRF_GPIO_PIN_NOPULL; -} + if (!has_gpiote(cfg)) { + nrf_gpio_pin_dir_t dir = (flags & GPIO_OUTPUT) + ? NRF_GPIO_PIN_DIR_OUTPUT + : NRF_GPIO_PIN_DIR_INPUT; + nrf_gpio_pin_input_t input = (flags & GPIO_INPUT) + ? NRF_GPIO_PIN_INPUT_CONNECT + : NRF_GPIO_PIN_INPUT_DISCONNECT; -static int gpio_nrfx_pin_configure(const struct device *port, gpio_pin_t pin, - gpio_flags_t flags) -{ - nrfx_err_t err = NRFX_SUCCESS; - uint8_t 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); + nrf_gpio_reconfigure(abs_pin, &dir, &input, &pull, &drive, NULL); + return 0; + } /* 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); + err = nrfx_gpiote_channel_get(&cfg->gpiote, 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. */ - (void)nrfx_gpiote_pin_uninit(abs_pin); - - if (free_ch) { - err = nrfx_gpiote_channel_free(ch); - __ASSERT_NO_MSG(err == NRFX_SUCCESS); + (void)nrfx_gpiote_pin_uninit(&cfg->gpiote, abs_pin); + } else { + /* Remove previously configured trigger when pin is reconfigured. */ + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { + nrfx_gpiote_trigger_config_t trigger_config = { + .trigger = NRFX_GPIOTE_TRIGGER_NONE, + }; + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_trigger_config = &trigger_config, + }; + + err = nrfx_gpiote_input_configure(&cfg->gpiote, + abs_pin, &input_pin_config); + if (err != NRFX_SUCCESS) { + return -EINVAL; + } } - return 0; - } - - if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT)) { - nrfx_gpiote_trigger_config_t trigger_config = { - .trigger = NRFX_GPIOTE_TRIGGER_NONE - }; + if (flags & GPIO_OUTPUT) { + nrfx_gpiote_output_config_t output_config = { + .drive = drive, + .input_connect = (flags & GPIO_INPUT) + ? NRF_GPIO_PIN_INPUT_CONNECT + : NRF_GPIO_PIN_INPUT_DISCONNECT, + .pull = pull, + }; + + err = nrfx_gpiote_output_configure(&cfg->gpiote, + abs_pin, &output_config, NULL); + } else { + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_pull_config = &pull, + }; + + err = nrfx_gpiote_input_configure(&cfg->gpiote, + abs_pin, &input_pin_config); + } - /* 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 (flags & GPIO_OUTPUT) { - nrf_gpio_pin_drive_t drive; - int rv = get_drive(flags, &drive); - - if (rv != 0) { - return rv; - } - - nrfx_gpiote_output_config_t output_config = { - .drive = drive, - .input_connect = (flags & GPIO_INPUT) ? - NRF_GPIO_PIN_INPUT_CONNECT : - NRF_GPIO_PIN_INPUT_DISCONNECT, - .pull = get_pull(flags) - }; - - - if (flags & GPIO_OUTPUT_INIT_HIGH) { - nrf_gpio_port_out_set(cfg->port, BIT(pin)); - } else if (flags & GPIO_OUTPUT_INIT_LOW) { - nrf_gpio_port_out_clear(cfg->port, BIT(pin)); - } - - err = nrfx_gpiote_output_configure(abs_pin, &output_config, NULL); - return (err != NRFX_SUCCESS) ? -EINVAL : 0; + if (IS_ENABLED(CONFIG_GPIO_NRFX_INTERRUPT) && free_ch) { + err = nrfx_gpiote_channel_free(&cfg->gpiote, ch); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); } - nrfx_gpiote_input_config_t input_config = { - .pull = get_pull(flags) - }; - - err = nrfx_gpiote_input_configure(abs_pin, &input_config, NULL, NULL); - - return (err != NRFX_SUCCESS) ? -EINVAL : 0; + return 0; } static int gpio_nrfx_port_get_raw(const struct device *port, @@ -242,12 +252,17 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, enum gpio_int_mode mode, enum gpio_int_trig trig) { - uint32_t abs_pin = NRF_GPIO_PIN_MAP(get_port_cfg(port)->port_num, pin); + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); + uint32_t abs_pin = NRF_GPIO_PIN_MAP(cfg->port_num, pin); nrfx_err_t err; uint8_t ch; + if (!has_gpiote(cfg)) { + return -ENOTSUP; + } + if (mode == GPIO_INT_MODE_DISABLED) { - nrfx_gpiote_trigger_disable(abs_pin); + nrfx_gpiote_trigger_disable(&cfg->gpiote, abs_pin); return 0; } @@ -255,16 +270,19 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, nrfx_gpiote_trigger_config_t trigger_config = { .trigger = get_trigger(mode, trig), }; + nrfx_gpiote_input_pin_config_t input_pin_config = { + .p_trigger_config = &trigger_config, + }; /* If edge mode is to be used and pin is not configured to use sense for * edge use IN event. */ - if (!(BIT(pin) & get_port_cfg(port)->edge_sense) && + if (!(BIT(pin) & cfg->edge_sense) && (mode == GPIO_INT_MODE_EDGE) && (nrf_gpio_pin_dir_get(abs_pin) == NRF_GPIO_PIN_DIR_INPUT)) { - err = nrfx_gpiote_channel_get(abs_pin, &ch); + err = nrfx_gpiote_channel_get(&cfg->gpiote, abs_pin, &ch); if (err == NRFX_ERROR_INVALID_PARAM) { - err = nrfx_gpiote_channel_alloc(&ch); + err = nrfx_gpiote_channel_alloc(&cfg->gpiote, &ch); if (err != NRFX_SUCCESS) { return -ENOMEM; } @@ -273,12 +291,12 @@ static int gpio_nrfx_pin_interrupt_configure(const struct device *port, trigger_config.p_in_channel = &ch; } - err = nrfx_gpiote_input_configure(abs_pin, NULL, &trigger_config, NULL); + err = nrfx_gpiote_input_configure(&cfg->gpiote, abs_pin, &input_pin_config); if (err != NRFX_SUCCESS) { return -EINVAL; } - nrfx_gpiote_trigger_enable(abs_pin, true); + nrfx_gpiote_trigger_enable(&cfg->gpiote, abs_pin, true); return 0; } @@ -367,26 +385,31 @@ static void nrfx_gpio_handler(nrfx_gpiote_pin_t abs_pin, } #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ -#define GPIOTE_NODE DT_INST(0, nordic_nrf_gpiote) +#define GPIOTE_IRQ_HANDLER_CONNECT(node_id) \ + IRQ_CONNECT(DT_IRQN(node_id), DT_IRQ(node_id, priority), nrfx_isr, \ + NRFX_CONCAT(nrfx_gpiote_, DT_PROP(node_id, instance), _irq_handler), 0); static int gpio_nrfx_init(const struct device *port) { + const struct gpio_nrfx_cfg *cfg = get_port_cfg(port); nrfx_err_t err; - if (nrfx_gpiote_is_init()) { + if (!has_gpiote(cfg)) { + return 0; + } + + if (nrfx_gpiote_init_check(&cfg->gpiote)) { return 0; } - err = nrfx_gpiote_init(0/*not used*/); + err = nrfx_gpiote_init(&cfg->gpiote, 0 /*not used*/); if (err != NRFX_SUCCESS) { 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); + nrfx_gpiote_global_callback_set(&cfg->gpiote, nrfx_gpio_handler, NULL); + DT_FOREACH_STATUS_OKAY(nordic_nrf_gpiote, GPIOTE_IRQ_HANDLER_CONNECT); #endif /* CONFIG_GPIO_NRFX_INTERRUPT */ return 0; @@ -408,12 +431,27 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { #endif }; +#define GPIOTE_PHANDLE(id) DT_INST_PHANDLE(id, gpiote_instance) +#define GPIOTE_INST(id) DT_PROP(GPIOTE_PHANDLE(id), instance) + +#define GPIOTE_INSTANCE(id) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ + (NRFX_GPIOTE_INSTANCE(GPIOTE_INST(id))), \ + ({ .p_reg = NULL })) + /* Device instantiation is done with node labels because 'port_num' is * the peripheral number by SoC numbering. We therefore cannot use * DT_INST APIs here without wider changes. */ +#define GPIOTE_CHECK(id) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(id, gpiote_instance), \ + (BUILD_ASSERT(DT_NODE_HAS_STATUS(GPIOTE_PHANDLE(id), okay), \ + "Please enable GPIOTE instance for used GPIO port!")), \ + ()) + #define GPIO_NRF_DEVICE(id) \ + GPIOTE_CHECK(id); \ static const struct gpio_nrfx_cfg gpio_nrfx_p##id##_cfg = { \ .common = { \ .port_pin_mask = \ @@ -421,7 +459,8 @@ static const struct gpio_driver_api gpio_nrfx_drv_api_funcs = { }, \ .port = _CONCAT(NRF_P, DT_INST_PROP(id, port)), \ .port_num = DT_INST_PROP(id, port), \ - .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0) \ + .edge_sense = DT_INST_PROP_OR(id, sense_edge_mask, 0), \ + .gpiote = GPIOTE_INSTANCE(id), \ }; \ \ static struct gpio_nrfx_data gpio_nrfx_p##id##_data; \ diff --git a/drivers/gpio/gpio_sifive.c b/drivers/gpio/gpio_sifive.c index 77703f25707..a412fdd1528 100644 --- a/drivers/gpio/gpio_sifive.c +++ b/drivers/gpio/gpio_sifive.c @@ -18,7 +18,7 @@ #include #include #include - +#include #include typedef void (*sifive_cfg_func_t)(void); diff --git a/drivers/hwinfo/Kconfig b/drivers/hwinfo/Kconfig index 7c4cc7f0805..4bf9e462318 100644 --- a/drivers/hwinfo/Kconfig +++ b/drivers/hwinfo/Kconfig @@ -181,7 +181,7 @@ config HWINFO_GECKO config HWINFO_ANDES bool "Andes system ID" default y - depends on SOC_SERIES_RISCV_ANDES_V5 + depends on SOC_FAMILY_ANDES_V5 help Enable Andes hwinfo driver diff --git a/drivers/hwinfo/hwinfo_nrf.c b/drivers/hwinfo/hwinfo_nrf.c index 2a79f1d0c0d..4375cf05b2f 100644 --- a/drivers/hwinfo/hwinfo_nrf.c +++ b/drivers/hwinfo/hwinfo_nrf.c @@ -58,22 +58,56 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) if (reason & NRFX_RESET_REASON_DIF_MASK) { flags |= RESET_DEBUG; } + if (reason & NRFX_RESET_REASON_SREQ_MASK) { + flags |= RESET_SOFTWARE; + } -#if !NRF_POWER_HAS_RESETREAS +#if NRFX_RESET_REASON_HAS_CTRLAP if (reason & NRFX_RESET_REASON_CTRLAP_MASK) { flags |= RESET_DEBUG; } - if (reason & NRFX_RESET_REASON_DOG0_MASK) { - flags |= RESET_WATCHDOG; +#endif +#if NRFX_RESET_REASON_HAS_LPCOMP + if (reason & NRFX_RESET_REASON_LPCOMP_MASK) { + flags |= RESET_LOW_POWER_WAKE; + } +#endif +#if NRFX_RESET_REASON_HAS_NFC + if (reason & NRFX_RESET_REASON_NFC_MASK) { + flags |= RESET_LOW_POWER_WAKE; + } +#endif +#if NRFX_RESET_REASON_HAS_VBUS + if (reason & NRFX_RESET_REASON_VBUS_MASK) { + flags |= RESET_POR; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPSOFT + if (reason & NRFX_RESET_REASON_CTRLAPSOFT_MASK) { + flags |= RESET_DEBUG; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPHARD + if (reason & NRFX_RESET_REASON_CTRLAPHARD_MASK) { + flags |= RESET_DEBUG; + } +#endif +#if NRFX_RESET_REASON_HAS_CTRLAPPIN + if (reason & NRFX_RESET_REASON_CTRLAPPIN_MASK) { + flags |= RESET_DEBUG; } +#endif +#if !NRF_POWER_HAS_RESETREAS if (reason & NRFX_RESET_REASON_DOG1_MASK) { flags |= RESET_WATCHDOG; } - if (reason & NRFX_RESETREAS_SREQ_MASK) { - flags |= RESET_SOFTWARE; +#endif +#if NRFX_RESET_REASON_HAS_GRTC + if (reason & NRFX_RESET_REASON_GRTC_MASK) { + flags |= RESET_CLOCK; } - -#if NRF_RESET_HAS_NETWORK +#endif +#if NRFX_RESET_REASON_HAS_NETWORK if (reason & NRFX_RESET_REASON_LSREQ_MASK) { flags |= RESET_SOFTWARE; } @@ -87,10 +121,14 @@ int z_impl_hwinfo_get_reset_cause(uint32_t *cause) flags |= RESET_DEBUG; } #endif - -#else - if (reason & NRFX_RESET_REASON_SREQ_MASK) { - flags |= RESET_SOFTWARE; +#if defined(NRFX_RESET_REASON_TAMPC_MASK) + if (reason & NRFX_RESET_REASON_TAMPC_MASK) { + flags |= RESET_SECURITY; + } +#endif +#if defined(NRFX_RESET_REASON_SECTAMPER_MASK) + if (reason & NRFX_RESET_REASON_SECTAMPER_MASK) { + flags |= RESET_SECURITY; } #endif diff --git a/drivers/i2s/i2s_nrfx.c b/drivers/i2s/i2s_nrfx.c index e1b3684c4f7..3c5af08e592 100644 --- a/drivers/i2s/i2s_nrfx.c +++ b/drivers/i2s/i2s_nrfx.c @@ -501,7 +501,8 @@ static int i2s_nrfx_configure(const struct device *dev, enum i2s_dir dir, * the MCK output is used), find a suitable clock configuration for it. */ if (nrfx_cfg.mode == NRF_I2S_MODE_MASTER || - nrfx_cfg.mck_pin != NRF_I2S_PIN_NOT_CONNECTED) { + (nrf_i2s_mck_pin_get(drv_cfg->i2s.p_reg) & I2S_PSEL_MCK_CONNECT_Msk) + == I2S_PSEL_MCK_CONNECT_Connected << I2S_PSEL_MCK_CONNECT_Pos) { find_suitable_clock(drv_cfg, &nrfx_cfg, i2s_cfg); /* Unless the PCLK32M source is used with the HFINT oscillator * (which is always available without any additional actions), diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig index feccd4a6001..d692024b096 100644 --- a/drivers/ieee802154/Kconfig +++ b/drivers/ieee802154/Kconfig @@ -98,11 +98,6 @@ config IEEE802154_CSL_DEBUG help Enable support for CSL debugging by avoiding sleep state in favor of receive state. -config IEEE802154_SELECTIVE_TXPOWER - bool "Support selective TX power setting" - help - Enable support for selectively setting TX power for every transmission request. - module = IEEE802154_DRIVER module-str = IEEE 802.15.4 driver module-help = Sets log level for IEEE 802.15.4 Device Drivers. diff --git a/drivers/ieee802154/ieee802154_b91.c b/drivers/ieee802154/ieee802154_b91.c index 0557c533944..0897b2b54df 100644 --- a/drivers/ieee802154/ieee802154_b91.c +++ b/drivers/ieee802154/ieee802154_b91.c @@ -26,6 +26,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #endif +#include + #include "ieee802154_b91.h" diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 9a02aef7e4c..80435f06fba 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -57,6 +57,9 @@ struct nrf5_802154_config { }; static struct nrf5_802154_data nrf5_data; +#if defined(CONFIG_IEEE802154_RAW_MODE) +static const struct device *nrf5_dev; +#endif #define DRX_SLOT_RX 0 /* Delayed reception window ID */ @@ -95,6 +98,15 @@ static struct nrf5_802154_data nrf5_data; #define IEEE802154_NRF5_VENDOR_OUI (uint32_t)0xF4CE36 #endif +static inline const struct device *nrf5_get_device(void) +{ +#if defined(CONFIG_IEEE802154_RAW_MODE) + return nrf5_dev; +#else + return net_if_get_device(nrf5_data.iface); +#endif +} + static void nrf5_get_eui64(uint8_t *mac) { uint64_t factoryAddress; @@ -224,6 +236,7 @@ static void nrf5_get_capabilities_at_boot(void) ((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) | ((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) | IEEE802154_HW_SLEEP_TO_TX | + IEEE802154_RX_ON_WHEN_IDLE | ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL) #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) | IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA @@ -363,7 +376,7 @@ static int nrf5_set_txpower(const struct device *dev, int16_t dbm) LOG_DBG("%d", dbm); - nrf_802154_tx_power_set(dbm); + nrf5_data.txpwr = dbm; return 0; } @@ -374,6 +387,17 @@ static int handle_ack(struct nrf5_802154_data *nrf5_radio) struct net_pkt *ack_pkt; int err = 0; +#if defined(CONFIG_NET_PKT_TIMESTAMP) + if (nrf5_radio->ack_frame.time == NRF_802154_NO_TIMESTAMP) { + /* Ack timestamp is invalid and cannot be used by the upper layer. + * Report the transmission as failed as if the Ack was not received at all. + */ + LOG_WRN("Invalid ACK timestamp."); + err = -ENOMSG; + goto free_nrf_ack; + } +#endif + if (IS_ENABLED(CONFIG_IEEE802154_NRF5_FCS_IN_LENGTH)) { ack_len = nrf5_radio->ack_frame.psdu[0]; } else { @@ -442,10 +466,8 @@ static bool nrf5_tx_immediate(struct net_pkt *pkt, uint8_t *payload, bool cca) }, .cca = cca, .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, }; @@ -461,10 +483,8 @@ static bool nrf5_tx_csma_ca(struct net_pkt *pkt, uint8_t *payload) .dynamic_data_is_set = net_pkt_ieee802154_mac_hdr_rdy(pkt), }, .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, }; @@ -507,10 +527,8 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, .cca = cca, .channel = nrf_802154_channel_get(), .tx_power = { - .use_metadata_value = IS_ENABLED(CONFIG_IEEE802154_SELECTIVE_TXPOWER), -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - .power = net_pkt_ieee802154_txpwr(pkt), -#endif + .use_metadata_value = true, + .power = nrf5_data.txpwr, }, #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) .extra_cca_attempts = max_extra_cca_attempts, @@ -648,6 +666,8 @@ static int nrf5_start(const struct device *dev) { ARG_UNUSED(dev); + nrf_802154_tx_power_set(nrf5_data.txpwr); + if (!nrf_802154_receive()) { LOG_ERR("Failed to enter receive state"); return -EIO; @@ -690,6 +710,8 @@ static int nrf5_continuous_carrier(const struct device *dev) { ARG_UNUSED(dev); + nrf_802154_tx_power_set(nrf5_data.txpwr); + if (!nrf_802154_continuous_carrier()) { LOG_ERR("Failed to enter continuous carrier state"); return -EIO; @@ -726,6 +748,9 @@ static int nrf5_init(const struct device *dev) { const struct nrf5_802154_config *nrf5_radio_cfg = NRF5_802154_CFG(dev); struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); +#if defined(CONFIG_IEEE802154_RAW_MODE) + nrf5_dev = dev; +#endif k_fifo_init(&nrf5_radio->rx_fifo); k_sem_init(&nrf5_radio->tx_wait, 0, 1); @@ -735,6 +760,7 @@ static int nrf5_init(const struct device *dev) nrf5_get_capabilities_at_boot(); + nrf5_radio->rx_on_when_idle = true; nrf5_radio_cfg->irq_config_func(dev); k_thread_create(&nrf5_radio->rx_thread, nrf5_radio->rx_stack, @@ -766,25 +792,17 @@ static void nrf5_iface_init(struct net_if *iface) #if defined(CONFIG_NRF_802154_ENCRYPTION) static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys) { - static nrf_802154_key_id_t stored_key_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE]; - static uint8_t stored_ids[NRF_802154_SECURITY_KEY_STORAGE_SIZE]; - uint8_t i; + nrf_802154_security_key_remove_all(); - for (i = 0; i < NRF_802154_SECURITY_KEY_STORAGE_SIZE && stored_key_ids[i].p_key_id; i++) { - nrf_802154_security_key_remove(&stored_key_ids[i]); - stored_key_ids[i].p_key_id = NULL; - } - - i = 0; - for (struct ieee802154_key *keys = mac_keys; keys->key_value - && i < NRF_802154_SECURITY_KEY_STORAGE_SIZE; keys++, i++) { + for (uint8_t i = 0; mac_keys->key_value + && i < NRF_802154_SECURITY_KEY_STORAGE_SIZE; mac_keys++, i++) { nrf_802154_key_t key = { - .value.p_cleartext_key = keys->key_value, - .id.mode = keys->key_id_mode, - .id.p_key_id = &(keys->key_index), + .value.p_cleartext_key = mac_keys->key_value, + .id.mode = mac_keys->key_id_mode, + .id.p_key_id = mac_keys->key_id, .type = NRF_802154_KEY_CLEARTEXT, .frame_counter = 0, - .use_global_frame_counter = !(keys->frame_counter_per_key), + .use_global_frame_counter = !(mac_keys->frame_counter_per_key), }; __ASSERT_EVAL((void)nrf_802154_security_key_store(&key), @@ -792,10 +810,6 @@ static void nrf5_config_mac_keys(struct ieee802154_key *mac_keys) err == NRF_802154_SECURITY_ERROR_NONE || err == NRF_802154_SECURITY_ERROR_ALREADY_PRESENT, "Storing key failed, err: %d", err); - - stored_ids[i] = *key.id.p_key_id; - stored_key_ids[i].mode = key.id.mode; - stored_key_ids[i].p_key_id = &stored_ids[i]; }; } #endif /* CONFIG_NRF_802154_ENCRYPTION */ @@ -882,35 +896,44 @@ static int nrf5_configure(const struct device *dev, uint8_t ext_addr_le[EXTENDED_ADDRESS_SIZE]; uint8_t short_addr_le[SHORT_ADDRESS_SIZE]; uint8_t element_id; + bool valid_vendor_specific_ie = false; + + if (config->ack_ie.purge_ie) { + nrf_802154_ack_data_remove_all(false, NRF_802154_ACK_DATA_IE); + nrf_802154_ack_data_remove_all(true, NRF_802154_ACK_DATA_IE); + break; + } 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); + sys_put_le16(config->ack_ie.short_addr, short_addr_le); + sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE); - 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 (config->ack_ie.header_ie == NULL || config->ack_ie.header_ie->length == 0) { + 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); + } else { + element_id = ieee802154_header_ie_get_element_id(config->ack_ie.header_ie); #if defined(CONFIG_NET_L2_OPENTHREAD) - uint8_t vendor_oui_le[IEEE802154_OPENTHREAD_VENDOR_OUI_LEN] = - IEEE802154_OPENTHREAD_THREAD_IE_VENDOR_OUI; + 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; - } + 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)) == 0) { + valid_vendor_specific_ie = true; + } #endif - sys_put_le16(config->ack_ie.short_addr, short_addr_le); - sys_memcpy_swap(ext_addr_le, config->ack_ie.ext_addr, EXTENDED_ADDRESS_SIZE); + if (element_id != IEEE802154_HEADER_IE_ELEMENT_ID_CSL_IE && + !valid_vendor_specific_ie) { + return -ENOTSUP; + } - 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, @@ -919,9 +942,6 @@ static int nrf5_configure(const struct device *dev, 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); } } break; @@ -930,9 +950,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 */ @@ -972,6 +992,11 @@ static int nrf5_configure(const struct device *dev, break; #endif /* CONFIG_IEEE802154_NRF5_MULTIPLE_CCA */ + case IEEE802154_CONFIG_RX_ON_WHEN_IDLE: + nrf_802154_rx_on_when_idle_set(config->rx_on_when_idle); + nrf5_data.rx_on_when_idle = config->rx_on_when_idle; + break; + default: return -EINVAL; } @@ -1046,22 +1071,16 @@ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi, void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) { - const struct device *dev = net_if_get_device(nrf5_data.iface); + const struct device *dev = nrf5_get_device(); #if defined(CONFIG_IEEE802154_CSL_ENDPOINT) - if (id == DRX_SLOT_RX) { - __ASSERT_NO_MSG(nrf5_data.event_handler); -#if !defined(CONFIG_IEEE802154_CSL_DEBUG) - /* When CSL debug option is used we intentionally avoid notifying the higher layer - * about the finalization of a DRX slot, so that the radio stays in receive state - * for receiving "out of slot" frames. - * As a side effect, regular failure notifications would be reported with the - * incorrect ID. - */ - nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); -#endif - if (error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) { + if (id == DRX_SLOT_RX && error == NRF_802154_RX_ERROR_DELAYED_TIMEOUT) { + if (!nrf5_data.rx_on_when_idle) { + /* Transition to RxOff done automatically by the driver */ return; + } else if (nrf5_data.event_handler) { + /* Notify the higher layer to allow it to transition if needed */ + nrf5_data.event_handler(dev, IEEE802154_EVENT_RX_OFF, NULL); } } #else @@ -1122,8 +1141,14 @@ void nrf_802154_transmitted_raw(uint8_t *frame, nrf5_data.ack_frame.lqi = metadata->data.transmitted.lqi; #if defined(CONFIG_NET_PKT_TIMESTAMP) - nrf5_data.ack_frame.time = nrf_802154_timestamp_end_to_phr_convert( - metadata->data.transmitted.time, nrf5_data.ack_frame.psdu[0]); + if (metadata->data.transmitted.time == NRF_802154_NO_TIMESTAMP) { + /* Ack timestamp is invalid. Keep this value to detect it when handling Ack + */ + nrf5_data.ack_frame.time = NRF_802154_NO_TIMESTAMP; + } else { + nrf5_data.ack_frame.time = nrf_802154_timestamp_end_to_phr_convert( + metadata->data.transmitted.time, nrf5_data.ack_frame.psdu[0]); + } #endif } @@ -1165,7 +1190,7 @@ void nrf_802154_energy_detected(const nrf_802154_energy_detected_t *result) energy_scan_done_cb_t callback = nrf5_data.energy_scan_done; nrf5_data.energy_scan_done = NULL; - callback(net_if_get_device(nrf5_data.iface), result->ed_dbm); + callback(nrf5_get_device(), result->ed_dbm); } } @@ -1175,7 +1200,7 @@ void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error) energy_scan_done_cb_t callback = nrf5_data.energy_scan_done; nrf5_data.energy_scan_done = NULL; - callback(net_if_get_device(nrf5_data.iface), SHRT_MAX); + callback(nrf5_get_device(), SHRT_MAX); } } diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index 9115fe0bdae..b1c95548210 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -97,6 +97,9 @@ struct nrf5_802154_data { uint8_t max_extra_cca_attempts; #endif + /* The TX power in dBm. */ + int8_t txpwr; + #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; @@ -104,6 +107,9 @@ struct nrf5_802154_data { /* 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 */ + + /* Indicates if RxOnWhenIdle mode is enabled. */ + bool rx_on_when_idle; }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ diff --git a/drivers/interrupt_controller/intc_plic.c b/drivers/interrupt_controller/intc_plic.c index 51ce1769396..211a6f11041 100644 --- a/drivers/interrupt_controller/intc_plic.c +++ b/drivers/interrupt_controller/intc_plic.c @@ -135,7 +135,7 @@ static int riscv_plic_is_edge_irq(const struct device *dev, uint32_t local_irq) * @brief Enable a riscv PLIC-specific interrupt line * * This routine enables a RISCV PLIC-specific interrupt line. - * riscv_plic_irq_enable is called by SOC_FAMILY_RISCV_PRIVILEGED + * riscv_plic_irq_enable is called by RISCV_PRIVILEGED * arch_irq_enable function to enable external interrupts for * IRQS level == 2, whenever CONFIG_RISCV_HAS_PLIC variable is set. * @@ -161,7 +161,7 @@ void riscv_plic_irq_enable(uint32_t irq) * @brief Disable a riscv PLIC-specific interrupt line * * This routine disables a RISCV PLIC-specific interrupt line. - * riscv_plic_irq_disable is called by SOC_FAMILY_RISCV_PRIVILEGED + * riscv_plic_irq_disable is called by RISCV_PRIVILEGED * arch_irq_disable function to disable external interrupts, for * IRQS level == 2, whenever CONFIG_RISCV_HAS_PLIC variable is set. * diff --git a/drivers/interrupt_controller/intc_swerv_pic.c b/drivers/interrupt_controller/intc_swerv_pic.c index 5c52ab49614..96eb248d27c 100644 --- a/drivers/interrupt_controller/intc_swerv_pic.c +++ b/drivers/interrupt_controller/intc_swerv_pic.c @@ -15,6 +15,7 @@ #include #include #include +#include #define SWERV_PIC_MAX_NUM CONFIG_NUM_IRQS #define SWERV_PIC_MAX_ID (SWERV_PIC_MAX_NUM + RISCV_MAX_GENERIC_IRQ) @@ -176,14 +177,14 @@ static int swerv_pic_init(const struct device *dev) __asm__ swerv_pic_writecsr(meicurpl, 0); /* Setup IRQ handler for SweRV PIC driver */ - IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, + IRQ_CONNECT(RISCV_IRQ_MEXT, 0, swerv_pic_irq_handler, NULL, 0); /* Enable IRQ for SweRV PIC driver */ - irq_enable(RISCV_MACHINE_EXT_IRQ); + irq_enable(RISCV_IRQ_MEXT); return 0; } diff --git a/drivers/interrupt_controller/intc_vexriscv_litex.c b/drivers/interrupt_controller/intc_vexriscv_litex.c index efec4d2478e..2d5d2233ab2 100644 --- a/drivers/interrupt_controller/intc_vexriscv_litex.c +++ b/drivers/interrupt_controller/intc_vexriscv_litex.c @@ -11,6 +11,7 @@ #include #include #include +#include #define IRQ_MASK DT_INST_REG_ADDR_BY_NAME(0, irq_mask) #define IRQ_PENDING DT_INST_REG_ADDR_BY_NAME(0, irq_pending) @@ -122,9 +123,9 @@ int arch_irq_is_enabled(unsigned int irq) static int vexriscv_litex_irq_init(const struct device *dev) { __asm__ volatile ("csrrs x0, mie, %0" - :: "r"(1 << RISCV_MACHINE_EXT_IRQ)); + :: "r"(1 << RISCV_IRQ_MEXT)); vexriscv_litex_irq_setie(1); - IRQ_CONNECT(RISCV_MACHINE_EXT_IRQ, 0, vexriscv_litex_irq_handler, + IRQ_CONNECT(RISCV_IRQ_MEXT, 0, vexriscv_litex_irq_handler, NULL, 0); return 0; diff --git a/drivers/mbox/CMakeLists.txt b/drivers/mbox/CMakeLists.txt index b81a3bb679f..476e131f00b 100644 --- a/drivers/mbox/CMakeLists.txt +++ b/drivers/mbox/CMakeLists.txt @@ -9,3 +9,7 @@ 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) +zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_LOCAL mbox_nrf_vevif_local.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_VEVIF_REMOTE mbox_nrf_vevif_remote.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_LOCAL mbox_nrf_bellboard_local.c) +zephyr_library_sources_ifdef(CONFIG_MBOX_NRF_BELLBOARD_REMOTE mbox_nrf_bellboard_remote.c) diff --git a/drivers/mbox/Kconfig b/drivers/mbox/Kconfig index 0668c9aab8b..eb138dca145 100644 --- a/drivers/mbox/Kconfig +++ b/drivers/mbox/Kconfig @@ -15,6 +15,8 @@ source "drivers/mbox/Kconfig.nrfx" source "drivers/mbox/Kconfig.nxp_s32" source "drivers/mbox/Kconfig.nxp_imx" source "drivers/mbox/Kconfig.andes" +source "drivers/mbox/Kconfig.nrf_vevif" +source "drivers/mbox/Kconfig.nrf_bellboard" config MBOX_INIT_PRIORITY int "MBOX init priority" diff --git a/drivers/mbox/Kconfig.nrf_bellboard b/drivers/mbox/Kconfig.nrf_bellboard new file mode 100644 index 00000000000..45233122bd5 --- /dev/null +++ b/drivers/mbox/Kconfig.nrf_bellboard @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_NRF_BELLBOARD_LOCAL + bool "nRF BELLBOARD local driver" + depends on DT_HAS_NORDIC_NRF_BELLBOARD_LOCAL_ENABLED + default y + help + Mailbox driver for local Nordic nRF BELLBOARD + +config MBOX_NRF_BELLBOARD_REMOTE + bool "nRF BELLBOARD remote driver" + depends on DT_HAS_NORDIC_NRF_BELLBOARD_REMOTE_ENABLED + default y + help + Mailbox driver for remote Nordic nRF BELLBOARD diff --git a/drivers/mbox/Kconfig.nrf_vevif b/drivers/mbox/Kconfig.nrf_vevif new file mode 100644 index 00000000000..4abb0ef8241 --- /dev/null +++ b/drivers/mbox/Kconfig.nrf_vevif @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config MBOX_NRF_VEVIF_LOCAL + bool "nRF VEVIF local driver" + depends on DT_HAS_NORDIC_NRF_VEVIF_LOCAL_ENABLED + default y + help + Mailbox driver for local Nordic nRF VEVIF (VPR Event Interface) + +config MBOX_NRF_VEVIF_REMOTE + bool "nRF VEVIF remote driver" + depends on DT_HAS_NORDIC_NRF_VEVIF_REMOTE_ENABLED + default y + help + Mailbox driver for remote Nordic nRF VEVIF (VPR Event Interface) diff --git a/drivers/mbox/mbox_andes_plic_sw.c b/drivers/mbox/mbox_andes_plic_sw.c index bc01da73a30..e2c287ae216 100644 --- a/drivers/mbox/mbox_andes_plic_sw.c +++ b/drivers/mbox/mbox_andes_plic_sw.c @@ -199,11 +199,11 @@ static void andes_plic_sw_irq_handler(const struct device *dev) static int mbox_andes_init(const struct device *dev) { /* Setup IRQ handler for PLIC SW driver */ - IRQ_CONNECT(RISCV_MACHINE_SOFT_IRQ, 1, + IRQ_CONNECT(RISCV_IRQ_MSOFT, 1, andes_plic_sw_irq_handler, DEVICE_DT_INST_GET(0), 0); #ifndef CONFIG_SMP - irq_enable(RISCV_MACHINE_SOFT_IRQ); + irq_enable(RISCV_IRQ_MSOFT); #endif return 0; } diff --git a/drivers/mbox/mbox_nrf_bellboard_local.c b/drivers/mbox/mbox_nrf_bellboard_local.c new file mode 100644 index 00000000000..99d05351aaa --- /dev/null +++ b/drivers/mbox/mbox_nrf_bellboard_local.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_bellboard_local + +#include +#include +#include + +#include + +#define BELLBOARD_NUM_IRQS 4U + +BUILD_ASSERT(DT_NUM_IRQS(DT_DRV_INST(0)) <= BELLBOARD_NUM_IRQS, "# interrupt exceeds maximum"); + +BUILD_ASSERT((DT_INST_PROP_LEN(0, nordic_interrupt_mapping) % 2) == 0, + "# interrupt mappings not specified in pairs"); + +/* BELLBOARD event mappings */ +#define EVT_MAPPING_ITEM(idx) DT_INST_PROP_BY_IDX(0, nordic_interrupt_mapping, idx) +#define BELLBOARD_GET_EVT_MAPPING(idx, _) \ + COND_CODE_1( \ + DT_INST_PROP_HAS_IDX(0, nordic_interrupt_mapping, UTIL_INC(UTIL_X2(idx))), \ + ([EVT_MAPPING_ITEM(UTIL_INC(UTIL_X2(idx)))] = EVT_MAPPING_ITEM(UTIL_X2(idx)),), \ + ()) + +static const uint32_t evt_mappings[BELLBOARD_NUM_IRQS] = { + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(0)), BELLBOARD_GET_EVT_MAPPING, ())}; + +/* BELLBOARD instance */ +static NRF_BELLBOARD_Type *bellboard = (NRF_BELLBOARD_Type *)DT_INST_REG_ADDR(0); + +/* BELLBOARD runtime resources */ +static mbox_callback_t cbs[NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT]; +static void *cbs_ctx[NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT]; +static uint32_t evt_enabled_masks[BELLBOARD_NUM_IRQS]; + +static void bellboard_local_isr(const void *parameter) +{ + uint8_t irq_idx = (uint8_t)(uintptr_t)parameter; + uint32_t int_pend; + + int_pend = nrf_bellboard_int_pending_get(bellboard, irq_idx); + + for (uint8_t i = 0U; i < NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT; i++) { + nrf_bellboard_event_t event = nrf_bellboard_triggered_event_get(i); + + if (nrf_bellboard_event_check(bellboard, event)) { + nrf_bellboard_event_clear(bellboard, event); + } + + if ((int_pend & BIT(i)) != 0U) { + if (cbs[i] != NULL) { + cbs[i](DEVICE_DT_INST_GET(0), i, cbs_ctx[i], NULL); + } + } + } +} + +static uint32_t bellboard_local_max_channels_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT; +} + +static int bellboard_local_register_callback(const struct device *dev, uint32_t id, + mbox_callback_t cb, void *user_data) +{ + ARG_UNUSED(dev); + + if (id >= NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT) { + return -EINVAL; + } + + cbs[id] = cb; + cbs_ctx[id] = user_data; + + return 0; +} + +static int bellboard_local_set_enabled(const struct device *dev, uint32_t id, bool enable) +{ + bool valid_found = false; + + ARG_UNUSED(dev); + + if (id >= NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT) { + return -EINVAL; + } + + for (uint8_t i = 0U; i < BELLBOARD_NUM_IRQS; i++) { + uint32_t *evt_enabled_mask; + + if ((evt_mappings[i] == 0U) || ((evt_mappings[i] & BIT(id)) == 0U)) { + continue; + } + + valid_found = true; + evt_enabled_mask = &evt_enabled_masks[i]; + + if (enable) { + if ((*evt_enabled_mask & BIT(id)) != 0U) { + return -EALREADY; + } + + *evt_enabled_mask |= BIT(id); + nrf_bellboard_int_enable(bellboard, i, BIT(id)); + } else { + if ((*evt_enabled_mask & BIT(id)) == 0U) { + return -EALREADY; + } + + *evt_enabled_mask &= ~BIT(id); + nrf_bellboard_int_disable(bellboard, i, BIT(id)); + } + } + + if (!valid_found) { + return -EINVAL; + } + + return 0; +} + +static const struct mbox_driver_api bellboard_local_driver_api = { + .max_channels_get = bellboard_local_max_channels_get, + .register_callback = bellboard_local_register_callback, + .set_enabled = bellboard_local_set_enabled, +}; + +#define BELLBOARD_IRQ_CONFIGURE(name, idx) \ + COND_CODE_1(DT_INST_IRQ_HAS_NAME(0, name), \ + (IRQ_CONNECT(DT_INST_IRQ_BY_NAME(0, name, irq), \ + DT_INST_IRQ_BY_NAME(0, name, priority), bellboard_local_isr, \ + (const void *)idx, 0); \ + irq_enable(DT_INST_IRQ_BY_NAME(0, name, irq));), \ + ()) + +static int bellboard_local_init(const struct device *dev) +{ + uint32_t evt_all_mappings = + evt_mappings[0] | evt_mappings[1] | evt_mappings[2] | evt_mappings[3]; + + ARG_UNUSED(dev); + + nrf_bellboard_int_disable(bellboard, 0, evt_mappings[0]); + nrf_bellboard_int_disable(bellboard, 1, evt_mappings[1]); + nrf_bellboard_int_disable(bellboard, 2, evt_mappings[2]); + nrf_bellboard_int_disable(bellboard, 3, evt_mappings[3]); + + for (uint8_t i = 0U; i < NRF_BELLBOARD_EVENTS_TRIGGERED_COUNT; i++) { + if ((evt_all_mappings & BIT(i)) != 0U) { + nrf_bellboard_event_clear(bellboard, nrf_bellboard_triggered_event_get(i)); + } + } + + BELLBOARD_IRQ_CONFIGURE(irq0, 0); + BELLBOARD_IRQ_CONFIGURE(irq1, 1); + BELLBOARD_IRQ_CONFIGURE(irq2, 2); + BELLBOARD_IRQ_CONFIGURE(irq3, 3); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, bellboard_local_init, NULL, NULL, NULL, POST_KERNEL, + CONFIG_MBOX_INIT_PRIORITY, &bellboard_local_driver_api); diff --git a/drivers/mbox/mbox_nrf_bellboard_remote.c b/drivers/mbox/mbox_nrf_bellboard_remote.c new file mode 100644 index 00000000000..c362522c0bf --- /dev/null +++ b/drivers/mbox/mbox_nrf_bellboard_remote.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_bellboard_remote + +#include +#include + +#include + +struct mbox_bellboard_remote_conf { + NRF_BELLBOARD_Type *bellboard; +}; + +static int bellboard_remote_send(const struct device *dev, uint32_t id, const struct mbox_msg *msg) +{ + const struct mbox_bellboard_remote_conf *config = dev->config; + + if (id >= BELLBOARD_TASKS_TRIGGER_MaxCount) { + return -EINVAL; + } + + if (msg != NULL) { + return -ENOTSUP; + } + + nrfy_bellboard_task_trigger(config->bellboard, nrf_bellboard_trigger_task_get(id)); + + return 0; +} + +static int bellboard_remote_mtu_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return 0; +} + +static uint32_t bellboard_remote_max_channels_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return BELLBOARD_TASKS_TRIGGER_MaxCount; +} + +static const struct mbox_driver_api bellboard_remote_driver_api = { + .send = bellboard_remote_send, + .mtu_get = bellboard_remote_mtu_get, + .max_channels_get = bellboard_remote_max_channels_get, +}; + +#define BELLBOARD_REMOTE_DEFINE(inst) \ + static const struct mbox_bellboard_remote_conf conf##inst = { \ + .bellboard = (NRF_BELLBOARD_Type *)DT_INST_REG_ADDR(inst), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, &conf##inst, POST_KERNEL, \ + CONFIG_MBOX_INIT_PRIORITY, &bellboard_remote_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(BELLBOARD_REMOTE_DEFINE) diff --git a/drivers/mbox/mbox_nrf_vevif_local.c b/drivers/mbox/mbox_nrf_vevif_local.c new file mode 100644 index 00000000000..31b89e1e6fb --- /dev/null +++ b/drivers/mbox/mbox_nrf_vevif_local.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_vevif_local + +#include +#include + +#include +#include +#include + +#define VEVIF_TASKS_NUM DT_INST_PROP(0, nordic_tasks) +#define VEVIF_TASKS_MASK DT_INST_PROP(0, nordic_tasks_mask) + +BUILD_ASSERT(VEVIF_TASKS_NUM <= VPR_TASKS_TRIGGER_MaxCount, "Number of tasks exceeds maximum"); +BUILD_ASSERT(VEVIF_TASKS_NUM == DT_NUM_IRQS(DT_DRV_INST(0)), "# IRQs != # tasks"); + +/* callbacks */ +struct mbox_vevif_local_cbs { + mbox_callback_t cb[VEVIF_TASKS_NUM]; + void *user_data[VEVIF_TASKS_NUM]; + uint32_t enabled_mask; +}; + +static struct mbox_vevif_local_cbs cbs; + +/* IRQ list */ +#define VEVIF_IRQN(idx, _) DT_INST_IRQ_BY_IDX(0, idx, irq) + +static const uint8_t vevif_irqs[VEVIF_TASKS_NUM] = { + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(0)), VEVIF_IRQN, (,)) +}; + +static void vevif_local_isr(const void *parameter) +{ + uint8_t id = *(uint8_t *)parameter; + + nrf_vpr_csr_vevif_tasks_clear(BIT(id)); + + if (cbs.cb[id] != NULL) { + cbs.cb[id](DEVICE_DT_INST_GET(0), id, cbs.user_data[id], NULL); + } +} + +static inline bool vevif_local_is_task_valid(uint32_t id) +{ + return (id < VEVIF_TASKS_NUM) && ((VEVIF_TASKS_MASK & BIT(id)) != 0U); +} + +static uint32_t vevif_local_max_channels_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return VEVIF_TASKS_NUM; +} + +static int vevif_local_register_callback(const struct device *dev, uint32_t id, mbox_callback_t cb, + void *user_data) +{ + ARG_UNUSED(dev); + + if (!vevif_local_is_task_valid(id)) { + return -EINVAL; + } + + cbs.cb[id] = cb; + cbs.user_data[id] = user_data; + + return 0; +} + +static int vevif_local_set_enabled(const struct device *dev, uint32_t id, bool enable) +{ + ARG_UNUSED(dev); + + if (!vevif_local_is_task_valid(id)) { + return -EINVAL; + } + + if (enable) { + if ((cbs.enabled_mask & BIT(id)) != 0U) { + return -EALREADY; + } + + cbs.enabled_mask |= BIT(id); + irq_enable(vevif_irqs[id]); + } else { + if ((cbs.enabled_mask & BIT(id)) == 0U) { + return -EALREADY; + } + + cbs.enabled_mask &= ~BIT(id); + irq_disable(vevif_irqs[id]); + } + + return 0; +} + +static const struct mbox_driver_api vevif_local_driver_api = { + .max_channels_get = vevif_local_max_channels_get, + .register_callback = vevif_local_register_callback, + .set_enabled = vevif_local_set_enabled, +}; + +#define VEVIF_IRQ_CONNECT(idx, _) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(0, idx, irq), DT_INST_IRQ_BY_IDX(0, idx, priority), \ + vevif_local_isr, &vevif_irqs[idx], 0) + +static int vevif_local_init(const struct device *dev) +{ + nrf_vpr_csr_rtperiph_enable_set(true); + nrf_vpr_csr_vevif_tasks_clear(NRF_VPR_TASK_TRIGGER_ALL_MASK); + + LISTIFY(DT_NUM_IRQS(DT_DRV_INST(0)), VEVIF_IRQ_CONNECT, (;)); + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, vevif_local_init, NULL, NULL, NULL, POST_KERNEL, CONFIG_MBOX_INIT_PRIORITY, + &vevif_local_driver_api); diff --git a/drivers/mbox/mbox_nrf_vevif_remote.c b/drivers/mbox/mbox_nrf_vevif_remote.c new file mode 100644 index 00000000000..cb5d7c507c5 --- /dev/null +++ b/drivers/mbox/mbox_nrf_vevif_remote.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_vevif_remote + +#include +#include + +#include + +struct mbox_vevif_remote_conf { + NRF_VPR_Type *vpr; + uint32_t tasks_mask; + uint8_t tasks; +}; + +static inline bool vevif_remote_is_task_valid(const struct device *dev, uint32_t id) +{ + const struct mbox_vevif_remote_conf *config = dev->config; + + return (id < config->tasks) && ((config->tasks_mask & BIT(id)) != 0U); +} + +static int vevif_remote_send(const struct device *dev, uint32_t id, const struct mbox_msg *msg) +{ + const struct mbox_vevif_remote_conf *config = dev->config; + + if (!vevif_remote_is_task_valid(dev, id)) { + return -EINVAL; + } + + if (msg != NULL) { + return -ENOTSUP; + } + + nrfy_vpr_task_trigger(config->vpr, nrfy_vpr_trigger_task_get(id)); + + return 0; +} + +static int vevif_remote_mtu_get(const struct device *dev) +{ + ARG_UNUSED(dev); + + return 0; +} + +static uint32_t vevif_remote_max_channels_get(const struct device *dev) +{ + const struct mbox_vevif_remote_conf *config = dev->config; + + return config->tasks; +} + +static const struct mbox_driver_api vevif_remote_driver_api = { + .send = vevif_remote_send, + .mtu_get = vevif_remote_mtu_get, + .max_channels_get = vevif_remote_max_channels_get, +}; + +#define VEVIF_REMOTE_DEFINE(inst) \ + BUILD_ASSERT(DT_INST_PROP(inst, nordic_tasks) <= VPR_TASKS_TRIGGER_MaxCount, \ + "Number of tasks exceeds maximum"); \ + \ + static const struct mbox_vevif_remote_conf conf##inst = { \ + .vpr = (NRF_VPR_Type *)DT_INST_REG_ADDR(inst), \ + .tasks = DT_INST_PROP(inst, nordic_tasks), \ + .tasks_mask = DT_INST_PROP(inst, nordic_tasks_mask), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, NULL, NULL, NULL, &conf##inst, POST_KERNEL, \ + CONFIG_MBOX_INIT_PRIORITY, &vevif_remote_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(VEVIF_REMOTE_DEFINE) diff --git a/drivers/mfd/mfd_npm6001.c b/drivers/mfd/mfd_npm6001.c index 1a077791816..b03b10b4cba 100644 --- a/drivers/mfd/mfd_npm6001.c +++ b/drivers/mfd/mfd_npm6001.c @@ -11,6 +11,7 @@ #include /* nPM6001 registers */ +#define NPM6001_SWREADY 0x01U #define NPM6001_BUCK3SELDAC 0x44U #define NPM6001_BUCKMODEPADCONF 0x4EU #define NPM6001_PADDRIVESTRENGTH 0x53U @@ -60,6 +61,12 @@ static int mfd_npm6001_init(const struct device *dev) return ret; } + /* Enable switching to hysteresis mode */ + ret = i2c_reg_write_byte_dt(&config->i2c, NPM6001_SWREADY, 1U); + if (ret < 0) { + return ret; + } + return 0; } diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index 863f839184e..c23bdb185de 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -6,3 +6,5 @@ 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) +add_subdirectory_ifdef(CONFIG_DEVMUX devmux) +add_subdirectory_ifdef(CONFIG_NORDIC_VPR_LAUNCHER nordic_vpr_launcher) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 66d83fc693d..3511b8b6fd4 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -10,5 +10,7 @@ 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" +source "drivers/misc/devmux/Kconfig" +source "drivers/misc/nordic_vpr_launcher/Kconfig" endmenu diff --git a/drivers/misc/devmux/CMakeLists.txt b/drivers/misc/devmux/CMakeLists.txt new file mode 100644 index 00000000000..94f74ea57ce --- /dev/null +++ b/drivers/misc/devmux/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_syscall_header( + ${ZEPHYR_BASE}/include/zephyr/drivers/misc/devmux/devmux.h +) + +zephyr_library_sources(devmux.c) diff --git a/drivers/misc/devmux/Kconfig b/drivers/misc/devmux/Kconfig new file mode 100644 index 00000000000..4f848b4e06c --- /dev/null +++ b/drivers/misc/devmux/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +config DEVMUX + bool "Device Multiplexer (devmux) [EXPERIMENTAL]" + depends on DT_HAS_ZEPHYR_DEVMUX_ENABLED + depends on DEVICE_MUTABLE + select EXPERIMENTAL + help + Devmux is a pseudo-device that operates as a device switch. It allows + software to select the data, config, and api from a number of linked + devices. + +if DEVMUX + +config DEVMUX_INIT_PRIORITY + int "Devmux init priority" + default 51 + help + Init priority for the devmux driver. It must be + greater than the priority of the initially selected muxed device. + +endif diff --git a/drivers/misc/devmux/devmux.c b/drivers/misc/devmux/devmux.c new file mode 100644 index 00000000000..653236f903d --- /dev/null +++ b/drivers/misc/devmux/devmux.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_devmux + +#include +#include +#include +#include + +struct devmux_config { + const struct device **devs; + const size_t n_devs; +}; + +struct devmux_data { + struct k_spinlock lock; + size_t selected; +}; + +/* The number of devmux devices */ +#define N DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) + +static const struct device *devmux_devices[N]; +static const struct devmux_config *devmux_configs[N]; +static struct devmux_data *devmux_datas[N]; + +static bool devmux_device_is_valid(const struct device *dev) +{ + for (size_t i = 0; i < N; ++i) { + if (dev == devmux_devices[i]) { + return true; + } + } + + return false; +} + +static size_t devmux_inst_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return i; + } + } + + return SIZE_MAX; +} + +const struct devmux_config *devmux_config_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return devmux_configs[i]; + } + } + + return NULL; +} + +struct devmux_data *devmux_data_get(const struct device *dev) +{ + for (size_t i = 0; i < N; i++) { + if (dev == devmux_devices[i]) { + return devmux_datas[i]; + } + } + + return NULL; +} + +ssize_t z_impl_devmux_select_get(const struct device *dev) +{ + ssize_t index; + struct devmux_data *const data = devmux_data_get(dev); + + if (!devmux_device_is_valid(dev)) { + return -EINVAL; + } + + K_SPINLOCK(&data->lock) + { + index = data->selected; + } + + return index; +} + +#ifdef CONFIG_USERSPACE +ssize_t z_vrfy_devmux_select_get(const struct device *dev) +{ + return z_impl_devmux_select_get(dev); +} +#include +#endif + +int z_impl_devmux_select_set(struct device *dev, size_t index) +{ + struct devmux_data *const data = devmux_data_get(dev); + const struct devmux_config *config = devmux_config_get(dev); + + if (!devmux_device_is_valid(dev) || index >= config->n_devs) { + return -EINVAL; + } + + if (!device_is_ready(config->devs[index])) { + return -ENODEV; + } + + K_SPINLOCK(&data->lock) + { + *dev = *config->devs[index]; + data->selected = index; + } + + return 0; +} + +#ifdef CONFIG_USERSPACE +int z_vrfy_devmux_select_set(struct device *dev, size_t index) +{ + return z_impl_devmux_select_set(dev, index); +} +#include +#endif + +static int devmux_init(struct device *const dev) +{ + size_t inst = devmux_inst_get(dev); + struct devmux_data *const data = dev->data; + const struct devmux_config *config = dev->config; + size_t sel = data->selected; + + devmux_configs[inst] = config; + devmux_datas[inst] = data; + + if (!device_is_ready(config->devs[sel])) { + return -ENODEV; + } + + *dev = *config->devs[sel]; + + return 0; +} + +#define DEVMUX_PHANDLE_TO_DEVICE(node_id, prop, idx) \ + DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)) + +#define DEVMUX_PHANDLE_DEVICES(_n) \ + DT_INST_FOREACH_PROP_ELEM_SEP(_n, devices, DEVMUX_PHANDLE_TO_DEVICE, (,)) + +#define DEVMUX_SELECTED(_n) DT_INST_PROP(_n, selected) + +#define DEVMUX_DEFINE(_n) \ + BUILD_ASSERT(DT_INST_PROP_OR(_n, zephyr_mutable, 0), \ + "devmux nodes must contain the 'zephyr,mutable' property"); \ + BUILD_ASSERT(DT_INST_PROP_LEN(_n, devices) > 0, "devices array must have non-zero size"); \ + BUILD_ASSERT(DEVMUX_SELECTED(_n) >= 0, "selected must be > 0"); \ + BUILD_ASSERT(DEVMUX_SELECTED(_n) < DT_INST_PROP_LEN(_n, devices), \ + "selected must be within bounds of devices phandle array"); \ + static const struct device *demux_devs_##_n[] = {DEVMUX_PHANDLE_DEVICES(_n)}; \ + static const struct devmux_config devmux_config_##_n = { \ + .devs = demux_devs_##_n, \ + .n_devs = DT_INST_PROP_LEN(_n, devices), \ + }; \ + static struct devmux_data devmux_data_##_n = { \ + .selected = DEVMUX_SELECTED(_n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(_n, devmux_init, NULL, &devmux_data_##_n, &devmux_config_##_n, \ + PRE_KERNEL_1, CONFIG_DEVMUX_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(DEVMUX_DEFINE) + +#define DEVMUX_DEVICE_GET(_n) DEVICE_DT_INST_GET(_n), +static const struct device *devmux_devices[] = {DT_INST_FOREACH_STATUS_OKAY(DEVMUX_DEVICE_GET)}; diff --git a/drivers/misc/nordic_vpr_launcher/CMakeLists.txt b/drivers/misc/nordic_vpr_launcher/CMakeLists.txt new file mode 100644 index 00000000000..70c84e84217 --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(nordic_vpr_launcher.c) diff --git a/drivers/misc/nordic_vpr_launcher/Kconfig b/drivers/misc/nordic_vpr_launcher/Kconfig new file mode 100644 index 00000000000..6aeabcd251c --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/Kconfig @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config NORDIC_VPR_LAUNCHER + bool "Nordic VPR coprocessor launcher" + default y + depends on DT_HAS_NORDIC_NRF_VPR_COPROCESSOR_ENABLED + help + When enabled, the VPR coprocessors will be automatically launched + during system initialization. + +if NORDIC_VPR_LAUNCHER + +module = NORDIC_VPR_LAUNCHER +module-str = Nordic VPR Launcher +source "subsys/logging/Kconfig.template.log_config" + +config NORDIC_VPR_LAUNCHER_INIT_PRIORITY + int "Nordic VPR coprocessor launcher init priority" + default 0 + help + The init priority of the VPR coprocessor launcher. + +endif # NORDIC_VPR_LAUNCHER diff --git a/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c new file mode 100644 index 00000000000..64d4969081b --- /dev/null +++ b/drivers/misc/nordic_vpr_launcher/nordic_vpr_launcher.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_vpr_coprocessor + +#include + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(nordic_vpr_launcher, CONFIG_NORDIC_VPR_LAUNCHER_LOG_LEVEL); + +struct nordic_vpr_launcher_config { + NRF_VPR_Type *vpr; + uintptr_t exec_addr; +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(source_memory) + uintptr_t src_addr; + size_t src_size; +#endif +}; + +static int nordic_vpr_launcher_init(const struct device *dev) +{ + const struct nordic_vpr_launcher_config *config = dev->config; + +#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(source_memory) + if (config->src_size > 0U) { + LOG_DBG("Loading VPR (%p) from %p to %p (%zu bytes)", config->vpr, + (void *)config->src_addr, (void *)config->exec_addr, config->src_size); + memcpy((void *)config->exec_addr, (void *)config->src_addr, config->src_size); + } +#endif + + LOG_DBG("Launching VPR (%p) from %p", config->vpr, (void *)config->exec_addr); + nrf_vpr_initpc_set(config->vpr, config->exec_addr); + nrf_vpr_cpurun_set(config->vpr, true); + + return 0; +} + +/* obtain VPR address either from memory or partition */ +#define VPR_ADDR(node_id) \ + (DT_REG_ADDR(node_id) + \ + COND_CODE_0(DT_FIXED_PARTITION_EXISTS(node_id), (0), (DT_REG_ADDR(DT_GPARENT(node_id))))) + +#define NORDIC_VPR_LAUNCHER_DEFINE(inst) \ + COND_CODE_1(DT_NODE_HAS_PROP(inst, source_memory), \ + (BUILD_ASSERT((DT_REG_SIZE(DT_INST_PHANDLE(inst, execution_memory)) == \ + DT_REG_SIZE(DT_INST_PHANDLE(inst, source_memory))), \ + "Source/execution memory sizes mismatch");), \ + ()) \ + \ + static const struct nordic_vpr_launcher_config config##inst = { \ + .vpr = (NRF_VPR_Type *)DT_INST_REG_ADDR(inst), \ + .exec_addr = VPR_ADDR(DT_INST_PHANDLE(inst, execution_memory)), \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, source_memory), \ + (.src_addr = VPR_ADDR(DT_INST_PHANDLE(inst, source_memory)), \ + .src_size = DT_REG_SIZE(DT_INST_PHANDLE(inst, source_memory)),), \ + ())}; \ + \ + DEVICE_DT_INST_DEFINE(inst, nordic_vpr_launcher_init, NULL, NULL, &config##inst, \ + POST_KERNEL, CONFIG_NORDIC_VPR_LAUNCHER_INIT_PRIORITY, NULL); + +DT_INST_FOREACH_STATUS_OKAY(NORDIC_VPR_LAUNCHER_DEFINE) diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig index c233d5db821..02e3557918f 100644 --- a/drivers/modem/Kconfig +++ b/drivers/modem/Kconfig @@ -142,6 +142,8 @@ config MODEM_CMD_HANDLER_MAX_PARAM_COUNT of the match_buf (match_buf_len) field as it needs to be large enough to hold a single line of data (ending with /r). +endif # MODEM_CONTEXT + config MODEM_SOCKET bool "Generic modem socket support layer" help @@ -165,8 +167,6 @@ config MODEM_SOCKET_PACKET_COUNT these values are organized into "packets". This setting limits the maximum number of packet sizes the socket can keep track of. -endif # MODEM_CONTEXT - config MODEM_SHELL bool "Modem shell utilities" select SHELL diff --git a/drivers/modem/Kconfig.cellular b/drivers/modem/Kconfig.cellular index 7817fb599e3..aacf4449d28 100644 --- a/drivers/modem/Kconfig.cellular +++ b/drivers/modem/Kconfig.cellular @@ -11,10 +11,12 @@ config MODEM_CELLULAR select MODEM_BACKEND_UART select RING_BUFFER select NET_L2_PPP_OPTION_MRU + select NET_L2_PPP_PAP 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_QUECTEL_EG25_G_ENABLED) + DT_HAS_U_BLOX_SARA_R5_ENABLED || DT_HAS_SWIR_HL7800_ENABLED || \ + DT_HAS_TELIT_ME910G1_ENABLED || DT_HAS_QUECTEL_EG25_G_ENABLED || \ + DT_HAS_NORDIC_NRF91_SLM_ENABLED) help This driver uses the generic 3gpp AT commands, along with the standard protocols CMUX and PPP, to configure @@ -35,4 +37,18 @@ config MODEM_CELLULAR_PERIODIC_SCRIPT_MS int "Periodic script interval in milliseconds" default 2000 +config MODEM_CELLULAR_UART_BUFFER_SIZES + int "The UART receive and transmit buffer sizes in bytes." + default 512 + +config MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE + int "The maximum CMUX frame size in bytes." + default 128 + help + This value affects the size of buffers used to receive and transmit CMUX frames. + +config MODEM_CELLULAR_CHAT_BUFFER_SIZES + int "The size of the buffers used for the chat scripts in bytes." + default 128 + endif diff --git a/drivers/modem/modem_cellular.c b/drivers/modem/modem_cellular.c index c3b97f0b618..276c9d38f7b 100644 --- a/drivers/modem/modem_cellular.c +++ b/drivers/modem/modem_cellular.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,23 @@ LOG_MODULE_REGISTER(modem_cellular, CONFIG_MODEM_LOG_LEVEL); #define MODEM_CELLULAR_PERIODIC_SCRIPT_TIMEOUT \ K_MSEC(CONFIG_MODEM_CELLULAR_PERIODIC_SCRIPT_MS) +#define MODEM_CELLULAR_DATA_IMEI_LEN (15) +#define MODEM_CELLULAR_DATA_MODEL_ID_LEN (64) +#define MODEM_CELLULAR_DATA_IMSI_LEN (22) +#define MODEM_CELLULAR_DATA_ICCID_LEN (22) +#define MODEM_CELLULAR_DATA_MANUFACTURER_LEN (64) +#define MODEM_CELLULAR_DATA_FW_VERSION_LEN (64) + +/* Magic constants */ +#define CSQ_RSSI_UNKNOWN (99) +#define CESQ_RSRP_UNKNOWN (255) +#define CESQ_RSRQ_UNKNOWN (255) + +/* Magic numbers to units conversions */ +#define CSQ_RSSI_TO_DB(v) (-113 + (2 * (rssi))) +#define CESQ_RSRP_TO_DB(v) (-140 + (v)) +#define CESQ_RSRQ_TO_DB(v) (-20 + ((v) / 2)) + enum modem_cellular_state { MODEM_CELLULAR_STATE_IDLE = 0, MODEM_CELLULAR_STATE_RESET_PULSE, @@ -61,33 +79,41 @@ struct modem_cellular_data { /* UART backend */ struct modem_pipe *uart_pipe; struct modem_backend_uart uart_backend; - uint8_t uart_backend_receive_buf[512]; - uint8_t uart_backend_transmit_buf[512]; + uint8_t uart_backend_receive_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES]; + uint8_t uart_backend_transmit_buf[CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES]; /* CMUX */ struct modem_cmux cmux; - uint8_t cmux_receive_buf[128]; - uint8_t cmux_transmit_buf[256]; + uint8_t cmux_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE]; + uint8_t cmux_transmit_buf[2 * CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE]; struct modem_cmux_dlci dlci1; struct modem_cmux_dlci dlci2; struct modem_pipe *dlci1_pipe; struct modem_pipe *dlci2_pipe; - uint8_t dlci1_receive_buf[128]; - uint8_t dlci2_receive_buf[256]; + uint8_t dlci1_receive_buf[CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE]; + /* DLCI 2 is only used for chat scripts. */ + uint8_t dlci2_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES]; /* Modem chat */ struct modem_chat chat; - uint8_t chat_receive_buf[128]; - uint8_t chat_delimiter[1]; - uint8_t chat_filter[1]; + uint8_t chat_receive_buf[CONFIG_MODEM_CELLULAR_CHAT_BUFFER_SIZES]; + uint8_t *chat_delimiter; + uint8_t *chat_filter; uint8_t *chat_argv[32]; /* Status */ - uint8_t imei[15]; - uint8_t hwinfo[64]; uint8_t registration_status_gsm; uint8_t registration_status_gprs; uint8_t registration_status_lte; + uint8_t rssi; + uint8_t rsrp; + uint8_t rsrq; + uint8_t imei[MODEM_CELLULAR_DATA_IMEI_LEN]; + uint8_t model_id[MODEM_CELLULAR_DATA_MODEL_ID_LEN]; + uint8_t imsi[MODEM_CELLULAR_DATA_IMSI_LEN]; + uint8_t iccid[MODEM_CELLULAR_DATA_ICCID_LEN]; + uint8_t manufacturer[MODEM_CELLULAR_DATA_MANUFACTURER_LEN]; + uint8_t fw_version[MODEM_CELLULAR_DATA_FW_VERSION_LEN]; /* PPP */ struct modem_ppp *ppp; @@ -114,6 +140,7 @@ struct modem_cellular_config { const uint16_t reset_pulse_duration_ms; const uint16_t startup_time_ms; const uint16_t shutdown_time_ms; + const bool autostarts; const struct modem_chat_script *init_chat_script; const struct modem_chat_script *dial_chat_script; const struct modem_chat_script *periodic_chat_script; @@ -275,16 +302,34 @@ static void modem_cellular_chat_on_imei(struct modem_chat *chat, char **argv, ui return; } - if (strlen(argv[1]) != 15) { + strncpy(data->imei, argv[1], sizeof(data->imei) - 1); +} + +static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + if (argc != 2) { return; } - for (uint8_t i = 0; i < 15; i++) { - data->imei[i] = argv[1][i] - '0'; + strncpy(data->model_id, argv[1], sizeof(data->model_id) - 1); +} + +static void modem_cellular_chat_on_cgmi(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + if (argc != 2) { + return; } + + strncpy(data->manufacturer, argv[1], sizeof(data->manufacturer) - 1); } -static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, uint16_t argc, +static void modem_cellular_chat_on_cgmr(struct modem_chat *chat, char **argv, uint16_t argc, void *user_data) { struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; @@ -293,7 +338,40 @@ static void modem_cellular_chat_on_cgmm(struct modem_chat *chat, char **argv, ui return; } - strncpy(data->hwinfo, argv[1], sizeof(data->hwinfo) - 1); + strncpy(data->fw_version, argv[1], sizeof(data->fw_version) - 1); +} + +static void modem_cellular_chat_on_csq(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + if (argc != 3) { + return; + } + + data->rssi = (uint8_t)atoi(argv[1]); +} + +static void modem_cellular_chat_on_cesq(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + if (argc != 7) { + return; + } + + data->rsrq = (uint8_t)atoi(argv[5]); + data->rsrp = (uint8_t)atoi(argv[6]); +} + +static void modem_cellular_chat_on_imsi(struct modem_chat *chat, char **argv, uint16_t argc, + void *user_data) +{ + struct modem_cellular_data *data = (struct modem_cellular_data *)user_data; + + strncpy(data->imsi, argv[1], sizeof(data->imsi) - 1); } static bool modem_cellular_is_registered(struct modem_cellular_data *data) @@ -345,6 +423,11 @@ MODEM_CHAT_MATCHES_DEFINE(allow_match, MODEM_CHAT_MATCH_DEFINE(imei_match, "", "", modem_cellular_chat_on_imei); MODEM_CHAT_MATCH_DEFINE(cgmm_match, "", "", modem_cellular_chat_on_cgmm); +MODEM_CHAT_MATCH_DEFINE(csq_match, "+CSQ: ", ",", modem_cellular_chat_on_csq); +MODEM_CHAT_MATCH_DEFINE(cesq_match, "+CESQ: ", ",", modem_cellular_chat_on_cesq); +MODEM_CHAT_MATCH_DEFINE(cimi_match __maybe_unused, "", "", modem_cellular_chat_on_imsi); +MODEM_CHAT_MATCH_DEFINE(cgmi_match __maybe_unused, "", "", modem_cellular_chat_on_cgmi); +MODEM_CHAT_MATCH_DEFINE(cgmr_match __maybe_unused, "", "", modem_cellular_chat_on_cgmr); MODEM_CHAT_MATCHES_DEFINE(unsol_matches, MODEM_CHAT_MATCH("+CREG: ", ",", modem_cellular_chat_on_cxreg), @@ -363,13 +446,13 @@ MODEM_CHAT_MATCHES_DEFINE(dial_abort_matches, static void modem_cellular_log_state_changed(enum modem_cellular_state last_state, enum modem_cellular_state new_state) { - LOG_INF("switch from %s to %s", modem_cellular_state_str(last_state), + LOG_DBG("switch from %s to %s", modem_cellular_state_str(last_state), modem_cellular_state_str(new_state)); } static void modem_cellular_log_event(enum modem_cellular_event evt) { - LOG_INF("event %s", modem_cellular_event_str(evt)); + LOG_DBG("event %s", modem_cellular_event_str(evt)); } static void modem_cellular_start_timer(struct modem_cellular_data *data, k_timeout_t timeout) @@ -444,6 +527,11 @@ static void modem_cellular_idle_event_handler(struct modem_cellular_data *data, switch (evt) { case MODEM_CELLULAR_EVENT_RESUME: + if (config->autostarts) { + modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_POWER_ON); + break; + } + if (modem_cellular_gpio_is_enabled(&config->power_gpio)) { modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_POWER_ON_PULSE); break; @@ -1177,6 +1265,153 @@ static void modem_cellular_cmux_handler(struct modem_cmux *cmux, enum modem_cmux } } +MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_csq_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(get_signal_csq_chat_script, get_signal_csq_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 2); + +static inline int modem_cellular_csq_parse_rssi(uint8_t rssi, int16_t *value) +{ + /* AT+CSQ returns a response +CSQ: , where: + * - rssi is a integer from 0 to 31 whose values describes a signal strength + * between -113 dBm for 0 and -51dbM for 31 or unknown for 99 + * - ber is an integer from 0 to 7 that describes the error rate, it can also + * be 99 for an unknown error rate + */ + if (rssi == CSQ_RSSI_UNKNOWN) { + return -EINVAL; + } + + *value = (int16_t)CSQ_RSSI_TO_DB(rssi); + return 0; +} + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(get_signal_cesq_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CESQ", cesq_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(get_signal_cesq_chat_script, get_signal_cesq_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 2); + +/* AT+CESQ returns a response +CESQ: ,,,,, where: + * - rsrq is a integer from 0 to 34 whose values describes the Reference Signal Receive + * Quality between -20 dB for 0 and -3 dB for 34 (0.5 dB steps), or unknown for 255 + * - rsrp is an integer from 0 to 97 that describes the Reference Signal Receive Power + * between -140 dBm for 0 and -44 dBm for 97 (1 dBm steps), or unknown for 255 + */ +static inline int modem_cellular_cesq_parse_rsrp(uint8_t rsrp, int16_t *value) +{ + if (rsrp == CESQ_RSRP_UNKNOWN) { + return -EINVAL; + } + + *value = (int16_t)CESQ_RSRP_TO_DB(rsrp); + return 0; +} + +static inline int modem_cellular_cesq_parse_rsrq(uint8_t rsrq, int16_t *value) +{ + if (rsrq == CESQ_RSRQ_UNKNOWN) { + return -EINVAL; + } + + *value = (int16_t)CESQ_RSRQ_TO_DB(rsrq); + return 0; +} + +static int modem_cellular_get_signal(const struct device *dev, + const enum cellular_signal_type type, + int16_t *value) +{ + int ret = -ENOTSUP; + struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data; + + if ((data->state != MODEM_CELLULAR_STATE_AWAIT_REGISTERED) && + (data->state != MODEM_CELLULAR_STATE_CARRIER_ON)) { + return -ENODATA; + } + + /* Run chat script */ + switch (type) { + case CELLULAR_SIGNAL_RSSI: + ret = modem_chat_run_script(&data->chat, &get_signal_csq_chat_script); + break; + + case CELLULAR_SIGNAL_RSRP: + case CELLULAR_SIGNAL_RSRQ: + ret = modem_chat_run_script(&data->chat, &get_signal_cesq_chat_script); + break; + + default: + ret = -ENOTSUP; + break; + } + + /* Verify chat script ran successfully */ + if (ret < 0) { + return ret; + } + + /* Parse received value */ + switch (type) { + case CELLULAR_SIGNAL_RSSI: + ret = modem_cellular_csq_parse_rssi(data->rssi, value); + break; + + case CELLULAR_SIGNAL_RSRP: + ret = modem_cellular_cesq_parse_rsrp(data->rsrp, value); + break; + + case CELLULAR_SIGNAL_RSRQ: + ret = modem_cellular_cesq_parse_rsrq(data->rsrq, value); + break; + + default: + ret = -ENOTSUP; + break; + } + + return ret; +} + +static int modem_cellular_get_modem_info(const struct device *dev, + enum cellular_modem_info_type type, + char *info, size_t size) +{ + int ret = 0; + struct modem_cellular_data *data = (struct modem_cellular_data *)dev->data; + + switch (type) { + case CELLULAR_MODEM_INFO_IMEI: + strncpy(info, &data->imei[0], MIN(size, sizeof(data->imei))); + break; + case CELLULAR_MODEM_INFO_SIM_IMSI: + strncpy(info, &data->imsi[0], MIN(size, sizeof(data->imsi))); + break; + case CELLULAR_MODEM_INFO_MANUFACTURER: + strncpy(info, &data->manufacturer[0], MIN(size, sizeof(data->manufacturer))); + break; + case CELLULAR_MODEM_INFO_FW_VERSION: + strncpy(info, &data->fw_version[0], MIN(size, sizeof(data->fw_version))); + break; + case CELLULAR_MODEM_INFO_MODEL_ID: + strncpy(info, &data->model_id[0], MIN(size, sizeof(data->model_id))); + break; + default: + ret = -ENODATA; + break; + } + + return ret; +} + +const static struct cellular_driver_api modem_cellular_api = { + .get_signal = modem_cellular_get_signal, + .get_modem_info = modem_cellular_get_modem_info, +}; + #ifdef CONFIG_PM_DEVICE static int modem_cellular_pm_action(const struct device *dev, enum pm_device_action action) { @@ -1279,14 +1514,13 @@ static int modem_cellular_init(const struct device *dev) .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), + .delimiter_size = strlen(data->chat_delimiter), .filter = data->chat_filter, - .filter_size = ARRAY_SIZE(data->chat_filter), + .filter_size = strlen(data->chat_filter), .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), }; modem_chat_init(&data->chat, &chat_config); @@ -1330,6 +1564,12 @@ 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("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_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(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds, @@ -1357,21 +1597,27 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_periodic_chat_script, #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_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("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_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); @@ -1390,7 +1636,8 @@ MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_dial_chat_script, quectel_eg25_g_dial_ch 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_CMD_RESP("AT+CGREG?", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CSQ", csq_match)); MODEM_CHAT_SCRIPT_DEFINE(quectel_eg25_g_periodic_chat_script, quectel_eg25_g_periodic_chat_script_cmds, abort_matches, @@ -1538,6 +1785,57 @@ MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_periodic_chat_script, modem_cellular_chat_callback_handler, 4); #endif +#if DT_HAS_COMPAT_STATUS_OKAY(u_blox_sara_r5) +MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_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), + 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+CGMI", cgmi_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match), + 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_r5_init_chat_script, u_blox_sara_r5_init_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_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(u_blox_sara_r5_dial_chat_script, u_blox_sara_r5_dial_chat_script_cmds, + dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r5_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_r5_periodic_chat_script, + u_blox_sara_r5_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); +#endif + #if DT_HAS_COMPAT_STATUS_OKAY(swir_hl7800) MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds, MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT", 100), @@ -1635,6 +1933,41 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, modem_cellular_chat_callback_handler, 4); #endif +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf91_slm) +MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_init_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP_MULT("AT", allow_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", 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+CGMI", cgmi_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match), + MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=1", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_init_chat_script, nordic_nrf91_slm_init_chat_script_cmds, + abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_dial_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=4", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match), + MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUX=2", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_dial_chat_script, nordic_nrf91_slm_dial_chat_script_cmds, + dial_abort_matches, modem_cellular_chat_callback_handler, 10); + +MODEM_CHAT_SCRIPT_CMDS_DEFINE(nordic_nrf91_slm_periodic_chat_script_cmds, + MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match)); + +MODEM_CHAT_SCRIPT_DEFINE(nordic_nrf91_slm_periodic_chat_script, + nordic_nrf91_slm_periodic_chat_script_cmds, abort_matches, + modem_cellular_chat_callback_handler, 4); +#endif + #define MODEM_CELLULAR_INST_NAME(name, inst) \ _CONCAT(_CONCAT(_CONCAT(name, _), DT_DRV_COMPAT), inst) @@ -1642,8 +1975,8 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, 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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1657,21 +1990,22 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, .shutdown_time_ms = 5000, \ .init_chat_script = &quectel_bg95_init_chat_script, \ .dial_chat_script = &quectel_bg95_dial_chat_script, \ - .periodic_chat_script = &quectel_bg95_periodic_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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1692,14 +2026,15 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1720,14 +2055,15 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1748,14 +2084,15 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1776,14 +2113,45 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); + +#define MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5(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, {}), \ + .autostarts = true, \ + .power_pulse_duration_ms = 1500, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 1500, \ + .shutdown_time_ms = 13000, \ + .init_chat_script = &u_blox_sara_r5_init_chat_script, \ + .dial_chat_script = &u_blox_sara_r5_dial_chat_script, \ + .periodic_chat_script = &u_blox_sara_r5_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, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1804,14 +2172,15 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); #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'}, \ + .chat_delimiter = "\r", \ + .chat_filter = "\n", \ .ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \ }; \ \ @@ -1832,7 +2201,36 @@ MODEM_CHAT_SCRIPT_DEFINE(telit_me910g1_periodic_chat_script, \ 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); + &MODEM_CELLULAR_INST_NAME(config, inst), POST_KERNEL, 99, \ + &modem_cellular_api); + +#define MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM(inst) \ + MODEM_PPP_DEFINE(MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 1500); \ + \ + static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \ + .chat_delimiter = "\r\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 = 100, \ + .reset_pulse_duration_ms = 100, \ + .startup_time_ms = 2000, \ + .shutdown_time_ms = 10000, \ + .init_chat_script = &nordic_nrf91_slm_init_chat_script, \ + .dial_chat_script = &nordic_nrf91_slm_dial_chat_script, \ + .periodic_chat_script = &nordic_nrf91_slm_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, \ + &modem_cellular_api); #define DT_DRV_COMPAT quectel_bg95 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_QUECTEL_BG95) @@ -1854,6 +2252,10 @@ DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SIMCOM_SIM7080) DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R4) #undef DT_DRV_COMPAT +#define DT_DRV_COMPAT u_blox_sara_r5 +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_U_BLOX_SARA_R5) +#undef DT_DRV_COMPAT + #define DT_DRV_COMPAT swir_hl7800 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800) #undef DT_DRV_COMPAT @@ -1861,3 +2263,7 @@ DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_SWIR_HL7800) #define DT_DRV_COMPAT telit_me910g1 DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_TELIT_ME910G1) #undef DT_DRV_COMPAT + +#define DT_DRV_COMPAT nordic_nrf91_slm +DT_INST_FOREACH_STATUS_OKAY(MODEM_CELLULAR_DEVICE_NORDIC_NRF91_SLM) +#undef DT_DRV_COMPAT diff --git a/drivers/pinctrl/pinctrl_nrf.c b/drivers/pinctrl/pinctrl_nrf.c index c2ac538c93b..12ee1d52294 100644 --- a/drivers/pinctrl/pinctrl_nrf.c +++ b/drivers/pinctrl/pinctrl_nrf.c @@ -13,19 +13,24 @@ BUILD_ASSERT(((NRF_PULL_NONE == NRF_GPIO_PIN_NOPULL) && (NRF_PULL_UP == NRF_GPIO_PIN_PULLUP)), "nRF pinctrl pull settings do not match HAL values"); -BUILD_ASSERT(((NRF_DRIVE_S0S1 == NRF_GPIO_PIN_S0S1) && - (NRF_DRIVE_H0S1 == NRF_GPIO_PIN_H0S1) && - (NRF_DRIVE_S0H1 == NRF_GPIO_PIN_S0H1) && - (NRF_DRIVE_H0H1 == NRF_GPIO_PIN_H0H1) && - (NRF_DRIVE_D0S1 == NRF_GPIO_PIN_D0S1) && - (NRF_DRIVE_D0H1 == NRF_GPIO_PIN_D0H1) && - (NRF_DRIVE_S0D1 == NRF_GPIO_PIN_S0D1) && - (NRF_DRIVE_H0D1 == NRF_GPIO_PIN_H0D1) && -#if defined(GPIO_PIN_CNF_DRIVE_E0E1) - (NRF_DRIVE_E0E1 == NRF_GPIO_PIN_E0E1) && -#endif /* defined(GPIO_PIN_CNF_DRIVE_E0E1) */ - (1U)), - "nRF pinctrl drive settings do not match HAL values"); +#if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0) +#define NRF_DRIVE_COUNT (NRF_DRIVE_E0E1 + 1) +#else +#define NRF_DRIVE_COUNT (NRF_DRIVE_H0D1 + 1) +#endif +static const nrf_gpio_pin_drive_t drive_modes[NRF_DRIVE_COUNT] = { + [NRF_DRIVE_S0S1] = NRF_GPIO_PIN_S0S1, + [NRF_DRIVE_H0S1] = NRF_GPIO_PIN_H0S1, + [NRF_DRIVE_S0H1] = NRF_GPIO_PIN_S0H1, + [NRF_DRIVE_H0H1] = NRF_GPIO_PIN_H0H1, + [NRF_DRIVE_D0S1] = NRF_GPIO_PIN_D0S1, + [NRF_DRIVE_D0H1] = NRF_GPIO_PIN_D0H1, + [NRF_DRIVE_S0D1] = NRF_GPIO_PIN_S0D1, + [NRF_DRIVE_H0D1] = NRF_GPIO_PIN_H0D1, +#if defined(GPIO_PIN_CNF_DRIVE_E0E1) || defined(GPIO_PIN_CNF_DRIVE0_E0) + [NRF_DRIVE_E0E1] = NRF_GPIO_PIN_E0E1, +#endif +}; /* value to indicate pin level doesn't need initialization */ #define NO_WRITE UINT32_MAX @@ -86,12 +91,19 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) { for (uint8_t i = 0U; i < pin_cnt; i++) { - nrf_gpio_pin_drive_t drive = NRF_GET_DRIVE(pins[i]); + nrf_gpio_pin_drive_t drive; + uint8_t drive_idx = NRF_GET_DRIVE(pins[i]); uint32_t psel = NRF_GET_PIN(pins[i]); uint32_t write = NO_WRITE; nrf_gpio_pin_dir_t dir; nrf_gpio_pin_input_t input; + if (drive_idx < ARRAY_SIZE(drive_modes)) { + drive = drive_modes[drive_idx]; + } else { + return -EINVAL; + } + if (psel == NRF_PIN_DISCONNECTED) { psel = PSEL_DISCONNECTED; } @@ -165,22 +177,22 @@ int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, #if defined(NRF_PSEL_TWIM) case NRF_FUN_TWIM_SCL: NRF_PSEL_TWIM(reg, SCL) = psel; - if (drive == NRF_DRIVE_S0S1) { + if (drive == NRF_GPIO_PIN_S0S1) { /* Override the default drive setting with one * suitable for TWI/TWIM peripherals (S0D1). * This drive cannot be used always so that * users are able to select e.g. H0D1 or E0E1 * in devicetree. */ - drive = NRF_DRIVE_S0D1; + drive = NRF_GPIO_PIN_S0D1; } dir = NRF_GPIO_PIN_DIR_INPUT; input = NRF_GPIO_PIN_INPUT_CONNECT; break; case NRF_FUN_TWIM_SDA: NRF_PSEL_TWIM(reg, SDA) = psel; - if (drive == NRF_DRIVE_S0S1) { - drive = NRF_DRIVE_S0D1; + if (drive == NRF_GPIO_PIN_S0S1) { + drive = NRF_GPIO_PIN_S0D1; } dir = NRF_GPIO_PIN_DIR_INPUT; input = NRF_GPIO_PIN_INPUT_CONNECT; diff --git a/drivers/pwm/pwm_nrf_sw.c b/drivers/pwm/pwm_nrf_sw.c index f367bb59899..2b9a22a38f0 100644 --- a/drivers/pwm/pwm_nrf_sw.c +++ b/drivers/pwm/pwm_nrf_sw.c @@ -62,6 +62,7 @@ struct pwm_config { NRF_RTC_Type *rtc; NRF_TIMER_Type *timer; }; + nrfx_gpiote_t gpiote[PWM_0_MAP_SIZE]; uint8_t psel_ch[PWM_0_MAP_SIZE]; uint8_t initially_inverted; uint8_t map_size; @@ -123,6 +124,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, const struct pwm_config *config = dev->config; NRF_TIMER_Type *timer = pwm_config_timer(config); NRF_RTC_Type *rtc = pwm_config_rtc(config); + NRF_GPIOTE_Type *gpiote; struct pwm_data *data = dev->data; uint32_t ppi_mask; uint8_t active_level; @@ -161,6 +163,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, } } + gpiote = config->gpiote[channel].p_reg; psel_ch = config->psel_ch[channel]; gpiote_ch = data->gpiote_ch[channel]; ppi_chs = data->ppi_ch[channel]; @@ -186,7 +189,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, : active_level); /* clear GPIOTE config */ - nrf_gpiote_te_default(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_te_default(gpiote, gpiote_ch); /* No PWM generation for this channel. */ data->pulse_cycles[channel] = 0U; @@ -235,7 +238,7 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, } /* Configure GPIOTE - toggle task with proper initial output value. */ - NRF_GPIOTE->CONFIG[gpiote_ch] = + gpiote->CONFIG[gpiote_ch] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) | ((uint32_t)psel_ch << 8) | (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) | @@ -256,9 +259,9 @@ static int pwm_nrf_sw_set_cycles(const struct device *dev, uint32_t channel, pulse_end_task = period_end_task = nrf_gpiote_out_task_get(gpiote_ch); #endif uint32_t pulse_end_task_address = - nrf_gpiote_task_address_get(NRF_GPIOTE, pulse_end_task); + nrf_gpiote_task_address_get(gpiote, pulse_end_task); uint32_t period_end_task_address = - nrf_gpiote_task_address_get(NRF_GPIOTE, period_end_task); + nrf_gpiote_task_address_get(gpiote, period_end_task); if (USE_RTC) { uint32_t clear_task_address = @@ -359,7 +362,8 @@ static int pwm_nrf_sw_init(const struct device *dev) } } - err = nrfx_gpiote_channel_alloc(&data->gpiote_ch[i]); + err = nrfx_gpiote_channel_alloc(&config->gpiote[i], + &data->gpiote_ch[i]); if (err != NRFX_SUCCESS) { /* Do not free allocated resource. It is a fatal condition, * system requires reconfiguration. @@ -402,8 +406,14 @@ static int pwm_nrf_sw_init(const struct device *dev) ((DT_GPIO_FLAGS_BY_IDX(_node_id, _prop, _idx) & GPIO_ACTIVE_LOW) \ ? BIT(_idx) : 0) | +#define GPIOTE_AND_COMMA(_node_id, _prop, _idx) \ + NRFX_GPIOTE_INSTANCE(NRF_DT_GPIOTE_INST_BY_IDX(_node_id, _prop, _idx)), + static const struct pwm_config pwm_nrf_sw_0_config = { COND_CODE_1(USE_RTC, (.rtc), (.timer)) = GENERATOR_ADDR, + .gpiote = { + DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, GPIOTE_AND_COMMA) + }, .psel_ch = { DT_INST_FOREACH_PROP_ELEM(0, channel_gpios, PSEL_AND_COMMA) }, diff --git a/drivers/regulator/regulator_common.c b/drivers/regulator/regulator_common.c index 7f33040d2d9..14866a3738f 100644 --- a/drivers/regulator/regulator_common.c +++ b/drivers/regulator/regulator_common.c @@ -107,10 +107,13 @@ int regulator_enable(const struct device *dev) (void)k_mutex_lock(&data->lock, K_FOREVER); #endif - if (data->refcnt == 0) { + data->refcnt++; + + if (data->refcnt == 1) { ret = api->enable(dev); - if (ret == 0) { - data->refcnt++; + if (ret < 0) { + data->refcnt--; + } else { regulator_delay(config->off_on_delay_us); } } diff --git a/drivers/sensor/adxl367/adxl367.c b/drivers/sensor/adxl367/adxl367.c index f63b8f73a32..1d5c31ad021 100644 --- a/drivers/sensor/adxl367/adxl367.c +++ b/drivers/sensor/adxl367/adxl367.c @@ -287,16 +287,22 @@ int adxl367_self_test(const struct device *dev) switch (cfg->odr) { case ADXL367_ODR_12P5HZ: st_delay_ms = 320; + break; case ADXL367_ODR_25HZ: st_delay_ms = 160; + break; case ADXL367_ODR_50HZ: st_delay_ms = 80; + break; case ADXL367_ODR_100HZ: st_delay_ms = 40; + break; case ADXL367_ODR_200HZ: st_delay_ms = 20; + break; case ADXL367_ODR_400HZ: st_delay_ms = 10; + break; default: return -EINVAL; } diff --git a/drivers/sensor/adxl367/adxl367_trigger.c b/drivers/sensor/adxl367/adxl367_trigger.c index 4e86d466343..534bd07324e 100644 --- a/drivers/sensor/adxl367/adxl367_trigger.c +++ b/drivers/sensor/adxl367/adxl367_trigger.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +#define DT_DRV_COMPAT adi_adxl367 + #include #include #include diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index bfc38603864..67e02e0c261 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -26,7 +26,13 @@ zephyr_library_sources_ifdef(CONFIG_UART_MIV uart_miv.c) zephyr_library_sources_ifdef(CONFIG_UART_MSP432P4XX uart_msp432p4xx.c) zephyr_library_sources_ifdef(CONFIG_UART_NS16550 uart_ns16550.c) zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UART uart_nrfx_uart.c) -zephyr_library_sources_ifdef(CONFIG_UART_NRFX_UARTE uart_nrfx_uarte.c) +if (CONFIG_UART_NRFX_UARTE) + if (CONFIG_UART_NRFX_UARTE_LEGACY_SHIM) + zephyr_library_sources(uart_nrfx_uarte.c) + else() + zephyr_library_sources(uart_nrfx_uarte2.c) + endif() +endif() zephyr_library_sources_ifdef(CONFIG_UART_NUMICRO uart_numicro.c) zephyr_library_sources_ifdef(CONFIG_UART_SAM uart_sam.c) zephyr_library_sources_ifdef(CONFIG_USART_SAM usart_sam.c) @@ -93,3 +99,4 @@ endif() zephyr_library_sources_ifdef(CONFIG_SERIAL_TEST serial_test.c) zephyr_library_sources_ifdef(CONFIG_UART_ASYNC_RX_HELPER uart_async_rx.c) +zephyr_library_sources_ifdef(CONFIG_UART_ASYNC_TO_INT_DRIVEN_API uart_async_to_irq.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 5eb183c9a3e..2d097932cf4 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -133,6 +133,21 @@ config UART_ASYNC_RX_HELPER is delayed. Module implements zero-copy approach with multiple reception buffers. +config UART_ASYNC_TO_INT_DRIVEN_API + bool + select UART_ASYNC_RX_HELPER + help + Asynchronous to Interrupt driven adaptation layer. When enabled device + which implements only asynchronous API can be used with interrupt driven + API implemented by the generic adaptation layer. + +config UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT + int "Receiver timeout (in bauds)" + depends on UART_ASYNC_TO_INT_DRIVEN_API + default 100 + help + Receiver inactivity timeout. It is used to calculate timeout in microseconds. + comment "Serial Drivers" source "drivers/serial/Kconfig.b91" diff --git a/drivers/serial/Kconfig.nrfx b/drivers/serial/Kconfig.nrfx index 53553e3d06e..158731404e6 100644 --- a/drivers/serial/Kconfig.nrfx +++ b/drivers/serial/Kconfig.nrfx @@ -25,11 +25,20 @@ config UART_NRFX_UART config UART_NRFX_UARTE def_bool y depends on DT_HAS_NORDIC_NRF_UARTE_ENABLED + imply NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM + imply NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG if !UART_NRFX_UARTE_LEGACY_SHIM + +config UART_NRFX_UARTE_LEGACY_SHIM + bool "Legacy UARTE shim" + depends on UART_NRFX_UARTE + depends on !SOC_SERIES_NRF54LX && !SOC_SERIES_NRF54HX + # New shim takes more ROM. Until it is fixed use legacy shim. + default y config UART_ASYNC_TX_CACHE_SIZE int "TX cache buffer size" depends on UART_ASYNC_API - depends on UART_NRFX_UARTE + depends on UART_NRFX_UARTE_LEGACY_SHIM default 8 help For UARTE, TX cache buffer is used when provided TX buffer is not located @@ -56,6 +65,76 @@ nrfx_uart_num = 3 rsource "Kconfig.nrfx_uart_instance" endif +if HAS_HW_NRF_UARTE00 +nrfx_uart_num = 00 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE20 +nrfx_uart_num = 20 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE21 +nrfx_uart_num = 21 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE22 +nrfx_uart_num = 22 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE30 +nrfx_uart_num = 30 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE120 +nrfx_uart_num = 120 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE130 +nrfx_uart_num = 130 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE131 +nrfx_uart_num = 131 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE132 +nrfx_uart_num = 132 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE133 +nrfx_uart_num = 133 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE134 +nrfx_uart_num = 134 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE135 +nrfx_uart_num = 135 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE136 +nrfx_uart_num = 136 +rsource "Kconfig.nrfx_uart_instance" +endif + +if HAS_HW_NRF_UARTE137 +nrfx_uart_num = 137 +rsource "Kconfig.nrfx_uart_instance" +endif + config NRFX_TIMER0 default y depends on UART_0_NRF_HW_ASYNC_TIMER = 0 \ diff --git a/drivers/serial/Kconfig.nrfx_uart_instance b/drivers/serial/Kconfig.nrfx_uart_instance index 39e774e2544..9e992ca9737 100644 --- a/drivers/serial/Kconfig.nrfx_uart_instance +++ b/drivers/serial/Kconfig.nrfx_uart_instance @@ -6,6 +6,7 @@ config UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN bool "Interrupt support on port $(nrfx_uart_num)" depends on UART_INTERRUPT_DRIVEN + select UART_ASYNC_TO_INT_DRIVEN_API if !UART_NRFX_UARTE_LEGACY_SHIM default y help This option enables UART interrupt support on port $(nrfx_uart_num). @@ -19,14 +20,19 @@ config UART_$(nrfx_uart_num)_ASYNC config UART_$(nrfx_uart_num)_ENHANCED_POLL_OUT bool "Efficient poll out on port $(nrfx_uart_num)" + depends on !SOC_SERIES_NRF54LX default y depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC 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 NRFX_UARTE$(nrfx_uart_num) + def_bool y if HAS_HW_NRF_UARTE$(nrfx_uart_num) && !UART_NRFX_UARTE_LEGACY_SHIM + config UART_$(nrfx_uart_num)_NRF_PARITY_BIT bool "Parity bit" help @@ -34,7 +40,8 @@ config UART_$(nrfx_uart_num)_NRF_PARITY_BIT config UART_$(nrfx_uart_num)_NRF_TX_BUFFER_SIZE int "Size of RAM buffer" - depends on UART_INTERRUPT_DRIVEN + depends on HAS_HW_NRF_UARTE$(nrfx_uart_num) + depends on UART_NRFX_UARTE_LEGACY_SHIM range 1 65535 default 32 help @@ -46,6 +53,7 @@ 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 + depends on UART_NRFX_UARTE_LEGACY_SHIM select NRFX_PPI if HAS_HW_NRF_PPI select NRFX_DPPI if HAS_HW_NRF_DPPIC help @@ -58,6 +66,7 @@ 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 + depends on UART_NRFX_UARTE_LEGACY_SHIM 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 @@ -67,6 +76,42 @@ 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)_TX_CACHE_SIZE + int "TX cache buffer size" + depends on !UART_NRFX_UARTE_LEGACY_SHIM + default 8 + help + For UARTE, TX cache buffer is used when provided TX buffer is not located + in memory which can be used by the EasyDMA. + +config UART_$(nrfx_uart_num)_RX_CACHE_SIZE + int "RX cache buffer size" + depends on !UART_NRFX_UARTE_LEGACY_SHIM + default 32 if $(dt_nodelabel_has_compat,ram3x,$(DT_COMPAT_MMIO_SRAM)) + default 5 + range 5 255 + help + For UARTE, RX cache buffer is used when provided RX buffer is not located + in memory which can be used by the EasyDMA. It is also used to store + flushed data. + +config UART_$(nrfx_uart_num)_A2I_RX_SIZE + depends on !UART_NRFX_UARTE_LEGACY_SHIM + int "Asynchronous to interrupt driven adaptation layer RX buffer size" + default 64 if UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + default 0 + help + Amount of space dedicated for RX. It is divided into chunks with some + amount of that space used for control data. + +config UART_$(nrfx_uart_num)_A2I_RX_BUF_COUNT + depends on !UART_NRFX_UARTE_LEGACY_SHIM + int "Asynchronous to interrupt driven adaptation layer RX buffer count" + default 8 if UART_$(nrfx_uart_num)_INTERRUPT_DRIVEN + default 0 + help + Number of chunks into RX space is divided. + config UART_$(nrfx_uart_num)_GPIO_MANAGEMENT bool "GPIO management on port $(nrfx_uart_num)" depends on PM_DEVICE diff --git a/drivers/serial/uart_async_to_irq.c b/drivers/serial/uart_async_to_irq.c new file mode 100644 index 00000000000..e18536449f3 --- /dev/null +++ b/drivers/serial/uart_async_to_irq.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +LOG_MODULE_REGISTER(UART_ASYNC_TO_IRQ_LOG_NAME, CONFIG_UART_LOG_LEVEL); + +/* Internal state flags. */ + +/* RX interrupt enabled. */ +#define A2I_RX_IRQ_ENABLED BIT(0) + +/* TX interrupt enabled. */ +#define A2I_TX_IRQ_ENABLED BIT(1) + +/* Error interrupt enabled. */ +#define A2I_ERR_IRQ_ENABLED BIT(2) + +/* Receiver to be kept enabled. */ +#define A2I_RX_ENABLE BIT(3) + +/* TX busy. */ +#define A2I_TX_BUSY BIT(4) + +static struct uart_async_to_irq_data *get_data(const struct device *dev) +{ + struct uart_async_to_irq_data **data = dev->data; + + return *data; +} + +static const struct uart_async_to_irq_config *get_config(const struct device *dev) +{ + const struct uart_async_to_irq_config * const *config = dev->config; + + return *config; +} + +/* Function calculates RX timeout based on baudrate. */ +static uint32_t get_rx_timeout(const struct device *dev) +{ + struct uart_config cfg; + int err; + uint32_t baudrate; + + err = uart_config_get(dev, &cfg); + if (err == 0) { + baudrate = cfg.baudrate; + } else { + baudrate = get_config(dev)->baudrate; + } + + uint32_t us = (CONFIG_UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT * 1000000) / baudrate; + + return us; +} + +static int rx_enable(const struct device *dev, + struct uart_async_to_irq_data *data, + uint8_t *buf, + size_t len) +{ + int err; + const struct uart_async_to_irq_config *config = get_config(dev); + + err = config->api->rx_enable(dev, buf, len, get_rx_timeout(dev)); + + return err; +} + +static int try_rx_enable(const struct device *dev, struct uart_async_to_irq_data *data) +{ + uint8_t *buf = uart_async_rx_buf_req(&data->rx.async_rx); + size_t len = uart_async_rx_get_buf_len(&data->rx.async_rx); + + if (buf == NULL) { + return -EBUSY; + } + + return rx_enable(dev, data, buf, len); +} + +static void on_rx_buf_req(const struct device *dev, + const struct uart_async_to_irq_config *config, + struct uart_async_to_irq_data *data) +{ + struct uart_async_rx *async_rx = &data->rx.async_rx; + uint8_t *buf = uart_async_rx_buf_req(async_rx); + size_t len = uart_async_rx_get_buf_len(async_rx); + + if (buf) { + int err = config->api->rx_buf_rsp(dev, buf, len); + + if (err < 0) { + uart_async_rx_on_buf_rel(async_rx, buf); + } + } else { + atomic_inc(&data->rx.pending_buf_req); + } +} + +static void on_rx_dis(const struct device *dev, struct uart_async_to_irq_data *data) +{ + if (data->flags & A2I_RX_ENABLE) { + int err; + + err = try_rx_enable(dev, data); + if (err == 0) { + data->rx.pending_buf_req = 0; + } + + LOG_INST_DBG(get_config(dev)->log, "Reenabling RX from RX_DISABLED (err:%d)", err); + __ASSERT((err >= 0) || (err == -EBUSY), "err: %d", err); + return; + } + + k_sem_give(&data->rx.sem); +} + +static void uart_async_to_irq_callback(const struct device *dev, + struct uart_event *evt, + void *user_data) +{ + struct uart_async_to_irq_data *data = (struct uart_async_to_irq_data *)user_data; + const struct uart_async_to_irq_config *config = get_config(dev); + bool call_handler = false; + + switch (evt->type) { + case UART_TX_DONE: + atomic_and(&data->flags, ~A2I_TX_BUSY); + call_handler = data->flags & A2I_TX_IRQ_ENABLED; + break; + case UART_RX_RDY: + uart_async_rx_on_rdy(&data->rx.async_rx, evt->data.rx.buf, evt->data.rx.len); + call_handler = data->flags & A2I_RX_IRQ_ENABLED; + break; + case UART_RX_BUF_REQUEST: + on_rx_buf_req(dev, config, data); + break; + case UART_RX_BUF_RELEASED: + uart_async_rx_on_buf_rel(&data->rx.async_rx, evt->data.rx_buf.buf); + break; + case UART_RX_STOPPED: + call_handler = data->flags & A2I_ERR_IRQ_ENABLED; + break; + case UART_RX_DISABLED: + on_rx_dis(dev, data); + break; + default: + break; + } + + if (data->callback && call_handler) { + atomic_inc(&data->irq_req); + config->trampoline(dev); + } +} + +int z_uart_async_to_irq_fifo_fill(const struct device *dev, const uint8_t *buf, int len) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + len = MIN(len, data->tx.len); + if (atomic_or(&data->flags, A2I_TX_BUSY) & A2I_TX_BUSY) { + return 0; + } + + memcpy(data->tx.buf, buf, len); + + err = config->api->tx(dev, data->tx.buf, len, SYS_FOREVER_US); + if (err < 0) { + atomic_and(&data->flags, ~A2I_TX_BUSY); + return 0; + } + + return len; +} + +/** Interrupt driven FIFO read function */ +int z_uart_async_to_irq_fifo_read(const struct device *dev, + uint8_t *buf, + const int len) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + struct uart_async_rx *async_rx = &data->rx.async_rx; + size_t claim_len; + uint8_t *claim_buf; + + claim_len = uart_async_rx_data_claim(async_rx, &claim_buf, len); + if (claim_len == 0) { + return 0; + } + + memcpy(buf, claim_buf, claim_len); + uart_async_rx_data_consume(async_rx, claim_len); + + if (data->rx.pending_buf_req) { + buf = uart_async_rx_buf_req(async_rx); + if (buf) { + int err; + size_t rx_len = uart_async_rx_get_buf_len(async_rx); + + atomic_dec(&data->rx.pending_buf_req); + err = config->api->rx_buf_rsp(dev, buf, rx_len); + if (err < 0) { + if (err == -EACCES) { + data->rx.pending_buf_req = 0; + err = rx_enable(dev, data, buf, rx_len); + } + if (err < 0) { + return err; + } + } + } + } + + return (int)claim_len; +} + +static void dir_disable(const struct device *dev, uint32_t flag) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + atomic_and(&data->flags, ~flag); +} + +static void dir_enable(const struct device *dev, uint32_t flag) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + atomic_or(&data->flags, flag); + + atomic_inc(&data->irq_req); + get_config(dev)->trampoline(dev); +} + +/** Interrupt driven transfer enabling function */ +void z_uart_async_to_irq_irq_tx_enable(const struct device *dev) +{ + dir_enable(dev, A2I_TX_IRQ_ENABLED); +} + +/** Interrupt driven transfer disabling function */ +void z_uart_async_to_irq_irq_tx_disable(const struct device *dev) +{ + dir_disable(dev, A2I_TX_IRQ_ENABLED); +} + +/** Interrupt driven transfer ready function */ +int z_uart_async_to_irq_irq_tx_ready(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + return (data->flags & A2I_TX_IRQ_ENABLED) && !(data->flags & A2I_TX_BUSY); +} + +/** Interrupt driven receiver enabling function */ +void z_uart_async_to_irq_irq_rx_enable(const struct device *dev) +{ + dir_enable(dev, A2I_RX_IRQ_ENABLED); +} + +/** Interrupt driven receiver disabling function */ +void z_uart_async_to_irq_irq_rx_disable(const struct device *dev) +{ + dir_disable(dev, A2I_RX_IRQ_ENABLED); +} + +/** Interrupt driven transfer complete function */ +int z_uart_async_to_irq_irq_tx_complete(const struct device *dev) +{ + return z_uart_async_to_irq_irq_tx_ready(dev); +} + +/** Interrupt driven receiver ready function */ +int z_uart_async_to_irq_irq_rx_ready(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + return (data->flags & A2I_RX_IRQ_ENABLED) && (data->rx.async_rx.pending_bytes > 0); +} + +/** Interrupt driven error enabling function */ +void z_uart_async_to_irq_irq_err_enable(const struct device *dev) +{ + dir_enable(dev, A2I_ERR_IRQ_ENABLED); +} + +/** Interrupt driven error disabling function */ +void z_uart_async_to_irq_irq_err_disable(const struct device *dev) +{ + dir_disable(dev, A2I_ERR_IRQ_ENABLED); +} + +/** Interrupt driven pending status function */ +int z_uart_async_to_irq_irq_is_pending(const struct device *dev) +{ + return z_uart_async_to_irq_irq_tx_ready(dev) || z_uart_async_to_irq_irq_rx_ready(dev); +} + +/** Interrupt driven interrupt update function */ +int z_uart_async_to_irq_irq_update(const struct device *dev) +{ + return 1; +} + +/** Set the irq callback function */ +void z_uart_async_to_irq_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + data->callback = cb; + data->user_data = user_data; +} + +int uart_async_to_irq_rx_enable(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + err = config->api->callback_set(dev, uart_async_to_irq_callback, data); + if (err < 0) { + return err; + } + + uart_async_rx_reset(&data->rx.async_rx); + + err = try_rx_enable(dev, data); + if (err == 0) { + atomic_or(&data->flags, A2I_RX_ENABLE); + } + + return err; +} + +int uart_async_to_irq_rx_disable(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + const struct uart_async_to_irq_config *config = get_config(dev); + int err; + + if (atomic_and(&data->flags, ~A2I_RX_ENABLE) & A2I_RX_ENABLE) { + err = config->api->rx_disable(dev); + if (err < 0) { + return err; + } + k_sem_take(&data->rx.sem, K_FOREVER); + } + + return 0; +} + +void uart_async_to_irq_trampoline_cb(const struct device *dev) +{ + struct uart_async_to_irq_data *data = get_data(dev); + + do { + data->callback(dev, data->user_data); + } while (atomic_dec(&data->irq_req) > 1); +} + +int uart_async_to_irq_init(struct uart_async_to_irq_data *data, + const struct uart_async_to_irq_config *config) +{ + data->tx.buf = config->tx_buf; + data->tx.len = config->tx_len; + + k_sem_init(&data->rx.sem, 0, 1); + + return uart_async_rx_init(&data->rx.async_rx, &config->async_rx); +} diff --git a/drivers/serial/uart_b91.c b/drivers/serial/uart_b91.c index cb2d7ebd190..e2502f4fd9b 100644 --- a/drivers/serial/uart_b91.c +++ b/drivers/serial/uart_b91.c @@ -11,6 +11,7 @@ #include #include #include +#include /* Driver dts compatibility: telink,b91_uart */ diff --git a/drivers/serial/uart_nrfx_uarte.c b/drivers/serial/uart_nrfx_uarte.c index 3a62057a47a..6e1ecfadfd8 100644 --- a/drivers/serial/uart_nrfx_uarte.c +++ b/drivers/serial/uart_nrfx_uarte.c @@ -1043,9 +1043,11 @@ static void rx_timeout(struct k_timer *timer) (data->async->rx_timeout_left < data->async->rx_timeout_slab)) { /* rx_timeout us elapsed since last receiving */ - notify_uart_rx_rdy(dev, len); - data->async->rx_offset += len; - data->async->rx_total_user_byte_cnt += len; + if (data->async->rx_buf != NULL) { + notify_uart_rx_rdy(dev, len); + data->async->rx_offset += len; + data->async->rx_total_user_byte_cnt += len; + } } else { data->async->rx_timeout_left -= data->async->rx_timeout_slab; diff --git a/drivers/serial/uart_nrfx_uarte2.c b/drivers/serial/uart_nrfx_uarte2.c new file mode 100644 index 00000000000..bfc770f1399 --- /dev/null +++ b/drivers/serial/uart_nrfx_uarte2.c @@ -0,0 +1,1029 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @brief Driver for Nordic Semiconductor nRF UARTE + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define LOG_MODULE_NAME uarte +LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_UART_LOG_LEVEL); + +#define INSTANCE_INT_DRIVEN(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_INTERRUPT_DRIVEN) + +#define INSTANCE_ASYNC(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ASYNC) + +#define INSTANCE_POLLING(periph, prefix, id, _) \ + UTIL_AND(CONFIG_HAS_HW_NRF_UARTE##prefix##id, \ + UTIL_AND(COND_CODE_1(CONFIG_UART_##prefix##id##_INTERRUPT_DRIVEN, (0), (1)), \ + COND_CODE_1(CONFIG_UART_##prefix##id##_ASYNC, (0), (1)))) + +#define INSTANCE_ENHANCED_POLL_OUT(periph, prefix, i, _) \ + IS_ENABLED(CONFIG_UART_##prefix##i##_ENHANCED_POLL_OUT) + +/* Macro determining if any instance is using interrupt driven API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_INT_DRIVEN, (+), (0), _)) +#define UARTE_ANY_INTERRUPT_DRIVEN 1 +#else +#define UARTE_ANY_INTERRUPT_DRIVEN 0 +#endif + +/* Macro determining if any instance is enabled and using ASYNC API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_ASYNC, (+), (0), _)) +#define UARTE_ANY_ASYNC 1 +#else +#define UARTE_ANY_ASYNC 0 +#endif + +/* Macro determining if any instance is using only polling API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_POLLING, (+), (0), _)) +#define UARTE_ANY_POLLING 1 +#else +#define UARTE_ANY_POLLING 0 +#endif + +/* Macro determining if any instance is using interrupt driven API. */ +#if (NRFX_FOREACH_ENABLED(UARTE, INSTANCE_ENHANCED_POLL_OUT, (+), (0), _)) +#define UARTE_ENHANCED_POLL_OUT 1 +#else +#define UARTE_ENHANCED_POLL_OUT 0 +#endif + +#if UARTE_ANY_INTERRUPT_DRIVEN || UARTE_ANY_ASYNC +#define UARTE_INT_ASYNC 1 +#else +#define UARTE_INT_ASYNC 0 +#endif + +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) +#define UARTE_ODD_PARITY_ALLOWED 1 +#else +#define UARTE_ODD_PARITY_ALLOWED 0 +#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. + */ +#define RX_TIMEOUT_DIV 5 + +/* Macro for converting numerical baudrate to register value. It is convenient + * to use this approach because for constant input it can calculate nrf setting + * at compile time. + */ +#define NRF_BAUDRATE(baudrate) ((baudrate) == 300 ? 0x00014000 :\ + (baudrate) == 600 ? 0x00027000 : \ + (baudrate) == 1200 ? NRF_UARTE_BAUDRATE_1200 : \ + (baudrate) == 2400 ? NRF_UARTE_BAUDRATE_2400 : \ + (baudrate) == 4800 ? NRF_UARTE_BAUDRATE_4800 : \ + (baudrate) == 9600 ? NRF_UARTE_BAUDRATE_9600 : \ + (baudrate) == 14400 ? NRF_UARTE_BAUDRATE_14400 : \ + (baudrate) == 19200 ? NRF_UARTE_BAUDRATE_19200 : \ + (baudrate) == 28800 ? NRF_UARTE_BAUDRATE_28800 : \ + (baudrate) == 31250 ? NRF_UARTE_BAUDRATE_31250 : \ + (baudrate) == 38400 ? NRF_UARTE_BAUDRATE_38400 : \ + (baudrate) == 56000 ? NRF_UARTE_BAUDRATE_56000 : \ + (baudrate) == 57600 ? NRF_UARTE_BAUDRATE_57600 : \ + (baudrate) == 76800 ? NRF_UARTE_BAUDRATE_76800 : \ + (baudrate) == 115200 ? NRF_UARTE_BAUDRATE_115200 : \ + (baudrate) == 230400 ? NRF_UARTE_BAUDRATE_230400 : \ + (baudrate) == 250000 ? NRF_UARTE_BAUDRATE_250000 : \ + (baudrate) == 460800 ? NRF_UARTE_BAUDRATE_460800 : \ + (baudrate) == 921600 ? NRF_UARTE_BAUDRATE_921600 : \ + (baudrate) == 1000000 ? NRF_UARTE_BAUDRATE_1000000 : 0) + +#define UARTE_DATA_FLAG_TRAMPOLINE BIT(0) +#define UARTE_DATA_FLAG_RX_ENABLED BIT(1) + +struct uarte_async_data { + uart_callback_t user_callback; + void *user_data; + + struct k_timer tx_timer; + struct k_timer rx_timer; + + k_timeout_t rx_timeout; + + /* Keeps the most recent error mask. */ + uint32_t err; + + uint8_t idle_cnt; +}; + +/* Device data structure */ +struct uarte_nrfx_data { + struct uart_async_to_irq_data *a2i_data; +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + struct uart_config uart_config; +#endif + struct uarte_async_data *async; + atomic_t flags; + uint8_t rx_byte; +}; +BUILD_ASSERT(offsetof(struct uarte_nrfx_data, a2i_data) == 0); + +/* If set then pins are managed when going to low power mode. */ +#define UARTE_CFG_FLAG_GPIO_MGMT BIT(0) + +/* If set then receiver is not used. */ +#define UARTE_CFG_FLAG_NO_RX BIT(1) + +/* If set then instance is using interrupt driven API. */ +#define UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API BIT(2) + +/** + * @brief Structure for UARTE configuration. + */ +struct uarte_nrfx_config { + const struct uart_async_to_irq_config *a2i_config; + nrfx_uarte_t nrfx_dev; + nrfx_uarte_config_t nrfx_config; + const struct pinctrl_dev_config *pcfg; + uint32_t flags; + + LOG_INSTANCE_PTR_DECLARE(log); +}; +BUILD_ASSERT(offsetof(struct uarte_nrfx_config, a2i_config) == 0); + +#define UARTE_ERROR_FROM_MASK(mask) \ + ((mask) & NRF_UARTE_ERROR_OVERRUN_MASK ? UART_ERROR_OVERRUN \ + : (mask) & NRF_UARTE_ERROR_PARITY_MASK ? UART_ERROR_PARITY \ + : (mask) & NRF_UARTE_ERROR_FRAMING_MASK ? UART_ERROR_FRAMING \ + : (mask) & NRF_UARTE_ERROR_BREAK_MASK ? UART_BREAK \ + : 0) + +/* Determine if the device has interrupt driven API enabled. */ +#define IS_INT_DRIVEN_API(dev) \ + (UARTE_ANY_INTERRUPT_DRIVEN && \ + (((const struct uarte_nrfx_config *)dev->config)->flags & \ + UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API)) + +/* Determine if the device supports only polling API. */ +#define IS_POLLING_API(dev) \ + (!UARTE_INT_ASYNC || (((struct uarte_nrfx_data *)dev->data)->async == NULL)) + +/* Determine if the device supports asynchronous API. */ +#define IS_ASYNC_API(dev) (!IS_INT_DRIVEN_API(dev) && !IS_POLLING_API(dev)) + +static inline const nrfx_uarte_t *get_nrfx_dev(const struct device *dev) +{ + const struct uarte_nrfx_config *config = dev->config; + + return &config->nrfx_dev; +} + +static int callback_set(const struct device *dev, uart_callback_t callback, void *user_data) +{ + struct uarte_nrfx_data *data = dev->data; + + data->async->user_callback = callback; + data->async->user_data = user_data; + + return 0; +} + +#if UARTE_ANY_ASYNC +static int api_callback_set(const struct device *dev, uart_callback_t callback, void *user_data) +{ + if (!IS_ASYNC_API(dev)) { + return -ENOTSUP; + } + + return callback_set(dev, callback, user_data); +} +#endif + +static void on_tx_done(const struct device *dev, const nrfx_uarte_event_t *event) +{ + struct uarte_nrfx_data *data = dev->data; + struct uart_event evt = { + .type = (event->data.tx.flags & NRFX_UARTE_TX_DONE_ABORTED) ? + UART_TX_ABORTED : UART_TX_DONE, + .data.tx.buf = event->data.tx.p_buffer, + .data.tx.len = event->data.tx.length + }; + bool hwfc; + +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + hwfc = data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS; +#else + const struct uarte_nrfx_config *config = dev->config; + + hwfc = config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED; +#endif + + if (hwfc) { + k_timer_stop(&data->async->tx_timer); + } + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void on_rx_done(const struct device *dev, const nrfx_uarte_event_t *event) +{ + struct uarte_nrfx_data *data = dev->data; + struct uart_event evt; + + if (event->data.rx.length) { + if (data->async->err) { + evt.type = UART_RX_STOPPED; + evt.data.rx_stop.reason = UARTE_ERROR_FROM_MASK(data->async->err); + evt.data.rx_stop.data.buf = event->data.rx.p_buffer; + evt.data.rx_stop.data.len = event->data.rx.length; + /* Keep error code for uart_err_check(). */ + if (!IS_INT_DRIVEN_API(dev)) { + data->async->err = 0; + } + } else { + evt.type = UART_RX_RDY, + evt.data.rx.buf = event->data.rx.p_buffer, + evt.data.rx.len = event->data.rx.length, + evt.data.rx.offset = 0; + } + data->async->user_callback(dev, &evt, data->async->user_data); + } + + evt.type = UART_RX_BUF_RELEASED; + evt.data.rx_buf.buf = event->data.rx.p_buffer; + + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void start_rx_timer(struct uarte_nrfx_data *data) +{ + struct uarte_async_data *adata = data->async; + + k_timer_start(&adata->rx_timer, adata->rx_timeout, K_NO_WAIT); +} + +static void on_rx_byte(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + nrfx_uarte_rxdrdy_disable(nrfx_dev); + adata->idle_cnt = RX_TIMEOUT_DIV; + start_rx_timer(data); +} + +static void on_rx_buf_req(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + struct uart_event evt = { + .type = UART_RX_BUF_REQUEST + }; + + /* If counter reached zero that indicates that timeout was reached and + * reception of one buffer was terminated to restart another transfer. + */ + if (!K_TIMEOUT_EQ(adata->rx_timeout, K_NO_WAIT)) { + /* Read and clear any pending new data information. */ + nrfx_uarte_rx_new_data_check(nrfx_dev); + nrfx_uarte_rxdrdy_enable(nrfx_dev); + } + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void on_rx_disabled(const struct device *dev, struct uarte_nrfx_data *data) +{ + struct uart_event evt = { + .type = UART_RX_DISABLED + }; + + atomic_and(&data->flags, ~UARTE_DATA_FLAG_RX_ENABLED); + k_timer_stop(&data->async->rx_timer); + + data->async->user_callback(dev, &evt, data->async->user_data); +} + +static void trigger_handler(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + + if (UARTE_ANY_INTERRUPT_DRIVEN && + atomic_and(&data->flags, ~UARTE_DATA_FLAG_TRAMPOLINE) & + UARTE_DATA_FLAG_TRAMPOLINE) { + uart_async_to_irq_trampoline_cb(dev); + } +} + +static void evt_handler(nrfx_uarte_event_t const *event, void *context) +{ + const struct device *dev = context; + struct uarte_nrfx_data *data = dev->data; + + switch (event->type) { + case NRFX_UARTE_EVT_TX_DONE: + on_tx_done(dev, event); + break; + case NRFX_UARTE_EVT_RX_DONE: + on_rx_done(dev, event); + break; + case NRFX_UARTE_EVT_RX_BYTE: + on_rx_byte(dev); + break; + case NRFX_UARTE_EVT_ERROR: + data->async->err = event->data.error.error_mask; + break; + case NRFX_UARTE_EVT_RX_BUF_REQUEST: + on_rx_buf_req(dev); + break; + case NRFX_UARTE_EVT_RX_DISABLED: + on_rx_disabled(dev, data); + break; + case NRFX_UARTE_EVT_RX_BUF_TOO_LATE: + /* No support */ + break; + case NRFX_UARTE_EVT_TRIGGER: + trigger_handler(dev); + break; + default: + __ASSERT_NO_MSG(0); + } +} + +static int api_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout) +{ + struct uarte_nrfx_data *data = dev->data; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + bool hwfc; + +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + hwfc = data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS; +#else + const struct uarte_nrfx_config *config = dev->config; + + hwfc = config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED; +#endif + + err = nrfx_uarte_tx(nrfx_dev, buf, len, 0); + if (err != NRFX_SUCCESS) { + return (err == NRFX_ERROR_BUSY) ? -EBUSY : -EIO; + } + + if (hwfc && timeout != SYS_FOREVER_US) { + k_timer_start(&data->async->tx_timer, K_USEC(timeout), K_NO_WAIT); + } + + return 0; +} + +static int api_tx_abort(const struct device *dev) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + + err = nrfx_uarte_tx_abort(nrfx_dev, false); + return (err == NRFX_SUCCESS) ? 0 : -EFAULT; +} + +static void tx_timeout_handler(struct k_timer *timer) +{ + const struct device *dev = k_timer_user_data_get(timer); + + (void)api_tx_abort(dev); +} + +static void rx_timeout_handler(struct k_timer *timer) +{ + const struct device *dev = (const struct device *)k_timer_user_data_get(timer); + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + + if (nrfx_uarte_rx_new_data_check(nrfx_dev)) { + adata->idle_cnt = RX_TIMEOUT_DIV - 1; + } else { + adata->idle_cnt--; + if (adata->idle_cnt == 0) { + (void)nrfx_uarte_rx_abort(nrfx_dev, false, false); + return; + } + } + + start_rx_timer(data); +} + +/* Determine if RX FIFO content shall be kept when device is being disabled. + * When flow-control is used then we expect to keep RX FIFO content since HWFC + * enforces lossless communication. However, when HWFC is not used (by any instance + * then RX FIFO handling feature is disabled in the nrfx_uarte to save space. + * It is based on assumption that without HWFC it is expected that some data may + * be lost and there are means to prevent that (keeping receiver always opened by + * provided reception buffers on time). + */ +static inline uint32_t get_keep_fifo_content_flag(const struct device *dev) +{ +#if CONFIG_UART_USE_RUNTIME_CONFIGURE + struct uarte_nrfx_data *data = dev->data; + + if (data->uart_config.flow_ctrl == UART_CFG_FLOW_CTRL_RTS_CTS) { + return NRFX_UARTE_RX_ENABLE_KEEP_FIFO_CONTENT; + } +#else + const struct uarte_nrfx_config *config = dev->config; + + if (config->nrfx_config.config.hwfc == NRF_UARTE_HWFC_ENABLED) { + return NRFX_UARTE_RX_ENABLE_KEEP_FIFO_CONTENT; + } +#endif + + return 0; +} + +static int api_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) +{ + nrfx_err_t err; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + struct uarte_async_data *adata = data->async; + uint32_t flags = NRFX_UARTE_RX_ENABLE_CONT | + get_keep_fifo_content_flag(dev) | + (IS_ASYNC_API(dev) ? NRFX_UARTE_RX_ENABLE_STOP_ON_END : 0); + + if (cfg->flags & UARTE_CFG_FLAG_NO_RX) { + return -ENOTSUP; + } + + if (timeout != SYS_FOREVER_US) { + adata->idle_cnt = RX_TIMEOUT_DIV + 1; + adata->rx_timeout = K_USEC(timeout / RX_TIMEOUT_DIV); + } else { + adata->rx_timeout = K_NO_WAIT; + } + + err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len); + if (err != NRFX_SUCCESS) { + return -EIO; + } + + err = nrfx_uarte_rx_enable(nrfx_dev, flags); + if (err != NRFX_SUCCESS) { + return (err == NRFX_ERROR_BUSY) ? -EBUSY : -EIO; + } + + atomic_or(&data->flags, UARTE_DATA_FLAG_RX_ENABLED); + + return 0; +} + +static int api_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + struct uarte_nrfx_data *data = dev->data; + nrfx_err_t err; + + if (!(data->flags & UARTE_DATA_FLAG_RX_ENABLED)) { + return -EACCES; + } + + err = nrfx_uarte_rx_buffer_set(nrfx_dev, buf, len); + switch (err) { + case NRFX_SUCCESS: + return 0; + case NRFX_ERROR_BUSY: + return -EBUSY; + default: + return -EIO; + } +} + +static int api_rx_disable(const struct device *dev) +{ + struct uarte_nrfx_data *data = dev->data; + + k_timer_stop(&data->async->rx_timer); + + return (nrfx_uarte_rx_abort(get_nrfx_dev(dev), true, false) == NRFX_SUCCESS) ? 0 : -EFAULT; +} + +static int api_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uarte_nrfx_config *cfg = dev->config; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + nrfx_err_t err; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_fifo_read(dev, c, 1) == 0 ? -1 : 0; + } + + if (IS_ASYNC_API(dev)) { + return -EBUSY; + } + + err = nrfx_uarte_rx_ready(instance, NULL); + if (err == NRFX_SUCCESS) { + uint8_t *rx_byte = cfg->nrfx_config.rx_cache.p_buffer; + + *c = *rx_byte; + err = nrfx_uarte_rx_buffer_set(instance, rx_byte, 1); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + return 0; + } + + return -1; +} + +static void api_poll_out(const struct device *dev, unsigned char out_char) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + nrfx_err_t err; + + do { + /* When runtime PM is used we cannot use early return because then + * we have no information when UART is actually done with the + * transmission. It reduces UART performance however, polling in + * general is not power efficient and should be avoided in low + * power applications. + */ + err = nrfx_uarte_tx(nrfx_dev, &out_char, 1, NRFX_UARTE_TX_EARLY_RETURN); + __ASSERT(err != NRFX_ERROR_INVALID_ADDR, "Invalid address of the buffer"); + + if (err == NRFX_ERROR_BUSY && + IS_ENABLED(CONFIG_MULTITHREADING) && k_is_preempt_thread()) { + k_msleep(1); + } + Z_SPIN_DELAY(3); + } while (err == NRFX_ERROR_BUSY); +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +/** + * @brief Set the baud rate + * + * This routine set the given baud rate for the UARTE. + * + * @param dev UARTE device struct + * @param baudrate Baud rate + * + * @return 0 on success or error code + */ +static int baudrate_set(NRF_UARTE_Type *uarte, uint32_t baudrate) +{ + nrf_uarte_baudrate_t nrf_baudrate = NRF_BAUDRATE(baudrate); + + if (baudrate == 0) { + return -EINVAL; + } + + nrfy_uarte_baudrate_set(uarte, nrf_baudrate); + + return 0; +} + +static int uarte_nrfx_configure(const struct device *dev, + const struct uart_config *cfg) +{ + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + struct uarte_nrfx_data *data = dev->data; + nrf_uarte_config_t uarte_cfg; + +#if defined(UARTE_CONFIG_STOP_Msk) + switch (cfg->stop_bits) { + case UART_CFG_STOP_BITS_1: + uarte_cfg.stop = NRF_UARTE_STOP_ONE; + break; + case UART_CFG_STOP_BITS_2: + uarte_cfg.stop = NRF_UARTE_STOP_TWO; + break; + default: + return -ENOTSUP; + } +#else + if (cfg->stop_bits != UART_CFG_STOP_BITS_1) { + return -ENOTSUP; + } +#endif + + if (cfg->data_bits != UART_CFG_DATA_BITS_8) { + return -ENOTSUP; + } + + switch (cfg->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + uarte_cfg.hwfc = NRF_UARTE_HWFC_DISABLED; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + uarte_cfg.hwfc = NRF_UARTE_HWFC_ENABLED; + break; + default: + return -ENOTSUP; + } + +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) + uarte_cfg.paritytype = NRF_UARTE_PARITYTYPE_EVEN; +#endif + switch (cfg->parity) { + case UART_CFG_PARITY_NONE: + uarte_cfg.parity = NRF_UARTE_PARITY_EXCLUDED; + break; + case UART_CFG_PARITY_EVEN: + uarte_cfg.parity = NRF_UARTE_PARITY_INCLUDED; + break; +#if defined(UARTE_CONFIG_PARITYTYPE_Msk) + case UART_CFG_PARITY_ODD: + uarte_cfg.parity = NRF_UARTE_PARITY_INCLUDED; + uarte_cfg.paritytype = NRF_UARTE_PARITYTYPE_ODD; + break; +#endif + default: + return -ENOTSUP; + } + + if (baudrate_set(nrfx_dev->p_reg, cfg->baudrate) != 0) { + return -ENOTSUP; + } + + nrfy_uarte_configure(nrfx_dev->p_reg, &uarte_cfg); + + data->uart_config = *cfg; + + return 0; +} + +static int uarte_nrfx_config_get(const struct device *dev, + struct uart_config *cfg) +{ + struct uarte_nrfx_data *data = dev->data; + + *cfg = data->uart_config; + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#if UARTE_ANY_POLLING || UARTE_ANY_INTERRUPT_DRIVEN +static int api_err_check(const struct device *dev) +{ + if (IS_POLLING_API(dev)) { + const struct uarte_nrfx_config *cfg = dev->config; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + uint32_t mask = nrfx_uarte_errorsrc_get(instance); + + return mask; + } + + struct uarte_nrfx_data *data = dev->data; + uint32_t rv = data->async->err; + + data->async->err = 0; + + return rv; +} +#endif + +static const struct uart_async_to_irq_async_api a2i_api = { + .callback_set = callback_set, + .tx = api_tx, + .tx_abort = api_tx_abort, + .rx_enable = api_rx_enable, + .rx_buf_rsp = api_rx_buf_rsp, + .rx_disable = api_rx_disable, +}; + +static const struct uart_driver_api uart_nrfx_uarte_driver_api = { + .poll_in = api_poll_in, + .poll_out = api_poll_out, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uarte_nrfx_configure, + .config_get = uarte_nrfx_config_get, +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ +#if UARTE_ANY_POLLING || UARTE_ANY_INTERRUPT_DRIVEN + .err_check = api_err_check, +#endif +#if UARTE_ANY_ASYNC + .callback_set = api_callback_set, + .tx = api_tx, + .tx_abort = api_tx_abort, + .rx_enable = api_rx_enable, + .rx_buf_rsp = api_rx_buf_rsp, + .rx_disable = api_rx_disable, +#endif /* UARTE_ANY_ASYNC */ +#if UARTE_ANY_INTERRUPT_DRIVEN + UART_ASYNC_TO_IRQ_API_INIT(), +#endif /* UARTE_ANY_INTERRUPT_DRIVEN */ +}; + +static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte) +{ + nrfx_err_t ret; + uint8_t ch; + + ret = nrfx_gppi_channel_alloc(&ch); + if (ret != NRFX_SUCCESS) { + LOG_ERR("Failed to allocate PPI Channel"); + return -EIO; + } + + nrfx_gppi_channel_endpoints_setup(ch, + nrfy_uarte_event_address_get(uarte, NRF_UARTE_EVENT_ENDTX), + nrfy_uarte_task_address_get(uarte, NRF_UARTE_TASK_STOPTX)); + nrfx_gppi_channels_enable(BIT(ch)); + + return 0; +} + +static int start_rx(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_async_to_irq_rx_enable(dev); + } + + __ASSERT_NO_MSG(IS_POLLING_API(dev)); + + nrfx_err_t err; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + uint8_t *rx_byte = cfg->nrfx_config.rx_cache.p_buffer; + + err = nrfx_uarte_rx_buffer_set(instance, rx_byte, 1); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + err = nrfx_uarte_rx_enable(instance, 0); + __ASSERT_NO_MSG(err == NRFX_SUCCESS || err == NRFX_ERROR_BUSY); + + (void)err; + + return 0; +} + +static void async_to_irq_trampoline(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + uint32_t prev = atomic_or(&data->flags, UARTE_DATA_FLAG_TRAMPOLINE); + + if (!(prev & UARTE_DATA_FLAG_TRAMPOLINE)) { + nrfx_uarte_int_trigger(&cfg->nrfx_dev); + } +} + +static int uarte_nrfx_init(const struct device *dev) +{ + int err; + nrfx_err_t nerr; + const nrfx_uarte_t *nrfx_dev = get_nrfx_dev(dev); + const struct uarte_nrfx_config *cfg = dev->config; + struct uarte_nrfx_data *data = dev->data; + + err = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (err < 0) { + return err; + } + + if (UARTE_ENHANCED_POLL_OUT && cfg->nrfx_config.tx_stop_on_end) { + err = endtx_stoptx_ppi_init(nrfx_dev->p_reg); + if (err < 0) { + return err; + } + } + + if (UARTE_ANY_INTERRUPT_DRIVEN) { + if (cfg->a2i_config) { + err = uart_async_to_irq_init(data->a2i_data, cfg->a2i_config); + if (err < 0) { + return err; + } + } + } + + if (IS_ENABLED(UARTE_INT_ASYNC) && data->async) { + k_timer_init(&data->async->rx_timer, rx_timeout_handler, NULL); + k_timer_user_data_set(&data->async->rx_timer, (void *)dev); + k_timer_init(&data->async->tx_timer, tx_timeout_handler, NULL); + k_timer_user_data_set(&data->async->tx_timer, (void *)dev); + } + + nerr = nrfx_uarte_init(nrfx_dev, &cfg->nrfx_config, + IS_ENABLED(UARTE_INT_ASYNC) ? + (IS_POLLING_API(dev) ? NULL : evt_handler) : NULL); + if (nerr == NRFX_SUCCESS && !IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + err = start_rx(dev); + } + + switch (nerr) { + case NRFX_ERROR_INVALID_STATE: + return -EBUSY; + case NRFX_ERROR_BUSY: + return -EACCES; + case NRFX_ERROR_INVALID_PARAM: + return -EINVAL; + default: + return 0; + } +} + +#ifdef CONFIG_PM_DEVICE +static int stop_rx(const struct device *dev) +{ + const struct uarte_nrfx_config *cfg = dev->config; + + if (IS_INT_DRIVEN_API(dev)) { + return uart_async_to_irq_rx_disable(dev); + } + + __ASSERT_NO_MSG(IS_POLLING_API(dev)); + nrfx_err_t err; + const nrfx_uarte_t *instance = &cfg->nrfx_dev; + + err = nrfx_uarte_rx_abort(instance, true, true); + __ASSERT_NO_MSG(err == NRFX_SUCCESS); + + return 0; +} + +static int uarte_nrfx_pm_action(const struct device *dev, + enum pm_device_action action) +{ + const struct uarte_nrfx_config *cfg = dev->config; + int ret; + + switch (action) { + case PM_DEVICE_ACTION_RESUME: + if (cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT) { + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT); + if (ret < 0) { + return ret; + } + } + if (!IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + return start_rx(dev); + } + + break; + case PM_DEVICE_ACTION_SUSPEND: + if (!IS_ASYNC_API(dev) && !(cfg->flags & UARTE_CFG_FLAG_NO_RX)) { + stop_rx(dev); + } + + if (cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT) { + ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_SLEEP); + if (ret < 0) { + return ret; + } + } + + break; + default: + return -ENOTSUP; + } + + return 0; +} +#endif + +#if defined(UARTE_CONFIG_STOP_Msk) +#define UARTE_HAS_STOP_CONFIG 1 +#endif + +#define UARTE(idx) DT_NODELABEL(uart##idx) +#define UARTE_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(UARTE(idx), prop) +#define UARTE_PROP(idx, prop) DT_PROP(UARTE(idx), prop) + +/* Macro returning initial log level. Logs are off for UART used for console. */ +#define GET_INIT_LOG_LEVEL(idx) \ + COND_CODE_1(DT_HAS_CHOSEN(zephyr_console), \ + (DT_SAME_NODE(UARTE(idx), \ + DT_CHOSEN(zephyr_console)) ? \ + LOG_LEVEL_NONE : CONFIG_UART_LOG_LEVEL), \ + (CONFIG_UART_LOG_LEVEL)) + +/* Macro puts buffers in dedicated section if device tree property is set. */ +#define UARTE_MEMORY_SECTION(idx) \ + COND_CODE_1(UARTE_HAS_PROP(idx, memory_regions), \ + (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \ + DT_PHANDLE(UARTE(idx), memory_regions)))))), \ + ()) + +#define UART_NRF_UARTE_DEVICE(idx) \ + LOG_INSTANCE_REGISTER(LOG_MODULE_NAME, idx, GET_INIT_LOG_LEVEL(idx)); \ + static uint8_t uarte##idx##_tx_cache[CONFIG_UART_##idx##_TX_CACHE_SIZE] \ + UARTE_MEMORY_SECTION(idx) __aligned(4); \ + static uint8_t uarte##idx##_rx_cache[CONFIG_UART_##idx##_RX_CACHE_SIZE] \ + UARTE_MEMORY_SECTION(idx) __aligned(4); \ + static nrfx_uarte_rx_cache_t uarte##idx##_rx_cache_scratch; \ + IF_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (static uint8_t a2i_rx_buf##idx[CONFIG_UART_##idx##_A2I_RX_SIZE];)) \ + PINCTRL_DT_DEFINE(UARTE(idx)); \ + static const struct uart_async_to_irq_config uarte_a2i_config_##idx = \ + UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(&a2i_api, \ + async_to_irq_trampoline, \ + UARTE_PROP(idx, current_speed), \ + uarte##idx##_tx_cache, \ + /* nrfx_uarte driver is using the last byte in the */ \ + /* cache buffer for keeping a byte that is currently*/\ + /* polled out so it cannot be used as a cache buffer*/\ + /* by the adaptation layer. */ \ + sizeof(uarte##idx##_tx_cache) - 1, \ + COND_CODE_1(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (a2i_rx_buf##idx), (NULL)), \ + COND_CODE_1(CONFIG_UART_##idx##_INTERRUPT_DRIVEN, \ + (sizeof(a2i_rx_buf##idx)), (0)), \ + CONFIG_UART_##idx##_A2I_RX_BUF_COUNT, \ + LOG_INSTANCE_PTR(LOG_MODULE_NAME, idx)); \ + static const struct uarte_nrfx_config uarte_config_##idx = { \ + .a2i_config = IS_ENABLED(CONFIG_UART_##idx## _INTERRUPT_DRIVEN) ? \ + &uarte_a2i_config_##idx : NULL, \ + .nrfx_dev = NRFX_UARTE_INSTANCE(idx), \ + .nrfx_config = { \ + .p_context = (void *)DEVICE_DT_GET(UARTE(idx)), \ + .tx_cache = { \ + .p_buffer = uarte##idx##_tx_cache, \ + .length = CONFIG_UART_##idx##_TX_CACHE_SIZE \ + }, \ + .rx_cache = { \ + .p_buffer = uarte##idx##_rx_cache, \ + .length = CONFIG_UART_##idx##_RX_CACHE_SIZE \ + }, \ + .p_rx_cache_scratch = &uarte##idx##_rx_cache_scratch, \ + .baudrate = NRF_BAUDRATE(UARTE_PROP(idx, current_speed)), \ + .interrupt_priority = DT_IRQ(UARTE(idx), priority), \ + .config = { \ + .hwfc = (UARTE_PROP(idx, hw_flow_control) == \ + UART_CFG_FLOW_CTRL_RTS_CTS) ? \ + NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED, \ + .parity = IS_ENABLED(CONFIG_UART_##idx##_NRF_PARITY_BIT) ? \ + NRF_UARTE_PARITY_INCLUDED : NRF_UARTE_PARITY_EXCLUDED, \ + IF_ENABLED(UARTE_HAS_STOP_CONFIG, (.stop = NRF_UARTE_STOP_ONE,))\ + IF_ENABLED(UARTE_ODD_PARITY_ALLOWED, \ + (.paritytype = NRF_UARTE_PARITYTYPE_EVEN,)) \ + }, \ + .tx_stop_on_end = IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT), \ + .skip_psel_cfg = true, \ + .skip_gpio_cfg = true, \ + }, \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(UARTE(idx)), \ + .flags = (UARTE_PROP(idx, disable_rx) ? UARTE_CFG_FLAG_NO_RX : 0) | \ + (IS_ENABLED(CONFIG_UART_##idx##_GPIO_MANAGEMENT) ? \ + UARTE_CFG_FLAG_GPIO_MGMT : 0) | \ + (IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) ? \ + UARTE_CFG_FLAG_INTERRUPT_DRIVEN_API : 0), \ + LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx) \ + }; \ + static struct uart_async_to_irq_data uarte_a2i_data_##idx; \ + static struct uarte_async_data uarte_async_##idx; \ + static struct uarte_nrfx_data uarte_data_##idx = { \ + .a2i_data = IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) ? \ + &uarte_a2i_data_##idx : NULL, \ + IF_ENABLED(CONFIG_UART_USE_RUNTIME_CONFIGURE, \ + (.uart_config = { \ + .baudrate = UARTE_PROP(idx, current_speed), \ + .parity = IS_ENABLED(CONFIG_UART_##idx##_NRF_PARITY_BIT) ? \ + UART_CFG_PARITY_EVEN : UART_CFG_PARITY_NONE, \ + .stop_bits = UART_CFG_STOP_BITS_1, \ + .data_bits = UART_CFG_DATA_BITS_8, \ + .flow_ctrl = UARTE_PROP(idx, hw_flow_control) ? \ + UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE, \ + },)) \ + .async = (IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN) || \ + IS_ENABLED(CONFIG_UART_##idx##_ASYNC)) ? &uarte_async_##idx : NULL \ + }; \ + static int uarte_init_##idx(const struct device *dev) \ + { \ + COND_CODE_1(INSTANCE_POLLING(_, /*empty*/, idx, _), (), \ + ( \ + IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \ + nrfx_isr, nrfx_uarte_##idx##_irq_handler, 0); \ + irq_enable(DT_IRQN(UARTE(idx))); \ + ) \ + ) \ + return uarte_nrfx_init(dev); \ + } \ + PM_DEVICE_DT_DEFINE(UARTE(idx), uarte_nrfx_pm_action); \ + DEVICE_DT_DEFINE(UARTE(idx), \ + uarte_init_##idx, \ + PM_DEVICE_DT_GET(UARTE(idx)), \ + &uarte_data_##idx, \ + &uarte_config_##idx, \ + PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ + &uart_nrfx_uarte_driver_api) + +/* Macro creates device instance if it is enabled in devicetree. */ +#define UARTE_DEVICE(periph, prefix, id, _) \ + IF_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##id, (UART_NRF_UARTE_DEVICE(prefix##id);)) + +/* Macro iterates over nrfx_uarte instances enabled in the nrfx_config.h. */ +NRFX_FOREACH_ENABLED(UARTE, UARTE_DEVICE, (), (), _) diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index c185efa9f8f..0ee1c03065b 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -54,6 +54,7 @@ config SPI_NRFX_SPIS config SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 depends on SOC_NRF52832 + select NRFX_PPI bool "Allow enabling the SPIM driver despite PAN 58" help Allow enabling the nRF SPI Master with EasyDMA, despite @@ -74,14 +75,20 @@ config SPI_NRFX_RAM_BUFFER_SIZE default 8 depends on SPI_NRFX_SPIM help - SPIM peripherals cannot transmit data directly from flash. Therefore, - a buffer in RAM needs to be provided for each instance of SPI driver - using SPIM peripheral, so that the driver can copy there a chunk of - data from flash and transmit it. - The size is specified in bytes. A size of 0 means that this feature - should be disabled, and the application must then take care of not - supplying buffers located in flash to the driver, otherwise such - transfers will fail. + Because of using EasyDMA, SPIM peripherals cannot use transmit and + receive buffers from all memory locations. They are restricted to + buffers located in certain RAM memories only. Therefore, each SPIM + driver instance needs to use an intermediate local RAM buffer, + to transfer data in chunks not exceeding the size of that buffer, + and to copy those chunks between the local buffer and the one + specified in the transfer request if the latter is not accessible + by EasyDMA. + + This option specifies the size in bytes of such local RAM buffers + for both TX and RX paths. A size of 0 means that this feature should + be disabled and the driver user must take care of not making transfer + requests with buffers not accessible by EasyDMA since such transfers + will fail. config SPI_NRFX_WAKE_TIMEOUT_US int "Maximum time to wait for SPI slave to wake up" diff --git a/drivers/spi/spi_nrfx_common.c b/drivers/spi/spi_nrfx_common.c index 1ef233cfab3..04a11c2367a 100644 --- a/drivers/spi/spi_nrfx_common.c +++ b/drivers/spi/spi_nrfx_common.c @@ -6,40 +6,39 @@ #include "spi_nrfx_common.h" #include -#include -int spi_nrfx_wake_init(uint32_t wake_pin) +int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) { - nrfx_gpiote_input_config_t input_config = { - .pull = NRF_GPIO_PIN_PULLDOWN, - }; + nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLDOWN; uint8_t ch; nrfx_gpiote_trigger_config_t trigger_config = { .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, .p_in_channel = &ch, }; + nrfx_gpiote_input_pin_config_t input_config = { + .p_pull_config = &pull_config, + .p_trigger_config = &trigger_config, + .p_handler_config = NULL, + }; nrfx_err_t res; - res = nrfx_gpiote_channel_alloc(&ch); + res = nrfx_gpiote_channel_alloc(gpiote, &ch); if (res != NRFX_SUCCESS) { return -ENODEV; } - res = nrfx_gpiote_input_configure(wake_pin, - &input_config, - &trigger_config, - NULL); + res = nrfx_gpiote_input_configure(gpiote, wake_pin, &input_config); if (res != NRFX_SUCCESS) { - nrfx_gpiote_channel_free(ch); + nrfx_gpiote_channel_free(gpiote, ch); return -EIO; } return 0; } -int spi_nrfx_wake_request(uint32_t wake_pin) +int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin) { - nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(wake_pin); + nrf_gpiote_event_t trigger_event = nrfx_gpiote_in_event_get(gpiote, wake_pin); uint32_t start_cycles; uint32_t max_wait_cycles = DIV_ROUND_UP(CONFIG_SPI_NRFX_WAKE_TIMEOUT_US * @@ -51,7 +50,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) * The expected time to wait is quite short so it is not worth paying * the overhead of context switching to handle the interrupt. */ - nrfx_gpiote_trigger_enable(wake_pin, false); + nrfx_gpiote_trigger_enable(gpiote, wake_pin, false); /* Enable pull-up on the WAKE line. After the slave device sees the * WAKE line going high, it will force the line to go low. This will * be caught by the enabled trigger and the loop below waits for that. @@ -59,7 +58,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLUP); start_cycles = k_cycle_get_32(); - while (!nrf_gpiote_event_check(NRF_GPIOTE, trigger_event)) { + while (!nrf_gpiote_event_check(gpiote->p_reg, trigger_event)) { uint32_t elapsed_cycles = k_cycle_get_32() - start_cycles; if (elapsed_cycles >= max_wait_cycles) { @@ -68,7 +67,7 @@ int spi_nrfx_wake_request(uint32_t wake_pin) } } - nrfx_gpiote_trigger_disable(wake_pin); + nrfx_gpiote_trigger_disable(gpiote, wake_pin); nrf_gpio_cfg_input(wake_pin, NRF_GPIO_PIN_PULLDOWN); return err; diff --git a/drivers/spi/spi_nrfx_common.h b/drivers/spi/spi_nrfx_common.h index 515ed5c6f1f..0cf17e2a035 100644 --- a/drivers/spi/spi_nrfx_common.h +++ b/drivers/spi/spi_nrfx_common.h @@ -8,10 +8,17 @@ #define ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ #include +#include #define WAKE_PIN_NOT_USED UINT32_MAX -int spi_nrfx_wake_init(uint32_t wake_pin); -int spi_nrfx_wake_request(uint32_t wake_pin); +#define WAKE_GPIOTE_INSTANCE(node_id) \ + COND_CODE_1(DT_NODE_HAS_PROP(node_id, wake_gpios), \ + (NRFX_GPIOTE_INSTANCE( \ + NRF_DT_GPIOTE_INST(node_id, wake_gpios))), \ + ({0})) + +int spi_nrfx_wake_init(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); +int spi_nrfx_wake_request(const nrfx_gpiote_t *gpiote, uint32_t wake_pin); #endif /* ZEPHYR_DRIVERS_SPI_NRFX_COMMON_H_ */ diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index fd1dc5d933c..752132fb248 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -31,6 +31,7 @@ struct spi_nrfx_config { void (*irq_connect)(void); const struct pinctrl_dev_config *pcfg; uint32_t wake_pin; + nrfx_gpiote_t wake_gpiote; }; static void event_handler(const nrfx_spi_evt_t *p_event, void *p_context); @@ -160,8 +161,6 @@ static void finish_transaction(const struct device *dev, int error) struct spi_nrfx_data *dev_data = dev->data; struct spi_context *ctx = &dev_data->ctx; - spi_context_cs_control(ctx, false); - LOG_DBG("Transaction finished with status %d", error); spi_context_complete(ctx, dev, error); @@ -237,7 +236,8 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(dev_config->wake_pin); + error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); /* If timeout occurs, try to perform the transfer @@ -275,6 +275,8 @@ static int transceive(const struct device *dev, /* Clean up the driver state. */ k_sem_reset(&dev_data->ctx.sync); } + + spi_context_cs_control(&dev_data->ctx, false); } spi_context_release(&dev_data->ctx, error); @@ -381,7 +383,7 @@ static int spi_nrfx_init(const struct device *dev) } if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(dev_config->wake_pin); + err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -444,6 +446,7 @@ static int spi_nrfx_init(const struct device *dev) .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPI(idx)), \ .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPI(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ + .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPI(idx)), \ }; \ BUILD_ASSERT(!DT_NODE_HAS_PROP(SPI(idx), wake_gpios) || \ !(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \ diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 8b187f54c52..08012b389c5 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -9,11 +9,12 @@ #include #include #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 -#include #include #endif -#include +#ifdef CONFIG_SOC_NRF5340_CPUAPP #include +#endif +#include #include #include @@ -40,8 +41,9 @@ struct spi_nrfx_data { size_t chunk_len; bool busy; bool initialized; -#if SPI_BUFFER_IN_RAM - uint8_t *buffer; +#ifdef SPI_BUFFER_IN_RAM + uint8_t *tx_buffer; + uint8_t *rx_buffer; #endif #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 bool anomaly_58_workaround_active; @@ -61,6 +63,7 @@ struct spi_nrfx_config { bool anomaly_58_workaround; #endif uint32_t wake_pin; + nrfx_gpiote_t wake_gpiote; }; static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context); @@ -69,9 +72,9 @@ static inline uint32_t get_nrf_spim_frequency(uint32_t frequency) { /* Get the highest supported frequency not exceeding the requested one. */ - if (frequency >= MHZ(32) && NRF_SPIM_HAS_32_MHZ_FREQ) { + if (frequency >= MHZ(32) && (NRF_SPIM_HAS_32_MHZ_FREQ || NRF_SPIM_HAS_PRESCALER)) { return MHZ(32); - } else if (frequency >= MHZ(16) && NRF_SPIM_HAS_16_MHZ_FREQ) { + } else if (frequency >= MHZ(16) && (NRF_SPIM_HAS_16_MHZ_FREQ || NRF_SPIM_HAS_PRESCALER)) { return MHZ(16); } else if (frequency >= MHZ(8)) { return MHZ(8); @@ -204,6 +207,8 @@ static int configure(const struct device *dev, } #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 +static const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(0); + /* * Brief Workaround for transmitting 1 byte with SPIM. * @@ -223,15 +228,15 @@ static void anomaly_58_workaround_setup(const struct device *dev) NRF_SPIM_Type *spim = dev_config->spim.p_reg; uint32_t ppi_ch = dev_data->ppi_ch; uint32_t gpiote_ch = dev_data->gpiote_ch; - uint32_t eep = (uint32_t)&NRF_GPIOTE->EVENTS_IN[gpiote_ch]; + uint32_t eep = (uint32_t)&gpiote.p_reg->EVENTS_IN[gpiote_ch]; uint32_t tep = (uint32_t)&spim->TASKS_STOP; dev_data->anomaly_58_workaround_active = true; /* Create an event when SCK toggles */ - nrf_gpiote_event_configure(NRF_GPIOTE, gpiote_ch, spim->PSEL.SCK, + nrf_gpiote_event_configure(gpiote.p_reg, gpiote_ch, spim->PSEL.SCK, GPIOTE_CONFIG_POLARITY_Toggle); - nrf_gpiote_event_enable(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_event_enable(gpiote.p_reg, gpiote_ch); /* Stop the spim instance when SCK toggles */ nrf_ppi_channel_endpoint_setup(NRF_PPI, ppi_ch, eep, tep); @@ -250,7 +255,7 @@ static void anomaly_58_workaround_clear(struct spi_nrfx_data *dev_data) if (dev_data->anomaly_58_workaround_active) { nrf_ppi_channel_disable(NRF_PPI, ppi_ch); - nrf_gpiote_task_disable(NRF_GPIOTE, gpiote_ch); + nrf_gpiote_task_disable(gpiote.p_reg, gpiote_ch); dev_data->anomaly_58_workaround_active = false; } @@ -271,7 +276,7 @@ static int anomaly_58_workaround_init(const struct device *dev) return -ENODEV; } - err_code = nrfx_gpiote_channel_alloc(&dev_data->gpiote_ch); + err_code = nrfx_gpiote_channel_alloc(&gpiote, &dev_data->gpiote_ch); if (err_code != NRFX_SUCCESS) { LOG_ERR("Failed to allocate GPIOTE channel"); return -ENODEV; @@ -289,8 +294,6 @@ static void finish_transaction(const struct device *dev, int error) struct spi_nrfx_data *dev_data = dev->data; struct spi_context *ctx = &dev_data->ctx; - spi_context_cs_control(ctx, false); - LOG_DBG("Transaction finished with status %d", error); spi_context_complete(ctx, dev, error); @@ -310,25 +313,40 @@ static void transfer_next_chunk(const struct device *dev) nrfx_spim_xfer_desc_t xfer; nrfx_err_t result; const uint8_t *tx_buf = ctx->tx_buf; -#if (CONFIG_SPI_NRFX_RAM_BUFFER_SIZE > 0) - if (spi_context_tx_buf_on(ctx) && !nrfx_is_in_ram(tx_buf)) { + uint8_t *rx_buf = ctx->rx_buf; + + if (chunk_len > dev_config->max_chunk_len) { + chunk_len = dev_config->max_chunk_len; + } + +#ifdef SPI_BUFFER_IN_RAM + if (spi_context_tx_buf_on(ctx) && + !nrf_dma_accessible_check(&dev_config->spim.p_reg, tx_buf)) { + if (chunk_len > CONFIG_SPI_NRFX_RAM_BUFFER_SIZE) { chunk_len = CONFIG_SPI_NRFX_RAM_BUFFER_SIZE; } - memcpy(dev_data->buffer, tx_buf, chunk_len); - tx_buf = dev_data->buffer; + memcpy(dev_data->tx_buffer, tx_buf, chunk_len); + tx_buf = dev_data->tx_buffer; } -#endif - if (chunk_len > dev_config->max_chunk_len) { - chunk_len = dev_config->max_chunk_len; + + if (spi_context_rx_buf_on(ctx) && + !nrf_dma_accessible_check(&dev_config->spim.p_reg, rx_buf)) { + + if (chunk_len > CONFIG_SPI_NRFX_RAM_BUFFER_SIZE) { + chunk_len = CONFIG_SPI_NRFX_RAM_BUFFER_SIZE; + } + + rx_buf = dev_data->rx_buffer; } +#endif dev_data->chunk_len = chunk_len; xfer.p_tx_buffer = tx_buf; xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0; - xfer.p_rx_buffer = ctx->rx_buf; + xfer.p_rx_buffer = rx_buf; xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0; #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 @@ -372,6 +390,15 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context) #ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58 anomaly_58_workaround_clear(dev_data); +#endif +#ifdef SPI_BUFFER_IN_RAM + if (spi_context_rx_buf_on(&dev_data->ctx) && + p_event->xfer_desc.p_rx_buffer != NULL && + p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) { + (void)memcpy(dev_data->ctx.rx_buf, + dev_data->rx_buffer, + dev_data->chunk_len); + } #endif spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len); spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len); @@ -399,7 +426,8 @@ static int transceive(const struct device *dev, dev_data->busy = true; if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - error = spi_nrfx_wake_request(dev_config->wake_pin); + error = spi_nrfx_wake_request(&dev_config->wake_gpiote, + dev_config->wake_pin); if (error == -ETIMEDOUT) { LOG_WRN("Waiting for WAKE acknowledgment timed out"); /* If timeout occurs, try to perform the transfer @@ -440,6 +468,8 @@ static int transceive(const struct device *dev, anomaly_58_workaround_clear(dev_data); #endif } + + spi_context_cs_control(&dev_data->ctx, false); } spi_context_release(&dev_data->ctx, error); @@ -547,7 +577,7 @@ static int spi_nrfx_init(const struct device *dev) } if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { - err = spi_nrfx_wake_init(dev_config->wake_pin); + err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); if (err == -ENODEV) { LOG_ERR("Failed to allocate GPIOTE channel for WAKE"); return err; @@ -599,7 +629,10 @@ static int spi_nrfx_init(const struct device *dev) nrfx_isr, nrfx_spim_##idx##_irq_handler, 0); \ } \ IF_ENABLED(SPI_BUFFER_IN_RAM, \ - (static uint8_t spim_##idx##_buffer \ + (static uint8_t spim_##idx##_tx_buffer \ + [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ + SPIM_MEMORY_SECTION(idx); \ + static uint8_t spim_##idx##_rx_buffer \ [CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \ SPIM_MEMORY_SECTION(idx);)) \ static struct spi_nrfx_data spi_##idx##_data = { \ @@ -607,7 +640,8 @@ static int spi_nrfx_init(const struct device *dev) SPI_CONTEXT_INIT_SYNC(spi_##idx##_data, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPIM(idx), ctx) \ IF_ENABLED(SPI_BUFFER_IN_RAM, \ - (.buffer = spim_##idx##_buffer,)) \ + (.tx_buffer = spim_##idx##_tx_buffer, \ + .rx_buffer = spim_##idx##_rx_buffer,)) \ .dev = DEVICE_DT_GET(SPIM(idx)), \ .busy = false, \ }; \ @@ -634,8 +668,9 @@ static int spi_nrfx_init(const struct device *dev) ()) \ .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \ WAKE_PIN_NOT_USED), \ + .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \ }; \ - BUILD_ASSERT(!DT_NODE_HAS_PROP(SPIM(idx), wake_gpios) || \ + BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \ !(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\ "WAKE line must be configured as active high"); \ PM_DEVICE_DT_DEFINE(SPIM(idx), spim_nrfx_pm_action); \ diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 47a10b358c1..36534e4716f 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -24,6 +24,7 @@ zephyr_library_sources_ifdef(CONFIG_MCUX_GPT_TIMER mcux_gpt_timer.c) zephyr_library_sources_ifdef(CONFIG_MIPS_CP0_TIMER mips_cp0_timer.c) zephyr_library_sources_ifdef(CONFIG_NATIVE_POSIX_TIMER native_posix_timer.c) zephyr_library_sources_ifdef(CONFIG_NPCX_ITIM_TIMER npcx_itim_timer.c) +zephyr_library_sources_ifdef(CONFIG_NRF_GRTC_TIMER nrf_grtc_timer.c) zephyr_library_sources_ifdef(CONFIG_NRF_RTC_TIMER nrf_rtc_timer.c) zephyr_library_sources_ifdef(CONFIG_RCAR_CMT_TIMER rcar_cmt_timer.c) zephyr_library_sources_ifdef(CONFIG_RISCV_MACHINE_TIMER riscv_machine_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 8a88e731986..f20442dd2c5 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -84,6 +84,8 @@ source "drivers/timer/Kconfig.mips_cp0" source "drivers/timer/Kconfig.native_posix" source "drivers/timer/Kconfig.npcx_itim" source "drivers/timer/Kconfig.nrf_rtc" +source "drivers/timer/Kconfig.nrf_grtc" +source "drivers/timer/Kconfig.nrf_xrtc" source "drivers/timer/Kconfig.rcar_cmt" source "drivers/timer/Kconfig.riscv_machine" source "drivers/timer/Kconfig.rv32m1_lptmr" diff --git a/drivers/timer/Kconfig.nrf_grtc b/drivers/timer/Kconfig.nrf_grtc new file mode 100644 index 00000000000..442c524fd19 --- /dev/null +++ b/drivers/timer/Kconfig.nrf_grtc @@ -0,0 +1,48 @@ +# Timer driver configuration options +# Copyright (c) 2024 Nordic Semiconductor ASA + +menuconfig NRF_GRTC_TIMER + bool "nRF GRTC Timer" + default y if DT_HAS_NORDIC_NRF_GRTC_ENABLED + select TICKLESS_CAPABLE + select TIMER_HAS_64BIT_CYCLE_COUNTER + select NRFX_GRTC + help + This module implements a kernel device driver for the nRF Global Real + Time Counter NRF_GRTC and provides the standard "system clock driver" + interfaces. + +if NRF_GRTC_TIMER + +config NRF_GRTC_SLEEP_ALLOWED + def_bool y + depends on POWEROFF + help + This feature allows GRTC SYSCOUNTER to go to sleep state. + +config NRF_GRTC_TIMER_APP_DEFINED_INIT + bool "Application defines GRTC initialization" + help + Application defines the initialization procedure and time of the GRTC + drivers, rather than leaving it up to SYS_INIT. + +config NRF_GRTC_START_SYSCOUNTER + bool "Start SYSCOUNTER on driver init" + select NRF_GRTC_TIMER_CLOCK_MANAGEMENT + help + Start the SYSCOUNTER when initializing the GRTC. This should only be + handled by one processor in the system. + +config NRF_GRTC_TIMER_CLOCK_MANAGEMENT + bool + help + Compile additional driver code for enabling management functionality of + the GRTC. Usually this is only needed by the processor that is starting + the SYSCOUNTER, but can be shared by multiple processors in the system. + +config NRF_GRTC_SLEEP_MINIMUM_LATENCY + int + default 1000 + depends on NRF_GRTC_SLEEP_ALLOWED + +endif # NRF_GRTC_TIMER diff --git a/drivers/timer/Kconfig.nrf_rtc b/drivers/timer/Kconfig.nrf_rtc index baa917282bc..729dc8d362a 100644 --- a/drivers/timer/Kconfig.nrf_rtc +++ b/drivers/timer/Kconfig.nrf_rtc @@ -42,36 +42,4 @@ config NRF_RTC_TIMER_TRIGGER_OVERFLOW When enabled, a function can be used to trigger RTC overflow and effectively shift time into the future. -choice - prompt "Clock startup policy" - default SYSTEM_CLOCK_WAIT_FOR_STABILITY - -config SYSTEM_CLOCK_NO_WAIT - bool "No wait" - help - System clock source is initiated but does not wait for clock readiness. - When this option is picked, system clock may not be ready when code relying - on kernel API is executed. Requested timeouts will be prolonged by the - remaining startup time. - -config SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY - bool "Wait for availability" - help - System clock source initialization waits until clock is available. In some - systems, clock initially runs from less accurate source which has faster - startup time and then seamlessly switches to the target clock source when - it is ready. When this option is picked, system clock is available after - system clock driver initialization but it may be less accurate. Option is - equivalent to waiting for stability if clock source does not have - intermediate state. - -config SYSTEM_CLOCK_WAIT_FOR_STABILITY - bool "Wait for stability" - help - System clock source initialization waits until clock is stable. When this - option is picked, system clock is available and stable after system clock - driver initialization. - -endchoice - endif # NRF_RTC_TIMER diff --git a/drivers/timer/Kconfig.nrf_xrtc b/drivers/timer/Kconfig.nrf_xrtc new file mode 100644 index 00000000000..f9fa25a1c30 --- /dev/null +++ b/drivers/timer/Kconfig.nrf_xrtc @@ -0,0 +1,38 @@ +# Common RTC configuration + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if NRF_RTC_TIMER || NRF_GRTC_TIMER +choice + prompt "Clock startup policy" + default SYSTEM_CLOCK_WAIT_FOR_STABILITY + +config SYSTEM_CLOCK_NO_WAIT + bool "No wait" + help + System clock source is initiated but does not wait for clock readiness. + When this option is picked, system clock may not be ready when code relying + on kernel API is executed. Requested timeouts will be prolonged by the + remaining startup time. + +config SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY + bool "Wait for availability" + help + System clock source initialization waits until clock is available. In some + systems, clock initially runs from less accurate source which has faster + startup time and then seamlessly switches to the target clock source when + it is ready. When this option is picked, system clock is available after + system clock driver initialization but it may be less accurate. Option is + equivalent to waiting for stability if clock source does not have + intermediate state. + +config SYSTEM_CLOCK_WAIT_FOR_STABILITY + bool "Wait for stability" + help + System clock source initialization waits until clock is stable. When this + option is picked, system clock is available and stable after system clock + driver initialization. + +endchoice +endif # NRF_RTC_TIMER || NRF_GRTC_TIMER diff --git a/drivers/timer/nrf_grtc_timer.c b/drivers/timer/nrf_grtc_timer.c new file mode 100644 index 00000000000..8ac357864cc --- /dev/null +++ b/drivers/timer/nrf_grtc_timer.c @@ -0,0 +1,580 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#if defined(CONFIG_CLOCK_CONTROL_NRF) +#include +#endif +#include +#include +#include +#include + +#define GRTC_NODE DT_NODELABEL(grtc) + +/* Ensure that GRTC properties in devicetree are defined correctly. */ +#if !DT_NODE_HAS_PROP(GRTC_NODE, owned_channels) +#error GRTC owned-channels DT property is not defined +#endif +#define OWNED_CHANNELS_MASK NRFX_CONFIG_GRTC_MASK_DT(owned_channels) +#define CHILD_OWNED_CHANNELS_MASK NRFX_CONFIG_GRTC_MASK_DT(child_owned_channels) +#if ((OWNED_CHANNELS_MASK | CHILD_OWNED_CHANNELS_MASK) != OWNED_CHANNELS_MASK) +#error GRTC child-owned-channels DT property must be a subset of owned-channels +#endif + +#define CHAN_COUNT NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define EXT_CHAN_COUNT (CHAN_COUNT - 1) +/* The reset value of waketime is 1, which doesn't seem to work. + * It's being looked into, but for the time being use 4. + * Timeout must always be higher than waketime, so setting that to 5. + */ +#define WAKETIME (4) +#define TIMEOUT (WAKETIME + 1) + +#ifndef GRTC_SYSCOUNTERL_VALUE_Msk +#define GRTC_SYSCOUNTERL_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERL_VALUE_Msk +#endif + +#ifndef GRTC_SYSCOUNTERH_VALUE_Msk +#define GRTC_SYSCOUNTERH_VALUE_Msk GRTC_SYSCOUNTER_SYSCOUNTERH_VALUE_Msk +#endif + +#define MAX_CC_LATCH_WAIT_TIME_US 77 + +#define CYC_PER_TICK \ + ((uint64_t)sys_clock_hw_cycles_per_sec() / (uint64_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +#define COUNTER_SPAN (GRTC_SYSCOUNTERL_VALUE_Msk | ((uint64_t)GRTC_SYSCOUNTERH_VALUE_Msk << 32)) +#define MAX_TICKS \ + (((COUNTER_SPAN / CYC_PER_TICK) > INT_MAX) ? INT_MAX : (COUNTER_SPAN / CYC_PER_TICK)) + +#define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK) + +/* The maximum SYSCOUNTERVALID settling time equals 1x32k cycles + 20x1MHz cycles. */ +#define GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US 51 + +#if defined(CONFIG_TEST) +const int32_t z_sys_timer_irq_for_test = DT_IRQN(GRTC_NODE); +#endif + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context); + +static struct k_spinlock lock; +static uint64_t last_count; +static atomic_t int_mask; +static uint8_t ext_channels_allocated; +static nrfx_grtc_channel_t system_clock_channel_data = { + .handler = sys_clock_timeout_handler, + .p_context = NULL, + .channel = (uint8_t)-1, +}; + +#define IS_CHANNEL_ALLOWED_ASSERT(chan) \ + __ASSERT_NO_MSG((NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK & (1UL << (chan))) && \ + ((chan) != system_clock_channel_data.channel)) + +static inline void grtc_active_set(void) +{ +#if defined(NRF_GRTC_HAS_SYSCOUNTER_ARRAY) && (NRF_GRTC_HAS_SYSCOUNTER_ARRAY == 1) + nrfy_grtc_sys_counter_active_set(NRF_GRTC, true); + while (!nrfy_grtc_sys_conter_ready_check(NRF_GRTC)) { + } +#else + nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, true); + k_busy_wait(GRTC_SYSCOUNTERVALID_SETTLE_MAX_TIME_US); +#endif +} + +static inline void grtc_wakeup(void) +{ + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + grtc_active_set(); + } +} + +static inline void grtc_sleep(void) +{ + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { +#if defined(NRF_GRTC_HAS_SYSCOUNTER_ARRAY) && (NRF_GRTC_HAS_SYSCOUNTER_ARRAY == 1) + nrfy_grtc_sys_counter_active_set(NRF_GRTC, false); +#else + nrfy_grtc_sys_counter_active_state_request_set(NRF_GRTC, false); +#endif + } +} + +static inline uint64_t counter_sub(uint64_t a, uint64_t b) +{ + return (a - b); +} + +static inline uint64_t counter(void) +{ + uint64_t now; + + grtc_wakeup(); + nrfx_grtc_syscounter_get(&now); + grtc_sleep(); + return now; +} + +static inline uint64_t get_comparator(uint32_t chan) +{ + uint64_t cc; + nrfx_err_t result; + + result = nrfx_grtc_syscounter_cc_value_read(chan, &cc); + if (result != NRFX_SUCCESS) { + if (result != NRFX_ERROR_INVALID_PARAM) { + return -EAGAIN; + } + return -EPERM; + } + return cc; +} + +static void system_timeout_set(uint64_t value) +{ + if (value <= NRF_GRTC_SYSCOUNTER_CCADD_MASK) { + grtc_wakeup(); + nrfx_grtc_syscounter_cc_relative_set(&system_clock_channel_data, value, true, + NRFX_GRTC_CC_RELATIVE_SYSCOUNTER); + grtc_sleep(); + } else { + nrfx_grtc_syscounter_cc_absolute_set(&system_clock_channel_data, value + counter(), + true); + } +} + +static bool compare_int_lock(int32_t chan) +{ + atomic_val_t prev = atomic_and(&int_mask, ~BIT(chan)); + + nrfx_grtc_syscounter_cc_int_disable(chan); + + return prev & BIT(chan); +} + +static void compare_int_unlock(int32_t chan, bool key) +{ + if (key) { + atomic_or(&int_mask, BIT(chan)); + nrfx_grtc_syscounter_cc_int_enable(chan); + } +} + +static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context) +{ + ARG_UNUSED(id); + ARG_UNUSED(p_context); + uint64_t dticks; + uint64_t now = counter(); + + if (unlikely(now < cc_val)) { + return; + } + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + /* protection is not needed because we are in the GRTC interrupt + * so it won't get preempted by the interrupt. + */ + system_timeout_set(CYC_PER_TICK); + } + + dticks = counter_sub(now, last_count) / CYC_PER_TICK; + + last_count += dticks * CYC_PER_TICK; + sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? (int32_t)dticks : (dticks > 0)); +} + +int32_t z_nrf_grtc_timer_chan_alloc(void) +{ + uint8_t chan; + nrfx_err_t err_code; + + /* Prevent allocating all available channels - one must be left for system purposes. */ + if (ext_channels_allocated >= EXT_CHAN_COUNT) { + return -ENOMEM; + } + err_code = nrfx_grtc_channel_alloc(&chan); + if (err_code != NRFX_SUCCESS) { + return -ENOMEM; + } + ext_channels_allocated++; + return (int32_t)chan; +} + +void z_nrf_grtc_timer_chan_free(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + nrfx_err_t err_code = nrfx_grtc_channel_free(chan); + + if (err_code == NRFX_SUCCESS) { + ext_channels_allocated--; + } +} + +bool z_nrf_grtc_timer_compare_evt_check(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + uint32_t event_address = nrfx_grtc_event_compare_address_get(chan); + + return *(volatile uint32_t *)event_address != 0; +} + +uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return nrfx_grtc_event_compare_address_get(chan); +} + +uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return nrfx_grtc_capture_task_address_get(chan); +} + +uint64_t z_nrf_grtc_timer_read(void) +{ + return counter(); +} + +bool z_nrf_grtc_timer_compare_int_lock(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return compare_int_lock(chan); +} + +void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + compare_int_unlock(chan, key); +} + +uint64_t z_nrf_grtc_timer_compare_read(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return get_comparator(chan); +} + +static int compare_set_nolocks(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + nrfx_err_t result; + + __ASSERT_NO_MSG(target_time < COUNTER_SPAN); + nrfx_grtc_channel_t user_channel_data = { + .handler = handler, + .p_context = user_data, + .channel = chan, + }; + result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, target_time, true); + if (result != NRFX_SUCCESS) { + return -EPERM; + } + return 0; +} + +static int compare_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + bool key = compare_int_lock(chan); + int ret = compare_set_nolocks(chan, target_time, handler, user_data); + + compare_int_unlock(chan, key); + + return ret; +} + +int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + return compare_set(chan, target_time, (nrfx_grtc_cc_handler_t)handler, user_data); +} + +void z_nrf_grtc_timer_abort(int32_t chan) +{ + IS_CHANNEL_ALLOWED_ASSERT(chan); + + bool key = compare_int_lock(chan); + (void)nrfx_grtc_syscounter_cc_disable(chan); + compare_int_unlock(chan, key); +} + +uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t) +{ + uint64_t curr_time; + int64_t curr_tick; + int64_t result; + int64_t abs_ticks; + + curr_time = counter(); + curr_tick = sys_clock_tick_get(); + + abs_ticks = Z_TICK_ABS(t.ticks); + if (abs_ticks < 0) { + /* relative timeout */ + return (t.ticks > (int64_t)COUNTER_SPAN) ? -EINVAL : (curr_time + t.ticks); + } + + /* absolute timeout */ + result = abs_ticks - curr_tick; + + if (result > (int64_t)COUNTER_SPAN) { + return -EINVAL; + } + + return curr_time + result; +} + +int z_nrf_grtc_timer_capture_prepare(int32_t chan) +{ + nrfx_grtc_channel_t user_channel_data = { + .handler = NULL, + .p_context = NULL, + .channel = chan, + }; + nrfx_err_t result; + + IS_CHANNEL_ALLOWED_ASSERT(chan); + + /* Set the CC value to mark channel as not triggered and also to enable it + * (makes CCEN=1). COUNTER_SPAN is used so as not to fire an event unnecessarily + * - it can be assumed that such a large value will never be reached. + */ + result = nrfx_grtc_syscounter_cc_absolute_set(&user_channel_data, COUNTER_SPAN, false); + + if (result != NRFX_SUCCESS) { + return -EPERM; + } + + return 0; +} + +int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time) +{ + /* TODO: The implementation should probably go to nrfx_grtc and this + * should be just a wrapper for some nrfx_grtc_syscounter_capture_read. + */ + + uint64_t capt_time; + + IS_CHANNEL_ALLOWED_ASSERT(chan); + + /* TODO: Use `nrfy_grtc_sys_counter_enable_check` when available (NRFX-2480) */ + if (NRF_GRTC->CC[chan].CCEN == GRTC_CC_CCEN_ACTIVE_Enable) { + /* If the channel is enabled (.CCEN), it means that there was no capture + * triggering event. + */ + return -EBUSY; + } + + capt_time = nrfy_grtc_sys_counter_cc_get(NRF_GRTC, chan); + + __ASSERT_NO_MSG(capt_time < COUNTER_SPAN); + + *captured_time = capt_time; + + return 0; +} + +#if defined(CONFIG_NRF_GRTC_SLEEP_ALLOWED) +int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us) +{ + nrfx_err_t err_code; + static uint8_t systemoff_channel; + uint64_t now = counter(); + /* Minimum time that ensures valid execution of system-off procedure. */ + uint32_t minimum_latency_us = nrfy_grtc_waketime_get(NRF_GRTC) + + nrfy_grtc_timeout_get(NRF_GRTC) + + CONFIG_NRF_GRTC_SLEEP_MINIMUM_LATENCY; + uint32_t chan; + int ret; + + if (minimum_latency_us > wake_time_us) { + return -EINVAL; + } + k_spinlock_key_t key = k_spin_lock(&lock); + + err_code = nrfx_grtc_channel_alloc(&systemoff_channel); + if (err_code != NRFX_SUCCESS) { + k_spin_unlock(&lock, key); + return -ENOMEM; + } + (void)nrfx_grtc_syscounter_cc_int_disable(systemoff_channel); + ret = compare_set(systemoff_channel, now + wake_time_us, NULL, NULL); + if (ret < 0) { + k_spin_unlock(&lock, key); + return ret; + } + + for (uint32_t grtc_chan_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + grtc_chan_mask > 0; grtc_chan_mask &= ~BIT(chan)) { + /* Clear all GRTC channels except the systemoff_channel. */ + chan = u32_count_trailing_zeros(grtc_chan_mask); + if (chan != systemoff_channel) { + nrfx_grtc_syscounter_cc_disable(chan); + } + } + + /* Make sure that wake_time_us was not triggered yet. */ + if (nrfy_grtc_sys_counter_compare_event_check(NRF_GRTC, systemoff_channel)) { + k_spin_unlock(&lock, key); + return -EINVAL; + } + + /* This mechanism ensures that stored CC value is latched. */ + uint32_t wait_time = + nrfy_grtc_timeout_get(NRF_GRTC) * CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 32768 + + MAX_CC_LATCH_WAIT_TIME_US; + k_busy_wait(wait_time); +#if NRF_GRTC_HAS_CLKSEL + nrfy_grtc_clksel_set(NRF_GRTC, NRF_GRTC_CLKSEL_LFXO); +#endif + k_spin_unlock(&lock, key); + return 0; +} +#endif /* CONFIG_NRF_GRTC_SLEEP_ALLOWED */ + +uint32_t sys_clock_cycle_get_32(void) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + uint32_t ret = (uint32_t)counter(); + + k_spin_unlock(&lock, key); + return ret; +} + +uint64_t sys_clock_cycle_get_64(void) +{ + k_spinlock_key_t key = k_spin_lock(&lock); + uint64_t ret = counter(); + + k_spin_unlock(&lock, key); + return ret; +} + +uint32_t sys_clock_elapsed(void) +{ + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return 0; + } + + return (uint32_t)(counter_sub(counter(), last_count) / CYC_PER_TICK); +} + +static int sys_clock_driver_init(void) +{ + nrfx_err_t err_code; + +#if defined(CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) && \ + (defined(NRF_GRTC_HAS_CLKSEL) && (NRF_GRTC_HAS_CLKSEL == 1)) + /* Use System LFCLK as the low-frequency clock source. */ + nrfy_grtc_clksel_set(NRF_GRTC, NRF_GRTC_CLKSEL_LFCLK); +#endif + +#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) + /* SYSCOUNTER needs to be turned off before initialization. */ + nrfy_grtc_sys_counter_set(NRF_GRTC, false); + nrfy_grtc_timeout_set(NRF_GRTC, TIMEOUT); + nrfy_grtc_waketime_set(NRF_GRTC, WAKETIME); +#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + IRQ_CONNECT(DT_IRQN(GRTC_NODE), DT_IRQ(GRTC_NODE, priority), nrfx_grtc_irq_handler, 0, 0); + + err_code = nrfx_grtc_init(0); + if (err_code != NRFX_SUCCESS) { + return -EPERM; + } + +#if defined(CONFIG_NRF_GRTC_START_SYSCOUNTER) + err_code = nrfx_grtc_syscounter_start(true, &system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return err_code == NRFX_ERROR_NO_MEM ? -ENOMEM : -EPERM; + } + if (IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + nrfy_grtc_sys_counter_auto_mode_set(NRF_GRTC, false); + } +#else + err_code = nrfx_grtc_channel_alloc(&system_clock_channel_data.channel); + if (err_code != NRFX_SUCCESS) { + return -ENOMEM; + } +#endif /* CONFIG_NRF_GRTC_START_SYSCOUNTER */ + + if (!IS_ENABLED(CONFIG_NRF_GRTC_SLEEP_ALLOWED)) { + grtc_active_set(); + } + + int_mask = NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK; + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + system_timeout_set(CYC_PER_TICK); + } + +#if defined(CONFIG_CLOCK_CONTROL_NRF) + static const enum nrf_lfclk_start_mode mode = + IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) + ? CLOCK_CONTROL_NRF_LF_START_NOWAIT + : (IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) + ? CLOCK_CONTROL_NRF_LF_START_AVAILABLE + : CLOCK_CONTROL_NRF_LF_START_STABLE); + + z_nrf_clock_control_lf_on(mode); +#endif + + return 0; +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + uint64_t cyc, off, now; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + return; + } + + ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : MIN(MAX_TICKS, MAX(ticks - 1, 0)); + + now = counter(); + + /* Round up to the next tick boundary */ + off = (now - last_count) + (CYC_PER_TICK - 1); + off = (off / CYC_PER_TICK) * CYC_PER_TICK; + + /* Get the offset with respect to now */ + off -= (now - last_count); + + /* Add the offset to get to the next tick boundary */ + cyc = (uint64_t)ticks * CYC_PER_TICK + off; + + /* Due to elapsed time the calculation above might produce a + * duration that laps the counter. Don't let it. + */ + if (cyc > MAX_CYCLES) { + cyc = MAX_CYCLES; + } + + system_timeout_set(cyc == 0 ? 1 : cyc); +} + +#if defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT) +int nrf_grtc_timer_clock_driver_init(void) +{ + return sys_clock_driver_init(); +} +#else +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); +#endif 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) { diff --git a/drivers/watchdog/Kconfig.nrfx b/drivers/watchdog/Kconfig.nrfx index 52cf45dc068..2967fe86489 100644 --- a/drivers/watchdog/Kconfig.nrfx +++ b/drivers/watchdog/Kconfig.nrfx @@ -9,5 +9,9 @@ config WDT_NRFX depends on DT_HAS_NORDIC_NRF_WDT_ENABLED select NRFX_WDT0 if HAS_HW_NRF_WDT0 select NRFX_WDT1 if HAS_HW_NRF_WDT1 + select NRFX_WDT30 if HAS_HW_NRF_WDT30 + select NRFX_WDT31 if HAS_HW_NRF_WDT31 + select NRFX_WDT130 if HAS_HW_NRF_WDT130 + help Enable support for nrfx WDT driver for nRF MCU series. diff --git a/drivers/watchdog/wdt_nrfx.c b/drivers/watchdog/wdt_nrfx.c index 98fcb713b81..8967d1e162b 100644 --- a/drivers/watchdog/wdt_nrfx.c +++ b/drivers/watchdog/wdt_nrfx.c @@ -145,8 +145,12 @@ static const struct wdt_driver_api wdt_nrfx_driver_api = { .feed = wdt_nrf_feed, }; -static void wdt_event_handler(const struct device *dev, uint32_t requests) +static void wdt_event_handler(const struct device *dev, nrf_wdt_event_t event_type, + uint32_t requests, void *p_context) { + (void)event_type; + (void)p_context; + struct wdt_nrfx_data *data = dev->data; while (requests) { @@ -162,9 +166,12 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) #define WDT(idx) DT_NODELABEL(wdt##idx) #define WDT_NRFX_WDT_DEVICE(idx) \ - static void wdt_##idx##_event_handler(uint32_t requests) \ + static void wdt_##idx##_event_handler(nrf_wdt_event_t event_type, \ + uint32_t requests, \ + void *p_context) \ { \ - wdt_event_handler(DEVICE_DT_GET(WDT(idx)), requests); \ + wdt_event_handler(DEVICE_DT_GET(WDT(idx)), event_type, \ + requests, p_context); \ } \ static int wdt_##idx##_init(const struct device *dev) \ { \ @@ -174,7 +181,8 @@ static void wdt_event_handler(const struct device *dev, uint32_t requests) nrfx_isr, nrfx_wdt_##idx##_irq_handler, 0); \ err_code = nrfx_wdt_init(&config->wdt, \ NULL, \ - wdt_##idx##_event_handler); \ + wdt_##idx##_event_handler, \ + NULL); \ if (err_code != NRFX_SUCCESS) { \ return -EBUSY; \ } \ @@ -202,3 +210,15 @@ WDT_NRFX_WDT_DEVICE(0); #ifdef CONFIG_HAS_HW_NRF_WDT1 WDT_NRFX_WDT_DEVICE(1); #endif + +#ifdef CONFIG_HAS_HW_NRF_WDT30 +WDT_NRFX_WDT_DEVICE(30); +#endif + +#ifdef CONFIG_HAS_HW_NRF_WDT31 +WDT_NRFX_WDT_DEVICE(31); +#endif + +#ifdef CONFIG_HAS_HW_NRF_WDT130 +WDT_NRFX_WDT_DEVICE(130); +#endif diff --git a/dts/arm/nordic/nrf51822.dtsi b/dts/arm/nordic/nrf51822.dtsi index 222ccd4854c..b64de1d4985 100644 --- a/dts/arm/nordic/nrf51822.dtsi +++ b/dts/arm/nordic/nrf51822.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -24,6 +24,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -131,11 +132,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 NRF_DEFAULT_IRQ_PRIORITY>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -316,6 +318,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; diff --git a/dts/arm/nordic/nrf52805.dtsi b/dts/arm/nordic/nrf52805.dtsi index dd7845588e7..c5a184d5e28 100644 --- a/dts/arm/nordic/nrf52805.dtsi +++ b/dts/arm/nordic/nrf52805.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -28,6 +28,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -132,11 +133,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -311,6 +313,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -318,3 +321,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52810.dtsi b/dts/arm/nordic/nrf52810.dtsi index 82f5afb99f6..1ca4a9ea378 100644 --- a/dts/arm/nordic/nrf52810.dtsi +++ b/dts/arm/nordic/nrf52810.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -136,11 +137,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -337,6 +339,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -344,3 +347,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52811.dtsi b/dts/arm/nordic/nrf52811.dtsi index 9e03d5edb32..63b85676587 100644 --- a/dts/arm/nordic/nrf52811.dtsi +++ b/dts/arm/nordic/nrf52811.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -36,6 +36,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -167,11 +168,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -372,6 +374,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -379,3 +382,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52820.dtsi b/dts/arm/nordic/nrf52820.dtsi index 71ff85afbeb..f93e449b0b2 100644 --- a/dts/arm/nordic/nrf52820.dtsi +++ b/dts/arm/nordic/nrf52820.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { @@ -37,6 +37,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -180,11 +181,12 @@ status = "disabled"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; timer0: timer@40008000 { @@ -389,6 +391,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -396,3 +399,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52832.dtsi b/dts/arm/nordic/nrf52832.dtsi index 69de3aa591a..ed5a21b9935 100644 --- a/dts/arm/nordic/nrf52832.dtsi +++ b/dts/arm/nordic/nrf52832.dtsi @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -179,11 +180,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -465,6 +467,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; }; }; @@ -472,3 +475,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52833.dtsi b/dts/arm/nordic/nrf52833.dtsi index 8003649385c..5ac9cb2d2f8 100644 --- a/dts/arm/nordic/nrf52833.dtsi +++ b/dts/arm/nordic/nrf52833.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -36,6 +36,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -186,11 +187,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -521,6 +523,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@50000300 { @@ -532,6 +535,7 @@ ngpios = <10>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; }; }; @@ -539,3 +543,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 24710e8e0ff..8efe49a3c91 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include -#include "nrf_common.dtsi" +#include / { chosen { - zephyr,entropy = &rng; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -32,6 +32,7 @@ ficr: ficr@10000000 { compatible = "nordic,nrf-ficr"; reg = <0x10000000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -181,11 +182,12 @@ status = "okay"; }; - gpiote: gpiote@40006000 { + gpiote: gpiote0: gpiote@40006000 { compatible = "nordic,nrf-gpiote"; reg = <0x40006000 0x1000>; interrupts = <6 5>; status = "disabled"; + instance = <0>; }; adc: adc@40007000 { @@ -525,6 +527,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@50000300 { @@ -536,6 +539,7 @@ ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; cryptocell: crypto@5002a000 { @@ -543,7 +547,7 @@ reg = <0x5002a000 0x1000>, <0x5002b000 0x1000>; reg-names = "wrapper", "core"; interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; }; @@ -551,3 +555,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 77762990e13..d48f0ce62dc 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -33,7 +33,7 @@ }; chosen { - zephyr,entropy = &rng_hci; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; @@ -41,6 +41,7 @@ ficr: ficr@ff0000 { compatible = "nordic,nrf-ficr"; reg = <0xff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -84,6 +85,16 @@ reg = <0x5000d000 0x1000>; interrupts = <13 5>; status = "disabled"; + instance = <0>; + }; + + /* Additional Non-Secure GPIOTE instance */ + gpiote1: gpiote@4002f000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x4002f000 0x1000>; + interrupts = <47 5>; + status = "disabled"; + instance = <1>; }; cryptocell: crypto@50844000 { @@ -91,7 +102,7 @@ reg = <0x50844000 0x1000>, <0x50845000 0x1000>; reg-names = "wrapper", "core"; interrupts = <68 NRF_DEFAULT_IRQ_PRIORITY>; - status = "disabled"; + status = "okay"; }; }; @@ -105,9 +116,7 @@ arm,num-irq-priority-bits = <3>; }; -/* - * Include the non-secure peripherals file here since - * it expects to be at the root level. This provides - * a node for GPIOTE1. - */ -#include "nrf5340_cpuapp_peripherals_ns.dtsi" +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi index e7aa0309f70..afb839fcef4 100644 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi @@ -526,6 +526,7 @@ gpio0: gpio@842500 { #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@842800 { @@ -536,6 +537,7 @@ gpio1: gpio@842800 { ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; ieee802154: ieee802154 { diff --git a/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi b/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi deleted file mode 100644 index 5cfe561e613..00000000000 --- a/dts/arm/nordic/nrf5340_cpuapp_peripherals_ns.dtsi +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2019 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * GPIOTE1 is always accessible as a non-secure peripheral. - */ - -/ { - soc { - gpiote1: gpiote@4002f000 { - compatible = "nordic,nrf-gpiote"; - reg = <0x4002f000 0x1000>; - interrupts = <47 5>; - status = "disabled"; - }; - }; -}; diff --git a/dts/arm/nordic/nrf5340_cpuappns.dtsi b/dts/arm/nordic/nrf5340_cpuappns.dtsi index b5278745e5d..6df1be54b34 100644 --- a/dts/arm/nordic/nrf5340_cpuappns.dtsi +++ b/dts/arm/nordic/nrf5340_cpuappns.dtsi @@ -7,7 +7,7 @@ /* .dtsi header for nRF5340 CPUAPP (Application MCU), Non-Secure domain */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -48,6 +48,19 @@ */ #include "nrf5340_cpuapp_peripherals.dtsi" }; + + /* + * GPIOTE1 is always accessible as a non-secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote1: gpiote@4002f000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x4002f000 0x1000>; + interrupts = <47 5>; + status = "disabled"; + instance = <1>; + }; }; /* Default IPC description */ @@ -65,11 +78,7 @@ arm,num-irq-priority-bits = <3>; }; -/* - * Include the non-secure peripherals file here since - * it expects to be at the root level, adding a 'gpiote' label - * for the GPIOTE1 peripheral defined in that file which is - * always accessible as a non-secure peripheral. - */ -#include "nrf5340_cpuapp_peripherals_ns.dtsi" -gpiote: &gpiote1 {}; +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf5340_cpunet.dtsi b/dts/arm/nordic/nrf5340_cpunet.dtsi index 63c7e920f81..8a95b3e9985 100644 --- a/dts/arm/nordic/nrf5340_cpunet.dtsi +++ b/dts/arm/nordic/nrf5340_cpunet.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { chosen { @@ -35,6 +35,7 @@ ficr: ficr@1ff0000 { compatible = "nordic,nrf-ficr"; reg = <0x01ff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -108,11 +109,12 @@ status = "okay"; }; - gpiote: gpiote@4100a000 { + gpiote: gpiote0: gpiote@4100a000 { compatible = "nordic,nrf-gpiote"; reg = <0x4100a000 0x1000>; interrupts = <10 5>; status = "disabled"; + instance = <0>; }; wdt: wdt0: watchdog@4100b000 { @@ -192,6 +194,7 @@ reg = <0x41013000 0x1000>; clock-frequency = ; interrupts = <19 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; status = "disabled"; }; @@ -317,6 +320,7 @@ #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; gpio1: gpio@418c0800 { @@ -327,6 +331,7 @@ ngpios = <16>; status = "disabled"; port = <1>; + gpiote-instance = <&gpiote>; }; }; @@ -346,3 +351,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi b/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi new file mode 100644 index 00000000000..7252b3d5a04 --- /dev/null +++ b/dts/arm/nordic/nrf54h20_enga_cpuapp.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuapp {}; +systick: &cpuapp_systick {}; +nvic: &cpuapp_nvic {}; +cpuppr_vevif: &cpuppr_vevif_remote {}; + +/delete-node/ &cpuppr; +/delete-node/ &cpurad; +/delete-node/ &cpurad_peripherals; +/delete-node/ &cpurad_ppb; +/delete-node/ &cpurad_ram0; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuapp_nvic>; + ranges; + }; +}; + +&cpuapp_ppb { + compatible = "simple-bus"; + ranges; +}; + +&cpusec_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&cpuapp_bellboard { + compatible = "nordic,nrf-bellboard-local"; +}; + +&cpurad_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&gpiote130 { + interrupts = <105 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi b/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi new file mode 100644 index 00000000000..d2aaa790349 --- /dev/null +++ b/dts/arm/nordic/nrf54h20_enga_cpurad.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpurad {}; +systick: &cpurad_systick {}; +nvic: &cpurad_nvic {}; +cpuppr_vevif: &cpuppr_vevif_remote {}; + +/delete-node/ &cpuapp; +/delete-node/ &cpuapp_peripherals; +/delete-node/ &cpuapp_ppb; +/delete-node/ &cpuapp_ram0; +/delete-node/ &cpuppr; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpurad_nvic>; + ranges; + }; +}; + +&cpurad_ppb { + compatible = "simple-bus"; + ranges; +}; + +&cpusec_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&cpuapp_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&cpurad_bellboard { + compatible = "nordic,nrf-bellboard-local"; +}; + +&gpiote130 { + interrupts = <105 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/dts/arm/nordic/nrf54l15_cpuapp.dtsi b/dts/arm/nordic/nrf54l15_cpuapp.dtsi new file mode 100644 index 00000000000..df4ccc52294 --- /dev/null +++ b/dts/arm/nordic/nrf54l15_cpuapp.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu: cpu@0 { + clock-frequency = ; + device_type = "cpu"; + compatible = "arm,cortex-m33f"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + itm: itm@e0000000 { + compatible = "arm,armv8m-itm"; + reg = <0xe0000000 0x1000>; + swo-ref-frequency = ; + }; + }; + }; + + clocks { + lfxo: lfxo { + compatible = "nordic,nrf-lfxo"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + hfxo: hfxo { + compatible = "nordic,nrf-hfxo"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + soc { + uicr: uicr@ffd000 { + compatible = "nordic,nrf-uicr"; + reg = <0xffd000 0x1000>; + }; + + ficr: ficr@ffc000 { + compatible = "nordic,nrf-ficr"; + reg = <0xffc000 0x1000>; + #nordic,ficr-cells = <1>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(256)>; + }; + + peripheral@50000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x50000000 0x10000000>; + + /* Common nRF54L15 peripheral description */ + #include "nrf54l15_cpuapp_peripherals.dtsi" + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <3>; +}; + +&rram_controller { + rram0: rram@0 { + /* + * "1524 KB non-volatile memory (RRAM) and 256 KB RAM" + * -- Product Specification + * NB: 1524 = 1.5 * 1024 - 12 + */ + reg = <0x0 DT_SIZE_K(1524)>; + }; +}; + +/* Disable by default to use GRTC */ +&systick { + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi b/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi new file mode 100644 index 00000000000..485d85829a4 --- /dev/null +++ b/dts/arm/nordic/nrf54l15_cpuapp_peripherals.dtsi @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +dppic00: dppic@42000 { + compatible = "nordic,nrf-dppic"; + reg = <0x42000 0x808>; + status = "disabled"; +}; + +spi00: spi@4a000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4a000 0x1000>; + interrupts = <74 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart00: uart@4a000 { + compatible = "nordic,nrf-uarte"; + reg = <0x4a000 0x1000>; + interrupts = <74 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +gpio2: gpio@50400 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0x50400 0x300>; + #gpio-cells = <2>; + ngpios = <11>; + status = "disabled"; + port = <2>; +}; + +timer00: timer@55000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0x55000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <85 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +dppic10: dppic@82000 { + compatible = "nordic,nrf-dppic"; + reg = <0x82000 0x808>; + status = "disabled"; +}; + +timer10: timer@85000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0x85000 0x1000>; + cc-num = <8>; + max-bit-width = <32>; + interrupts = <133 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +egu10: egu@87000 { + compatible = "nordic,nrf-egu"; + reg = <0x87000 0x1000>; + interrupts = <135 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +radio: radio@8a000 { + compatible = "nordic,nrf-radio"; + reg = <0x8a000 0x1000>; + interrupts = <138 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + dfe-supported; + ieee802154-supported; + ble-2mbps-supported; + ble-coded-phy-supported; + + ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; +}; + +dppic20: dppic@c2000 { + compatible = "nordic,nrf-dppic"; + reg = <0xc2000 0x808>; + status = "disabled"; +}; + +i2c20: i2c@c6000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc6000 0x1000>; + clock-frequency = ; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +spi20: spi@c6000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart20: uart@c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc6000 0x1000>; + interrupts = <198 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +i2c21: i2c@c7000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc7000 0x1000>; + clock-frequency = ; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +spi21: spi@c7000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart21: uart@c7000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc7000 0x1000>; + interrupts = <199 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +i2c22: i2c@c8000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc8000 0x1000>; + clock-frequency = ; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +spi22: spi@c8000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart22: uart@c8000 { + compatible = "nordic,nrf-uarte"; + reg = <0xc8000 0x1000>; + interrupts = <200 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +egu20: egu@c9000 { + compatible = "nordic,nrf-egu"; + reg = <0xc9000 0x1000>; + interrupts = <201 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +timer20: timer@ca000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xca000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <202 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +timer21: timer@cb000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcb000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <203 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +timer22: timer@cc000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcc000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <204 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +timer23: timer@cd000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xcd000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <205 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +timer24: timer@ce000 { + compatible = "nordic,nrf-timer"; + status = "disabled"; + reg = <0xce000 0x1000>; + cc-num = <6>; + max-bit-width = <32>; + interrupts = <206 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <0>; +}; + +adc: adc@d5000 { + compatible = "nordic,nrf-saadc"; + reg = <0xd5000 0x1000>; + interrupts = <213 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + #io-channel-cells = <1>; +}; + +nfct: nfct@d6000 { + compatible = "nordic,nrf-nfct"; + reg = <0xd6000 0x1000>; + interrupts = <214 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +temp: temp@d7000 { + compatible = "nordic,nrf-temp"; + reg = <0xd7000 0x1000>; + interrupts = <215 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +gpio1: gpio@d8200 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0xd8200 0x300>; + #gpio-cells = <2>; + ngpios = <16>; + status = "disabled"; + port = <1>; + gpiote-instance = <&gpiote20>; +}; + +gpiote20: gpiote@da000 { + compatible = "nordic,nrf-gpiote"; + reg = <0xda000 0x1000>; + interrupts = <219 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + instance = <20>; +}; + +i2s20: i2s@dd000 { + compatible = "nordic,nrf-i2s"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0xdd000 0x1000>; + interrupts = <221 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +qdec20: qdec@e0000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe0000 0x1000>; + interrupts = <224 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +qdec21: qdec@e1000 { + compatible = "nordic,nrf-qdec"; + reg = <0xe1000 0x1000>; + interrupts = <225 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +grtc: grtc@e2000 { + compatible = "nordic,nrf-grtc"; + reg = <0xe2000 0x1000>; + cc-num = <12>; + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + interrupts = <228 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +dppic30: dppic@102000 { + compatible = "nordic,nrf-dppic"; + reg = <0x102000 0x808>; + status = "disabled"; +}; + +i2c30: i2c@104000 { + compatible = "nordic,nrf-twim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x104000 0x1000>; + clock-frequency = ; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +spi30: spi@104000 { + /* + * This spi node can be either SPIM or SPIS, + * for the user to pick: + * compatible = "nordic,nrf-spim" or + * "nordic,nrf-spis". + */ + compatible = "nordic,nrf-spim"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + easydma-maxcnt-bits = <16>; + status = "disabled"; +}; + +uart30: uart@104000 { + compatible = "nordic,nrf-uarte"; + reg = <0x104000 0x1000>; + interrupts = <260 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +wdt30: watchdog@108000 { + compatible = "nordic,nrf-wdt"; + reg = <0x108000 0x620>; + interrupts = <264 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +wdt31: watchdog@109000 { + compatible = "nordic,nrf-wdt"; + reg = <0x109000 0x620>; + interrupts = <265 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; + +gpio0: gpio@10a000 { + compatible = "nordic,nrf-gpio"; + gpio-controller; + reg = <0x10a000 0x300>; + #gpio-cells = <2>; + ngpios = <5>; + status = "disabled"; + port = <0>; + gpiote-instance = <&gpiote30>; +}; + +gpiote30: gpiote@10c000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x10c000 0x1000>; + interrupts = <269 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + instance = <30>; +}; + +clock: clock@10e000 { + compatible = "nordic,nrf-clock"; + reg = <0x10e000 0x1000>; + interrupts = <270 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf54l_common.dtsi b/dts/arm/nordic/nrf54l_common.dtsi new file mode 100644 index 00000000000..3214daeac84 --- /dev/null +++ b/dts/arm/nordic/nrf54l_common.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + soc { + rram_controller: rram-controller@5004b000 { + compatible = "nordic,rram-controller"; + reg = <0x5004b000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + interrupts = <75 NRF_DEFAULT_IRQ_PRIORITY>; + rram0: rram@0 { + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <1>; + }; + }; + }; + + chosen { + zephyr,flash-controller = &rram_controller; + zephyr,entropy = &psa_rng; + }; + + psa_rng: psa-rng { + compatible = "zephyr,psa-crypto-rng"; + status = "okay"; + }; + + sw_pwm: sw-pwm { + generator = <&timer21>; + }; +}; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index 46024011166..e65ce04a004 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -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 { @@ -60,11 +61,26 @@ status = "okay"; }; - gpiote: gpiote@5000d000 { + /* + * GPIOTE0 is always accessible as a secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote0: gpiote@5000d000 { compatible = "nordic,nrf-gpiote"; reg = <0x5000d000 0x1000>; interrupts = <13 5>; status = "disabled"; + instance = <0>; + }; + + /* Additional Non-Secure GPIOTE instance */ + gpiote1: gpiote@40031000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x40031000 0x1000>; + interrupts = <49 5>; + status = "disabled"; + instance = <1>; }; spu: spu@50003000 { @@ -77,6 +93,7 @@ ficr: ficr@ff0000 { compatible = "nordic,nrf-ficr"; reg = <0xff0000 0x1000>; + #nordic,ficr-cells = <1>; status = "okay"; }; @@ -91,3 +108,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/arm/nordic/nrf9151_laca.dtsi b/dts/arm/nordic/nrf9151_laca.dtsi new file mode 100644 index 00000000000..9ed20274017 --- /dev/null +++ b/dts/arm/nordic/nrf9151_laca.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +/ { + soc { + compatible = "nordic,nrf9151-laca", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; + }; +}; diff --git a/dts/arm/nordic/nrf9151ns_laca.dtsi b/dts/arm/nordic/nrf9151ns_laca.dtsi new file mode 100644 index 00000000000..ac31c6e19c6 --- /dev/null +++ b/dts/arm/nordic/nrf9151ns_laca.dtsi @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&flash0 { + reg = <0x00000000 DT_SIZE_K(1024)>; +}; + +&sram0 { + reg = <0x20000000 DT_SIZE_K(256)>; +}; + +/ { + soc { + compatible = "nordic,nrf9151-laca", "nordic,nrf9120", + "nordic,nrf91", "simple-bus"; + }; +}; diff --git a/dts/arm/nordic/nrf91_peripherals.dtsi b/dts/arm/nordic/nrf91_peripherals.dtsi index 2e437eb082d..12e61743bfe 100644 --- a/dts/arm/nordic/nrf91_peripherals.dtsi +++ b/dts/arm/nordic/nrf91_peripherals.dtsi @@ -313,6 +313,7 @@ gpio0: gpio@842500 { #gpio-cells = <2>; status = "disabled"; port = <0>; + gpiote-instance = <&gpiote>; }; rtc0: rtc@14000 { diff --git a/dts/arm/nordic/nrf91ns.dtsi b/dts/arm/nordic/nrf91ns.dtsi index 910f45ec706..c692873981b 100644 --- a/dts/arm/nordic/nrf91ns.dtsi +++ b/dts/arm/nordic/nrf91ns.dtsi @@ -5,7 +5,7 @@ */ #include -#include "nrf_common.dtsi" +#include / { cpus { @@ -46,12 +46,17 @@ #include "nrf91_peripherals.dtsi" }; - /* Additional Non-Secure peripherals */ - gpiote: gpiote@40031000 { + /* + * GPIOTE1 is always accessible as a non-secure peripheral, + * so we give it the 'gpiote' label for use when building + * code for this target. + */ + gpiote: gpiote1: gpiote@40031000 { compatible = "nordic,nrf-gpiote"; reg = <0x40031000 0x1000>; interrupts = <49 5>; status = "disabled"; + instance = <1>; }; }; @@ -64,3 +69,8 @@ &nvic { arm,num-irq-priority-bits = <3>; }; + +&systick { + /* Use RTC for system clock, instead of SysTick. */ + status = "disabled"; +}; diff --git a/dts/bindings/arm/nordic,nrf-uicr-v2.yaml b/dts/bindings/arm/nordic,nrf-uicr-v2.yaml new file mode 100644 index 00000000000..f509fdf4061 --- /dev/null +++ b/dts/bindings/arm/nordic,nrf-uicr-v2.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic UICR v2 (User Information Configuration Registers) + +compatible: "nordic,nrf-uicr-v2" + +include: base.yaml + +properties: + reg: + required: true + + domain: + type: int + required: true + description: | + Domain ID of the domain associated with this UICR instance. Must be unique + across all UICR instances in the system. + + ptr-ext-uicr: + type: phandle + required: true + description: | + Handle of a memory region reserved to contain an Extended UICR instance. + The address of that node will be stored in the UICR.PTREXTUICR register. diff --git a/dts/bindings/base/mutable.yaml b/dts/bindings/base/mutable.yaml new file mode 100644 index 00000000000..0e2d1cad3b0 --- /dev/null +++ b/dts/bindings/base/mutable.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +# Properties for Mutable devices + +properties: + zephyr,mutable: + type: boolean + description: | + True iff the device structure may be mutated. + + Inherit this binding for devices that are runtime-modifiable, in-place. + This places the device structure into SRAM rather than Flash. diff --git a/dts/bindings/clock/nordic,nrf-hfxo.yaml b/dts/bindings/clock/nordic,nrf-hfxo.yaml new file mode 100644 index 00000000000..cd82e1c34d3 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hfxo.yaml @@ -0,0 +1,82 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF high-frequency crystal oscillator + +compatible: "nordic,nrf-hfxo" + +include: fixed-clock.yaml + +properties: + clock-frequency: + const: 32000000 + + load-capacitors: + type: string + enum: + - "internal" + - "external" + description: | + Type of load capacitors connected to the crystal. If not specified, + adjustments may still happen when the device trimming happens during + system initialization. + + load-capacitance-femtofarad: + type: int + enum: + - 4000 + - 4250 + - 4500 + - 4750 + - 5000 + - 5250 + - 5500 + - 5750 + - 6000 + - 6250 + - 6500 + - 6750 + - 7000 + - 7250 + - 7500 + - 7750 + - 8000 + - 8250 + - 8500 + - 8750 + - 9000 + - 9250 + - 9500 + - 9750 + - 10000 + - 10250 + - 10500 + - 10750 + - 11000 + - 11250 + - 11500 + - 11750 + - 12000 + - 12250 + - 12500 + - 12750 + - 13000 + - 13250 + - 13500 + - 13750 + - 14000 + - 14250 + - 14500 + - 14750 + - 15000 + - 15250 + - 15500 + - 15750 + - 16000 + - 16250 + - 16500 + - 16750 + - 17000 + description: | + Load capacitance in femtofarads. This property is only used when + load-capacitors is set to "internal". diff --git a/dts/bindings/clock/nordic,nrf-hsfll.yaml b/dts/bindings/clock/nordic,nrf-hsfll.yaml new file mode 100644 index 00000000000..3614d80870f --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-hsfll.yaml @@ -0,0 +1,65 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF HSFLL + + The HSFLL mixed-mode IP generates several clock frequencies in the range from + 64 MHz to 400 MHz (in steps of 16 MHz). + + Usage example: + + hsfll: clock@deadbeef { + compatible = "nordic,nrf-hsfll"; + reg = <0xdeadbeef 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + + Required FICR entries are for VSUP, COARSE and FINE trim values. + +compatible: "nordic,nrf-hsfll" + +include: [base.yaml, fixed-clock.yaml, nordic-nrf-ficr-client.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + clock-frequency: + enum: + - 64000000 + - 80000000 + - 96000000 + - 112000000 + - 128000000 + - 144000000 + - 160000000 + - 176000000 + - 192000000 + - 208000000 + - 224000000 + - 240000000 + - 256000000 + - 272000000 + - 288000000 + - 304000000 + - 320000000 + - 336000000 + - 352000000 + - 368000000 + - 384000000 + - 400000000 + + nordic,ficrs: + required: true + + nordic,ficr-names: + required: true diff --git a/dts/bindings/clock/nordic,nrf-lfxo.yaml b/dts/bindings/clock/nordic,nrf-lfxo.yaml new file mode 100644 index 00000000000..328c374769c --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-lfxo.yaml @@ -0,0 +1,58 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF low-frequency crystal oscillator + +compatible: "nordic,nrf-lfxo" + +include: fixed-clock.yaml + +properties: + clock-frequency: + const: 32768 + + load-capacitors: + type: string + enum: + - "internal" + - "external" + description: | + Type of load capacitors connected to the crystal. If not specified, + adjustments may still happen when the device trimming happens during + system initialization. + + load-capacitance-femtofarad: + type: int + enum: + - 4000 + - 4500 + - 5000 + - 5500 + - 6000 + - 6500 + - 7000 + - 7500 + - 8000 + - 8500 + - 9000 + - 9500 + - 10000 + - 10500 + - 11000 + - 11500 + - 12000 + - 12500 + - 13000 + - 13500 + - 14000 + - 14500 + - 15000 + - 15500 + - 16000 + - 16500 + - 17000 + - 17500 + - 18000 + description: | + Load capacitance in femtofarads. This property is only used when + load-capacitors is set to "internal". diff --git a/dts/bindings/cpu/nordic,vpr.yaml b/dts/bindings/cpu/nordic,vpr.yaml new file mode 100644 index 00000000000..11146f89c51 --- /dev/null +++ b/dts/bindings/cpu/nordic,vpr.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic Semiconductor RISC-V VPR CPU + +compatible: "nordic,vpr" + +include: riscv,cpus.yaml + +properties: + nordic,bus-width: + type: int + enum: + - 32 + - 64 + required: true + description: + Bus width of the CPU. diff --git a/dts/bindings/cpu/nuclei,bumblebee.yaml b/dts/bindings/cpu/nuclei,bumblebee.yaml index 8c9dfc7d35d..96eebcd0fb8 100644 --- a/dts/bindings/cpu/nuclei,bumblebee.yaml +++ b/dts/bindings/cpu/nuclei,bumblebee.yaml @@ -6,9 +6,3 @@ description: Nuclei Bumblebee RISC-V Core compatible: "nuclei,bumblebee" include: riscv,cpus.yaml - -properties: - mcause-exception-mask: - type: int - required: true - description: Specify the bits to use for exception code in mcause register. diff --git a/dts/bindings/flash_controller/nordic,rram-controller.yaml b/dts/bindings/flash_controller/nordic,rram-controller.yaml new file mode 100644 index 00000000000..be764127f09 --- /dev/null +++ b/dts/bindings/flash_controller/nordic,rram-controller.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-4-Clause +# + +description: | + Nordic RRAMC (Resistive random access memory controller) + + The resistive random access memory controller (RRAMC) is used for writing + the internal RRAM memory, the secure information configuration registers (SICR), + and the user information configuration registers (UICR). + +compatible: "nordic,rram-controller" + +include: base.yaml diff --git a/dts/bindings/gnss/gnss-nmea-generic.yaml b/dts/bindings/gnss/gnss-nmea-generic.yaml new file mode 100644 index 00000000000..a3887995e10 --- /dev/null +++ b/dts/bindings/gnss/gnss-nmea-generic.yaml @@ -0,0 +1,22 @@ +# Copyright 2023 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +description: | + Generic GNSS NMEA receiver + + Implement a generic NMEA based GNSS device. + + Example configuration: + + &uart0 { + current-speed = <9600>; + ... + gnss: gnss-nmea-generic { + compatible = "gnss-nmea-generic"; + }; + }; + +compatible: "gnss-nmea-generic" + +include: + - uart-device.yaml diff --git a/dts/bindings/gpio/nordic,nrf-gpio.yaml b/dts/bindings/gpio/nordic,nrf-gpio.yaml index 550acd1a865..097a99d8fa9 100644 --- a/dts/bindings/gpio/nordic,nrf-gpio.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpio.yaml @@ -11,6 +11,11 @@ properties: reg: required: true + gpiote-instance: + type: phandle + description: | + GPIOTE instance that can be used with this GPIO port. + "#gpio-cells": const: 2 diff --git a/dts/bindings/gpio/nordic,nrf-gpiote.yaml b/dts/bindings/gpio/nordic,nrf-gpiote.yaml index 49ddba3595b..4bb09574e9b 100644 --- a/dts/bindings/gpio/nordic,nrf-gpiote.yaml +++ b/dts/bindings/gpio/nordic,nrf-gpiote.yaml @@ -5,7 +5,9 @@ description: NRF5 GPIOTE node compatible: "nordic,nrf-gpiote" -include: base.yaml +include: + - base.yaml + - nordic,split-channels.yaml properties: reg: @@ -13,3 +15,15 @@ properties: interrupts: required: true + + instance: + type: int + required: true + description: | + The GPIOTE instance number. GPIOTE instance GPIOTE0 has: + + instance = <0>; + + And GPIOTE1 has: + + instance = <1>; diff --git a/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml b/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml new file mode 100644 index 00000000000..f570e668ea5 --- /dev/null +++ b/dts/bindings/interrupt-controller/nordic,nrf-clic.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic VPR CLIC + +compatible: "nordic,nrf-clic" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/mbox/nordic,nrf-bellboard-common.yaml b/dts/bindings/mbox/nordic,nrf-bellboard-common.yaml new file mode 100644 index 00000000000..0d1d0bc26e2 --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-bellboard-common.yaml @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include: [base.yaml, "mailbox-controller.yaml"] + +properties: + reg: + required: true + +mbox-cells: + - channel diff --git a/dts/bindings/mbox/nordic,nrf-bellboard-local.yaml b/dts/bindings/mbox/nordic,nrf-bellboard-local.yaml new file mode 100644 index 00000000000..5c1709987cc --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-bellboard-local.yaml @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic BELLBOARD + + BELLBOARD provides support for inter-domain software signaling. It implements + a set of tasks and events intended for signaling within an interprocessor + communication (IPC) framework. When used in local mode, the BELLBOARD + instance is used to receive events triggered by other remote cores. + + Example definition: + + bellboard: mailbox@deadbeef { + compatible = "nordic,nrf-bellboard-local"; + reg = <0xdeadbeef 0x1000>; + interrupts = <98 NRF_DEFAULT_IRQ_PRIORITY>, + <99 NRF_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "irq2", "irq3"; + nordic,interrupt-mapping = <0x0000000f 2>, <0x000000f0 3>; + #mbox-cells = <1>; + }; + +compatible: "nordic,nrf-bellboard-local" + +include: "nordic,nrf-bellboard-common.yaml" + +properties: + interrupts: + required: true + + interrupt-names: + required: true + + nordic,interrupt-mapping: + type: array + required: true + description: | + Set of interrupt mapping pairs. Each pair consists of a bitmask and an + interrupt identifier. The bitmask is used to indicate which of the 32 + possible events are mapped to the given interrupt. For example, given + <0x0000000f 2>, the first four events are mapped to interrupt 2 + (irq2). diff --git a/dts/bindings/mbox/nordic,nrf-bellboard-remote.yaml b/dts/bindings/mbox/nordic,nrf-bellboard-remote.yaml new file mode 100644 index 00000000000..ae17fc916a1 --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-bellboard-remote.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic BELLBOARD + + BELLBOARD provides support for inter-domain software signaling. It implements + a set of tasks and events intended for signaling within an interprocessor + communication (IPC) framework. When used in remote mode, the BELLBOARD + instance is used to trigger events to another core. + + Example definition: + + bellboard: mailbox@deadbeef { + compatible = "nordic,nrf-bellboard-remote"; + reg = <0xdeadbeef 0x1000>; + #mbox-cells = <1>; + }; + +compatible: "nordic,nrf-bellboard-remote" + +include: "nordic,nrf-bellboard-common.yaml" diff --git a/dts/bindings/mbox/nordic,nrf-vevif-common.yaml b/dts/bindings/mbox/nordic,nrf-vevif-common.yaml new file mode 100644 index 00000000000..b7cb15457f6 --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-vevif-common.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +include: mailbox-controller.yaml + +properties: + nordic,tasks: + type: int + required: true + description: Number of tasks supported by the VEVIF instance. + + nordic,tasks-mask: + type: int + required: true + description: Mask of tasks supported by the VEVIF instance. + +mbox-cells: + - channel diff --git a/dts/bindings/mbox/nordic,nrf-vevif-local.yaml b/dts/bindings/mbox/nordic,nrf-vevif-local.yaml new file mode 100644 index 00000000000..5d23cfdcf1e --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-vevif-local.yaml @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic VEVIF (VPR Event Interface) - Local + + VEVIF is an event interface for VPR, allowing connection to the domain's DPPI + system. VEVIF can also generate IRQs to other CPUs. + + Example definition: + + cpuppr: cpu@d { + ... + cpuppr_vevif_local: mailbox { + compatible = "nordic,nrf-vevif-local"; + interrupts = <0 NRF_DEFAULT_IRQ_PRIORITY>, + <1 NRF_DEFAULT_IRQ_PRIORITY>, + ... + ; + #mbox-cells = <1>; + nordic,tasks = <16>; + nordic,tasks-mask: <0xfffffff0>; + }; + }; + +compatible: "nordic,nrf-vevif-local" + +include: [base.yaml, "nordic,nrf-vevif-common.yaml"] + +properties: + interrupts: + required: true diff --git a/dts/bindings/mbox/nordic,nrf-vevif-remote.yaml b/dts/bindings/mbox/nordic,nrf-vevif-remote.yaml new file mode 100644 index 00000000000..07522fed99d --- /dev/null +++ b/dts/bindings/mbox/nordic,nrf-vevif-remote.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic VEVIF (VPR Event Interface) - Remote + + VEVIF is an event interface for VPR, allowing connection to the domain's DPPI + system. VEVIF can also generate IRQs to other CPUs. + + Example definition: + + cpuppr_vpr: vpr@deadbeef{ + ... + cpuppr_vevif_remote: mailbox@0 { + compatible = "nordic,nrf-vevif-remote"; + reg = <0x0 0x1000>; + #mbox-cells = <1>; + nordic,tasks = <16>; + nordic,tasks-mask: <0xfffffff0>; + }; + }; + +compatible: "nordic,nrf-vevif-remote" + +include: [base.yaml, "nordic,nrf-vevif-common.yaml"] + +properties: + reg: + required: true diff --git a/dts/bindings/arm/nordic,nrf-ficr.yaml b/dts/bindings/misc/nordic,nrf-ficr.yaml similarity index 61% rename from dts/bindings/arm/nordic,nrf-ficr.yaml rename to dts/bindings/misc/nordic,nrf-ficr.yaml index bea0762573e..ca199c24f07 100644 --- a/dts/bindings/arm/nordic,nrf-ficr.yaml +++ b/dts/bindings/misc/nordic,nrf-ficr.yaml @@ -7,3 +7,11 @@ include: base.yaml properties: reg: required: true + + "#nordic,ficr-cells": + type: int + required: true + const: 1 + +nordic,ficr-cells: + - offset diff --git a/dts/bindings/misc/nordic,split-channels.yaml b/dts/bindings/misc/nordic,split-channels.yaml new file mode 100644 index 00000000000..a875dc12d7f --- /dev/null +++ b/dts/bindings/misc/nordic,split-channels.yaml @@ -0,0 +1,44 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: | + Nordic Split Channels + + Some of Nordic's peripherals support split ownership feature that allows to + be used by independent owners. As an example the configuration of the + Global Real Time Counter (GRTC) is shown below: + owned-channels = <0 1 2 3 4 5 6 7 8 9 10 11>; + child-owned-channels = <7 8 9 10 11>; + + Which means that channels 0-11 will be assigned to the particular CPU. + Other CPUs cannot use those and another set must be defined for them. + In addition, `child-owned-channels` property allows to use channels + 7-11 only by child subprocessor. If the CPU you're configuring has no + subprocessor(s) assigned, the `child-owned-channels` property + should not be defined. + +properties: + owned-channels: + type: array + description: | + List of channels in a split-ownership peripheral that are to be owned + for use by the compiled CPU. + + nonsecure-channels: + type: array + description: | + List of channels in a split-ownership, split-security peripheral that + are to be configured as nonsecure. In Trustzone systems, this property + is only evaluated for secure peripherals, as nonsecure channels are + implicitly specified through the owned-channels property. This property + is ignored in non-Trustzone systems. + + child-owned-channels: + type: array + description: | + List of channels in a split-ownership peripheral that are officially + owned by the compiled CPU but intended to be used by its child + subprocessor(s). diff --git a/dts/bindings/misc/nordic-nrf-ficr-client.yaml b/dts/bindings/misc/nordic-nrf-ficr-client.yaml new file mode 100644 index 00000000000..06a1e727f3f --- /dev/null +++ b/dts/bindings/misc/nordic-nrf-ficr-client.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +properties: + nordic,ficrs: + type: phandle-array + description: | + FICR entries, e.g. <&ficr OFFSET>. Available offsets (or FICR entries) are + available at . + + nordic,ficr-names: + type: string-array + description: | + Names of each nordic,ficrs entry. diff --git a/dts/bindings/misc/zephyr,devmux.yaml b/dts/bindings/misc/zephyr,devmux.yaml new file mode 100644 index 00000000000..744daaca120 --- /dev/null +++ b/dts/bindings/misc/zephyr,devmux.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2023, Meta +# SPDX-License-Identifier: Apache-2.0 + +description: Generic Device Multiplexer + +compatible: "zephyr,devmux" + +include: [base.yaml, mutable.yaml] + +properties: + + devices: + type: phandles + required: true + description: | + Devices to be multiplexed. + + selected: + type: int + default: 0 + description: | + Initial multiplexer selection. + + This must be in the range [0, N-1], where N is the length of the + 'devices' phandle list. + + If unspecified, the default selection is zero in order to ensure that + the multiplexer is ready for use (i.e. one of the [0, N-1] multiplexed + devices is selected). Zero is, necessarily, the only possible valid + default value since the phandle list must have length >= 1. + + Note: Specifying a value of 'selected' outside the range [0, N-1] + results in a compile-time error. diff --git a/dts/bindings/modem/nordic,nrf91-slm.yaml b/dts/bindings/modem/nordic,nrf91-slm.yaml new file mode 100644 index 00000000000..3f06696197d --- /dev/null +++ b/dts/bindings/modem/nordic,nrf91-slm.yaml @@ -0,0 +1,9 @@ +description: Nordic nRF91 series running the Serial LTE Modem application + +compatible: "nordic,nrf91-slm" + +include: uart-device.yaml + +properties: + mdm-power-gpios: + type: phandle-array diff --git a/dts/bindings/modem/u-blox,sara-r5.yaml b/dts/bindings/modem/u-blox,sara-r5.yaml new file mode 100644 index 00000000000..af6c3318fd0 --- /dev/null +++ b/dts/bindings/modem/u-blox,sara-r5.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2023 Emil Lindqvist +# SPDX-License-Identifier: Apache-2.0 + +description: u-blox SARA-R5 modem + +compatible: "u-blox,sara-r5" + +include: uart-device.yaml + +properties: + mdm-power-gpios: + type: phandle-array + + mdm-reset-gpios: + type: phandle-array diff --git a/dts/bindings/mtd/nordic,mram.yaml b/dts/bindings/mtd/nordic,mram.yaml new file mode 100644 index 00000000000..dac7d14305d --- /dev/null +++ b/dts/bindings/mtd/nordic,mram.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic MRAM + +compatible: nordic,mram + +include: soc-nv-flash.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/mtd/nordic,owned-partitions.yaml b/dts/bindings/mtd/nordic,owned-partitions.yaml new file mode 100644 index 00000000000..bf42c13346a --- /dev/null +++ b/dts/bindings/mtd/nordic,owned-partitions.yaml @@ -0,0 +1,89 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Owned Partitions + + Memory partition table with permission attributes common to its partitions. + This is a special case of the Nordic Owned Memory binding. + + Every compatible node is expected to be a child of a memory node, where the + listed partitions belong. + + A single memory node can contain multiple partition tables, each with a + different set of permissions. For each such table, the smallest memory region + spanning the contained partitions will be recorded in the UICR. These regions + are allowed to contain gaps between the partitions, but this is discouraged. + + Example: + + mram1x: mram@e000000 { + compatible = "nordic,mram"; + reg = <0xe000000 0x200000>; + ... + + rx-partitions { + compatible = "nordic,owned-partitions"; + perm-read; + perm-execute; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@c0000 { + label = "image-0"; + reg = <0xc0000 0x40000>; + }; + }; + + rw-partitions { + compatible = "nordic,owned-partitions"; + perm-read; + perm-write; + #address-cells = <1>; + #size-cells = <1>; + + slot1_partition: partition@100000 { + label = "image-1"; + reg = <0x100000 0x50000>; + }; + storage_partition: partition@150000 { + label = "storage"; + reg = <0x150000 0x6000>; + }; + }; + }; + + From this example, two memory regions will be inferred: + + - 0x0E0C0000--0x0E100000, with read & execute permissions, containing the + partition labeled "image-0". + - 0x0E100000--0x0E156000, with read & write permissions, containing the + partitions labeled "image-1" and "storage". + +compatible: "nordic,owned-partitions" + +include: + - name: nordic,owned-memory.yaml + property-blocklist: + - reg + +properties: + "#address-cells": + required: true + + "#size-cells": + required: true + +child-binding: + description: | + Partitions in the table are defined as subnodes. Each partition must have a + size and an offset relative to the base address of the parent memory node. + + include: + - name: base.yaml + property-blocklist: + - compatible + + properties: + reg: + required: true diff --git a/dts/bindings/options/openthread,config.yaml b/dts/bindings/options/openthread,config.yaml index 054107fab44..6366c289c80 100644 --- a/dts/bindings/options/openthread,config.yaml +++ b/dts/bindings/options/openthread,config.yaml @@ -10,6 +10,7 @@ description: | compatible = "openthread,config"; diag-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>, <&gpio1 0 GPIO_ACTIVE_LOW>; + bootloader-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; }; @@ -21,3 +22,9 @@ properties: description: | This enables access to diagnostic GPIO pins. Each field consists of GPIO pin's configuration: controller's phandle, pin number and configuration flags. + + bootloader-gpios: + type: phandle-array + description: | + This enables resetting to bootloader by triggering given GPIO pin. Property represents + chosen GPIO pin's configuration: controller's phandle, pin number and configuration flags. diff --git a/dts/bindings/reserved-memory/nordic,owned-memory.yaml b/dts/bindings/reserved-memory/nordic,owned-memory.yaml new file mode 100644 index 00000000000..9b13c965ac8 --- /dev/null +++ b/dts/bindings/reserved-memory/nordic,owned-memory.yaml @@ -0,0 +1,46 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic Owned Memory + + Memory region with permission attributes. Each enabled region of this kind + will be recorded in the UICR of the compiled domain. Memory ownership and + access is then configured for the domain at boot time, based on the UICR. + +compatible: "nordic,owned-memory" + +include: base.yaml + +properties: + reg: + required: true + + owner-id: + type: int + description: | + Owner ID of the domain that will own this memory region. If not defined, + the ownership will default to the domain being compiled. + + Note: owner ID is not the same as domain ID; see the product specification + for details. + + perm-read: + type: boolean + description: Owner has read access to the region. + + perm-write: + type: boolean + description: Owner has write access to the region. + + perm-execute: + type: boolean + description: Owner can execute code from the region. + + perm-secure: + type: boolean + description: Owner has secure-only access to the region. + + non-secure-callable: + type: boolean + description: Memory region is used for non-secure-callable code. diff --git a/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml b/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml new file mode 100644 index 00000000000..6be94dce25d --- /dev/null +++ b/dts/bindings/riscv/nordic,nrf-vpr-coprocessor.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +compatible: "nordic,nrf-vpr-coprocessor" + +description: | + VPR coprocessor + + VPR is a RISC-V CPU implementation. VPR instances are exposed to other CPUs as + peripherals. + +include: base.yaml + +properties: + cpu: + type: int + description: | + Processor ID of the VPR core. + + execution-memory: + type: phandle + required: true + description: | + Memory area from which the VPR core will execute. + + source-memory: + type: phandle + description: | + Memory area or partition from which the VPR code will be loaded. diff --git a/dts/bindings/timer/nordic,nrf-grtc.yaml b/dts/bindings/timer/nordic,nrf-grtc.yaml new file mode 100644 index 00000000000..e78e57df97e --- /dev/null +++ b/dts/bindings/timer/nordic,nrf-grtc.yaml @@ -0,0 +1,25 @@ +# +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: Nordic GRTC (Global RTC) + +compatible: "nordic,nrf-grtc" + +include: + - "base.yaml" + - "nordic,split-channels.yaml" + +properties: + reg: + required: true + + interrupts: + required: true + + cc-num: + description: Number of capture/compare channels + type: int + required: true diff --git a/dts/common/nordic/nrf54h20_enga.dtsi b/dts/common/nordic/nrf54h20_enga.dtsi new file mode 100644 index 00000000000..610fbd81587 --- /dev/null +++ b/dts/common/nordic/nrf54h20_enga.dtsi @@ -0,0 +1,839 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +/delete-node/ &sw_pwm; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpuapp: cpu@2 { + compatible = "arm,cortex-m33"; + reg = <2>; + device_type = "cpu"; + clock-frequency = ; + }; + + cpurad: cpu@3 { + compatible = "arm,cortex-m33"; + reg = <3>; + device_type = "cpu"; + clock-frequency = ; + }; + + cpuppr: cpu@d { + compatible = "nordic,vpr"; + reg = <13>; + device_type = "cpu"; + clock-frequency = ; + riscv,isa = "rv32emc"; + nordic,bus-width = <32>; + + cpuppr_vevif_local: mailbox { + compatible = "nordic,nrf-vevif-local"; + status = "disabled"; + interrupt-parent = <&cpuppr_clic>; + interrupts = <0 NRF_DEFAULT_IRQ_PRIORITY>, + <1 NRF_DEFAULT_IRQ_PRIORITY>, + <2 NRF_DEFAULT_IRQ_PRIORITY>, + <3 NRF_DEFAULT_IRQ_PRIORITY>, + <4 NRF_DEFAULT_IRQ_PRIORITY>, + <5 NRF_DEFAULT_IRQ_PRIORITY>, + <6 NRF_DEFAULT_IRQ_PRIORITY>, + <7 NRF_DEFAULT_IRQ_PRIORITY>, + <8 NRF_DEFAULT_IRQ_PRIORITY>, + <9 NRF_DEFAULT_IRQ_PRIORITY>, + <10 NRF_DEFAULT_IRQ_PRIORITY>, + <11 NRF_DEFAULT_IRQ_PRIORITY>, + <12 NRF_DEFAULT_IRQ_PRIORITY>, + <13 NRF_DEFAULT_IRQ_PRIORITY>, + <14 NRF_DEFAULT_IRQ_PRIORITY>, + <15 NRF_DEFAULT_IRQ_PRIORITY>; + #mbox-cells = <1>; + nordic,tasks = <16>; + nordic,tasks-mask = <0xfffffff0>; + }; + }; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + cpurad_uicr_ext: memory@e1ff000 { + reg = <0xe1ff000 DT_SIZE_K(2)>; + }; + + cpuapp_uicr_ext: memory@e1ff800 { + reg = <0xe1ff800 DT_SIZE_K(2)>; + }; + }; + + clocks { + fll16m: fll16m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = ; + }; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + mram1x: mram@e000000 { + compatible = "nordic,mram"; + reg = <0xe000000 DT_SIZE_K(2048)>; + write-block-size = <16>; + }; + + cpuapp_uicr: uicr@fff8000 { + compatible = "nordic,nrf-uicr-v2"; + reg = <0xfff8000 DT_SIZE_K(2)>; + domain = <2>; + ptr-ext-uicr = <&cpuapp_uicr_ext>; + }; + + cpurad_uicr: uicr@fffa000 { + compatible = "nordic,nrf-uicr-v2"; + reg = <0xfffa000 DT_SIZE_K(2)>; + domain = <3>; + ptr-ext-uicr = <&cpurad_uicr_ext>; + }; + + ficr: ficr@fffe000 { + compatible = "nordic,nrf-ficr"; + reg = <0xfffe000 DT_SIZE_K(2)>; + #nordic,ficr-cells = <1>; + }; + + cpuapp_ram0: sram@22000000 { + compatible = "mmio-sram"; + reg = <0x22000000 DT_SIZE_K(32)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x22000000 0x8000>; + }; + + cpurad_ram0: sram@23000000 { + compatible = "mmio-sram"; + reg = <0x23000000 DT_SIZE_K(64)>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x23000000 0x10000>; + }; + + cpuapp_peripherals: peripheral@52000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x52000000 0x1000000>; + + cpuapp_hsfll: clock@d000 { + compatible = "nordic,nrf-hsfll"; + #clock-cells = <0>; + reg = <0xd000 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + }; + + cpurad_peripherals: peripheral@53000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x53000000 0x1000000>; + + cpurad_hsfll: clock@d000 { + compatible = "nordic,nrf-hsfll"; + #clock-cells = <0>; + reg = <0xd000 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_1>, + <&ficr NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_1>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + + egu020: egu@25000 { + compatible = "nordic,nrf-egu"; + reg = <0x25000 0x1000>; + status = "disabled"; + interrupts = <37 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + timer020: timer@28000 { + compatible = "nordic,nrf-timer"; + reg = <0x28000 0x1000>; + status = "disabled"; + cc-num = <8>; + interrupts = <40 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer021: timer@29000 { + compatible = "nordic,nrf-timer"; + reg = <0x29000 0x1000>; + status = "disabled"; + cc-num = <8>; + interrupts = <41 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer022: timer@2a000 { + compatible = "nordic,nrf-timer"; + reg = <0x2a000 0x1000>; + status = "disabled"; + cc-num = <8>; + interrupts = <42 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + rtc: rtc@2b000 { + compatible = "nordic,nrf-rtc"; + reg = <0x2b000 0x1000>; + status = "disabled"; + cc-num = <4>; + clock-frequency = <32768>; + interrupts = <43 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <1>; + }; + + radio: radio@2c000 { + compatible = "nordic,nrf-radio"; + reg = <0x2c000 0x1000>; + status = "disabled"; + ble-2mbps-supported; + ble-coded-phy-supported; + dfe-supported; + ieee802154-supported; + interrupts = <44 NRF_DEFAULT_IRQ_PRIORITY>; + + cpurad_ieee802154: ieee802154 { + compatible = "nordic,nrf-ieee802154"; + status = "disabled"; + }; + }; + + ecb030: ecb@3b000 { + compatible = "nordic,nrf-ecb"; + reg = <0x3b000 0x1000>; + interrupts = <59 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + }; + + global_peripherals: peripheral@5f000000 { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x5f000000 0x1000000>; + + cpusec_bellboard: mailbox@99000 { + reg = <0x99000 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + }; + + cpuapp_bellboard: mailbox@9a000 { + reg = <0x9a000 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + }; + + cpurad_bellboard: mailbox@9b000 { + reg = <0x9b000 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + }; + + timer120: timer@8e2000 { + compatible = "nordic,nrf-timer"; + reg = <0x8e2000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <226 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer121: timer@8e3000 { + compatible = "nordic,nrf-timer"; + reg = <0x8e3000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <227 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + uart120: uart@8e5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x8e5000 0x1000>; + status = "disabled"; + interrupts = <229 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + spi120: spi@8e6000 { + compatible = "nordic,nrf-spim"; + reg = <0x8e6000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <230 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi121: spi@8e7000 { + compatible = "nordic,nrf-spim"; + reg = <0x8e7000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <231 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + cpuppr_vpr: vpr@908000 { + compatible = "nordic,nrf-vpr-coprocessor"; + reg = <0x908000 0x1000>; + status = "disabled"; + cpu = <13>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x908000 0x4000>; + + cpuppr_vevif_remote: mailbox@0 { + compatible = "nordic,nrf-vevif-remote"; + reg = <0x0 0x1000>; + status = "disabled"; + #mbox-cells = <1>; + nordic,tasks = <16>; + nordic,tasks-mask = <0xfffffff0>; + }; + + cpuppr_clic: interrupt-controller@1000 { + compatible = "nordic,nrf-clic"; + reg = <0x1000 0x3000>; + status = "disabled"; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; + + rtc130: rtc@928000 { + compatible = "nordic,nrf-rtc"; + reg = <0x928000 0x1000>; + status = "disabled"; + cc-num = <4>; + clock-frequency = <32768>; + interrupts = <296 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <1>; + }; + + rtc131: rtc@929000 { + compatible = "nordic,nrf-rtc"; + reg = <0x929000 0x1000>; + status = "disabled"; + cc-num = <4>; + clock-frequency = <32768>; + interrupts = <297 NRF_DEFAULT_IRQ_PRIORITY>; + prescaler = <1>; + }; + + wdt131: watchdog@92b000 { + compatible = "nordic,nrf-wdt"; + reg = <0x92b000 0x1000>; + status = "disabled"; + interrupts = <299 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + wdt132: watchdog@92c000 { + compatible = "nordic,nrf-wdt"; + reg = <0x92c000 0x1000>; + status = "disabled"; + interrupts = <300 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + gpiote130: gpiote@934000 { + compatible = "nordic,nrf-gpiote"; + reg = <0x934000 0x1000>; + status = "disabled"; + instance = <130>; + }; + + gpio0: gpio@938000 { + compatible = "nordic,nrf-gpio"; + reg = <0x938000 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <0>; + }; + + gpio1: gpio@938200 { + compatible = "nordic,nrf-gpio"; + reg = <0x938200 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <1>; + }; + + gpio2: gpio@938400 { + compatible = "nordic,nrf-gpio"; + reg = <0x938400 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <12>; + port = <2>; + }; + + gpio6: gpio@938c00 { + compatible = "nordic,nrf-gpio"; + reg = <0x938c00 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + ngpios = <14>; + port = <6>; + }; + + gpio7: gpio@938e00 { + compatible = "nordic,nrf-gpio"; + reg = <0x938e00 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + ngpios = <8>; + port = <7>; + }; + + gpio9: gpio@939200 { + compatible = "nordic,nrf-gpio"; + reg = <0x939200 0x200>; + status = "disabled"; + #gpio-cells = <2>; + gpio-controller; + gpiote-instance = <&gpiote130>; + ngpios = <6>; + port = <9>; + }; + + comp: comparator@983000 { + compatible = "nordic,nrf-comp"; + reg = <0x983000 0x1000>; + status = "disabled"; + interrupts = <387 NRF_DEFAULT_IRQ_PRIORITY>; + #io-channel-cells = <1>; + }; + + temp: temperature-sensor@984000 { + compatible = "nordic,nrf-temp"; + reg = <0x984000 0x1000>; + interrupts = <388 NRF_DEFAULT_IRQ_PRIORITY>; + status = "disabled"; + }; + + nfct: nfct@985000 { + compatible = "nordic,nrf-nfct"; + reg = <0x985000 0x1000>; + status = "disabled"; + interrupts = <389 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + qdec130: qdec@994000 { + compatible = "nordic,nrf-qdec"; + reg = <0x994000 0x1000>; + status = "disabled"; + interrupts = <404 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + qdec131: qdec@995000 { + compatible = "nordic,nrf-qdec"; + reg = <0x995000 0x1000>; + status = "disabled"; + interrupts = <405 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + grtc: grtc@99c000 { + compatible = "nordic,nrf-grtc"; + reg = <0x99c000 0x1000>; + status = "disabled"; + cc-num = <16>; + }; + + timer130: timer@9a2000 { + compatible = "nordic,nrf-timer"; + reg = <0x9a2000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <418 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer131: timer@9a3000 { + compatible = "nordic,nrf-timer"; + reg = <0x9a3000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <419 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + i2c130: i2c@9a5000 { + compatible = "nordic,nrf-twim"; + reg = <0x9a5000 0x1000>; + status = "disabled"; + interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi130: spi@9a5000 { + compatible = "nordic,nrf-spim"; + reg = <0x9a5000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart130: uart@9a5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9a5000 0x1000>; + status = "disabled"; + interrupts = <421 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + i2c131: i2c@9a6000 { + compatible = "nordic,nrf-twim"; + reg = <0x9a6000 0x1000>; + status = "disabled"; + interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi131: spi@9a6000 { + compatible = "nordic,nrf-spim"; + reg = <0x9a6000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart131: uart@9a6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9a6000 0x1000>; + status = "disabled"; + interrupts = <422 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + timer132: timer@9b2000 { + compatible = "nordic,nrf-timer"; + reg = <0x9b2000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <434 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer133: timer@9b3000 { + compatible = "nordic,nrf-timer"; + reg = <0x9b3000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <435 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + i2c132: i2c@9b5000 { + compatible = "nordic,nrf-twim"; + reg = <0x9b5000 0x1000>; + status = "disabled"; + interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi132: spi@9b5000 { + compatible = "nordic,nrf-spim"; + reg = <0x9b5000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart132: uart@9b5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9b5000 0x1000>; + status = "disabled"; + interrupts = <437 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + i2c133: i2c@9b6000 { + compatible = "nordic,nrf-twim"; + reg = <0x9b6000 0x1000>; + status = "disabled"; + interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi133: spi@9b6000 { + compatible = "nordic,nrf-spim"; + reg = <0x9b6000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart133: uart@9b6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9b6000 0x1000>; + status = "disabled"; + interrupts = <438 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + timer134: timer@9c2000 { + compatible = "nordic,nrf-timer"; + reg = <0x9c2000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <450 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer135: timer@9c3000 { + compatible = "nordic,nrf-timer"; + reg = <0x9c3000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <451 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + i2c134: i2c@9c5000 { + compatible = "nordic,nrf-twim"; + reg = <0x9c5000 0x1000>; + status = "disabled"; + interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi134: spi@9c5000 { + compatible = "nordic,nrf-spim"; + reg = <0x9c5000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart134: uart@9c5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9c5000 0x1000>; + status = "disabled"; + interrupts = <453 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + i2c135: i2c@9c6000 { + compatible = "nordic,nrf-twim"; + reg = <0x9c6000 0x1000>; + status = "disabled"; + interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi135: spi@9c6000 { + compatible = "nordic,nrf-spim"; + reg = <0x9c6000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart135: uart@9c6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9c6000 0x1000>; + status = "disabled"; + interrupts = <454 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + timer136: timer@9d2000 { + compatible = "nordic,nrf-timer"; + reg = <0x9d2000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <466 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + timer137: timer@9d3000 { + compatible = "nordic,nrf-timer"; + reg = <0x9d3000 0x1000>; + status = "disabled"; + cc-num = <6>; + interrupts = <467 NRF_DEFAULT_IRQ_PRIORITY>; + max-bit-width = <32>; + prescaler = <0>; + }; + + i2c136: i2c@9d5000 { + compatible = "nordic,nrf-twim"; + reg = <0x9d5000 0x1000>; + status = "disabled"; + interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi136: spi@9d5000 { + compatible = "nordic,nrf-spim"; + reg = <0x9d5000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart136: uart@9d5000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9d5000 0x1000>; + status = "disabled"; + interrupts = <469 NRF_DEFAULT_IRQ_PRIORITY>; + }; + + i2c137: i2c@9d6000 { + compatible = "nordic,nrf-twim"; + reg = <0x9d6000 0x1000>; + status = "disabled"; + interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; + easydma-maxcnt-bits = <15>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi137: spi@9d6000 { + compatible = "nordic,nrf-spim"; + reg = <0x9d6000 0x1000>; + status = "disabled"; + easydma-maxcnt-bits = <15>; + interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; + max-frequency = ; + #address-cells = <1>; + #size-cells = <0>; + }; + + uart137: uart@9d6000 { + compatible = "nordic,nrf-uarte"; + reg = <0x9d6000 0x1000>; + status = "disabled"; + interrupts = <470 NRF_DEFAULT_IRQ_PRIORITY>; + }; + }; + }; + + cpuapp_ppb: cpuapp-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpuapp_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + + cpuapp_nvic: interrupt-controller@e000e100 { + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; + + cpurad_ppb: cpurad-ppb-bus { + #address-cells = <1>; + #size-cells = <1>; + + cpurad_systick: timer@e000e010 { + compatible = "arm,armv8m-systick"; + reg = <0xe000e010 0x10>; + status = "disabled"; + }; + + cpurad_nvic: interrupt-controller@e000e100 { + compatible = "arm,v8m-nvic"; + reg = <0xe000e100 0xc00>; + arm,num-irq-priority-bits = <3>; + #interrupt-cells = <2>; + interrupt-controller; + #address-cells = <1>; + }; + }; +}; diff --git a/dts/arm/nordic/nrf_common.dtsi b/dts/common/nordic/nrf_common.dtsi similarity index 86% rename from dts/arm/nordic/nrf_common.dtsi rename to dts/common/nordic/nrf_common.dtsi index 8aec8dd0c89..cb2df6bcccd 100644 --- a/dts/arm/nordic/nrf_common.dtsi +++ b/dts/common/nordic/nrf_common.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -43,11 +44,3 @@ #pwm-cells = <3>; }; }; - -&systick { - /* - * Nordic SoCs rely by default on the RTC for system clock - * implementation, so the SysTick node is not to be enabled. - */ - status = "disabled"; -}; diff --git a/dts/riscv/gigadevice/gd32vf103.dtsi b/dts/riscv/gigadevice/gd32vf103.dtsi index c9f37db5180..b52aee61fbc 100644 --- a/dts/riscv/gigadevice/gd32vf103.dtsi +++ b/dts/riscv/gigadevice/gd32vf103.dtsi @@ -23,7 +23,6 @@ cpu: cpu@0 { clock-frequency = ; - mcause-exception-mask = <0x7ff>; compatible = "nuclei,bumblebee"; riscv,isa = "rv32imac_zicsr_zifencei"; reg = <0>; diff --git a/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi b/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi new file mode 100644 index 00000000000..0af6618688f --- /dev/null +++ b/dts/riscv/nordic/nrf54h20_enga_cpuppr.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +cpu: &cpuppr {}; +clic: &cpuppr_clic {}; +cpuppr_vevif: &cpuppr_vevif_local {}; + +/delete-node/ &cpuapp; +/delete-node/ &cpuapp_peripherals; +/delete-node/ &cpuapp_ppb; +/delete-node/ &cpuapp_ram0; +/delete-node/ &cpurad; +/delete-node/ &cpurad_peripherals; +/delete-node/ &cpurad_ppb; +/delete-node/ &cpurad_ram0; + +/ { + soc { + compatible = "simple-bus"; + interrupt-parent = <&cpuppr_clic>; + ranges; + }; +}; + +&cpusec_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&cpuapp_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&cpurad_bellboard { + compatible = "nordic,nrf-bellboard-remote"; +}; + +&gpiote130 { + interrupts = <104 NRF_DEFAULT_IRQ_PRIORITY>; +}; + +&grtc { + interrupts = <108 NRF_DEFAULT_IRQ_PRIORITY>; +}; diff --git a/include/zephyr/arch/arc/v2/irq.h b/include/zephyr/arch/arc/v2/irq.h index e0b42549597..45b9d138857 100644 --- a/include/zephyr/arch/arc/v2/irq.h +++ b/include/zephyr/arch/arc/v2/irq.h @@ -77,7 +77,7 @@ extern void z_irq_priority_set(unsigned int irq, unsigned int prio, */ #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ - Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \ + Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p); \ BUILD_ASSERT(priority_p || !IS_ENABLED(CONFIG_ARC_FIRQ) || \ (IS_ENABLED(CONFIG_ARC_FIRQ_STACK) && \ !IS_ENABLED(CONFIG_ARC_STACK_CHECKING)), \ diff --git a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld index a27dd55a8cf..a28209c1b43 100644 --- a/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_a_r/scripts/linker.ld @@ -32,10 +32,16 @@ #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET) #endif +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif + #if CONFIG_FLASH_LOAD_SIZE > 0 - #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE + #define ROM_SIZE (CONFIG_FLASH_LOAD_SIZE - ROM_END_OFFSET) #else - #define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET) + #define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET - ROM_END_OFFSET) #endif #if defined(CONFIG_XIP) @@ -81,7 +87,7 @@ MEMORY RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ - IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K + IDT_LIST (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K } ENTRY(CONFIG_KERNEL_ENTRY) diff --git a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld index 13c2747f5a3..25a48d11252 100644 --- a/include/zephyr/arch/arm/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/cortex_m/scripts/linker.ld @@ -26,16 +26,51 @@ #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 #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET) #endif +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif + #if CONFIG_FLASH_LOAD_SIZE > 0 -#define ROM_SIZE CONFIG_FLASH_LOAD_SIZE +#define ROM_SIZE (CONFIG_FLASH_LOAD_SIZE - ROM_END_OFFSET) #else -#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - CONFIG_FLASH_LOAD_OFFSET) +#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - CONFIG_FLASH_LOAD_OFFSET - ROM_END_OFFSET) #endif #if defined(CONFIG_XIP) @@ -52,6 +87,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 @@ -86,7 +138,7 @@ MEMORY #endif LINKER_DT_REGIONS() /* Used by and documented in include/linker/intlist.ld */ - IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K + IDT_LIST (wx) : ORIGIN = 0xFFFF7FFF, LENGTH = 32K } ENTRY(CONFIG_KERNEL_ENTRY) diff --git a/include/zephyr/arch/arm/irq.h b/include/zephyr/arch/arm/irq.h index 357c91a83ae..143b8e54179 100644 --- a/include/zephyr/arch/arm/irq.h +++ b/include/zephyr/arch/arm/irq.h @@ -127,7 +127,7 @@ extern void z_arm_interrupt_init(void); BUILD_ASSERT(IS_ENABLED(CONFIG_ZERO_LATENCY_IRQS) || !(flags_p & IRQ_ZERO_LATENCY), \ "ZLI interrupt registered but feature is disabled"); \ _CHECK_PRIO(priority_p, flags_p) \ - Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \ + Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p); \ z_arm_irq_priority_set(irq_p, priority_p, flags_p); \ } diff --git a/include/zephyr/arch/arm64/scripts/linker.ld b/include/zephyr/arch/arm64/scripts/linker.ld index fa08b730304..5a8e1404a98 100644 --- a/include/zephyr/arch/arm64/scripts/linker.ld +++ b/include/zephyr/arch/arm64/scripts/linker.ld @@ -31,10 +31,16 @@ #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET) #endif +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif + #if CONFIG_FLASH_LOAD_SIZE > 0 - #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE + #define ROM_SIZE (CONFIG_FLASH_LOAD_SIZE - ROM_END_OFFSET) #else - #define ROM_SIZE (CONFIG_FLASH_SIZE * 1K - CONFIG_FLASH_LOAD_OFFSET) + #define ROM_SIZE (CONFIG_FLASH_SIZE * 1K - CONFIG_FLASH_LOAD_OFFSET - ROM_END_OFFSET) #endif #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K) @@ -61,7 +67,7 @@ MEMORY FLASH (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE RAM (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE /* Used by and documented in include/linker/intlist.ld */ - IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K + IDT_LIST (wx) : ORIGIN = 0xFFFF8000, LENGTH = 32K } ENTRY(CONFIG_KERNEL_ENTRY) @@ -105,8 +111,11 @@ SECTIONS KEEP(*(.exc_vector_table)) KEEP(*(".exc_vector_table.*")) +#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) + INCLUDE isr_tables_vt.ld +#else KEEP(*(.vectors)) - +#endif _vector_end = .; *(.text) diff --git a/include/zephyr/arch/nios2/linker.ld b/include/zephyr/arch/nios2/linker.ld index 6958533eaf6..f7ba64088fc 100644 --- a/include/zephyr/arch/nios2/linker.ld +++ b/include/zephyr/arch/nios2/linker.ld @@ -39,6 +39,11 @@ * the exception vector is in RAM */ +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif #ifdef CONFIG_XIP #define ROMABLE_REGION FLASH @@ -54,7 +59,7 @@ ASSERT(_RESET_VECTOR == _ROM_ADDR, "Reset vector not at beginning of ROM!") MEMORY { RESET (rx) : ORIGIN = _RESET_VECTOR, LENGTH = 0x20 - FLASH (rx) : ORIGIN = _RESET_VECTOR + 0x20 , LENGTH = (_ROM_SIZE - 0x20) + FLASH (rx) : ORIGIN = _RESET_VECTOR + 0x20 , LENGTH = (_ROM_SIZE - 0x20 - ROM_END_OFFSET) RAM (wx) : ORIGIN = _EXC_VECTOR, LENGTH = _RAM_SIZE - (_EXC_VECTOR - _RAM_ADDR) /* Used by and documented in include/linker/intlist.ld */ IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K diff --git a/include/zephyr/arch/riscv/arch.h b/include/zephyr/arch/riscv/arch.h index 99bccb74a08..bbde28bdfbe 100644 --- a/include/zephyr/arch/riscv/arch.h +++ b/include/zephyr/arch/riscv/arch.h @@ -26,7 +26,6 @@ #endif /* CONFIG_USERSPACE */ #include #include -#include #include #include #include @@ -300,7 +299,7 @@ static inline uint64_t arch_k_cycle_get_64(void) #endif /*_ASMLANGUAGE */ -#if defined(CONFIG_SOC_FAMILY_RISCV_PRIVILEGED) +#if defined(CONFIG_RISCV_PRIVILEGED) #include #endif diff --git a/include/zephyr/arch/riscv/common/linker.ld b/include/zephyr/arch/riscv/common/linker.ld index eb5c4782441..3245012731d 100644 --- a/include/zephyr/arch/riscv/common/linker.ld +++ b/include/zephyr/arch/riscv/common/linker.ld @@ -11,7 +11,6 @@ * Generic Linker script for the riscv platform */ -#include #include #include @@ -30,27 +29,52 @@ #define _EXCEPTION_SECTION_NAME exceptions #define _RESET_SECTION_NAME reset +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif + +#if defined(CONFIG_FLASH_LOAD_OFFSET) +#define FLASH_LOAD_OFFSET CONFIG_FLASH_LOAD_OFFSET +#else +#define FLASH_LOAD_OFFSET 0 +#endif + #ifdef CONFIG_XIP + +#if CONFIG_FLASH_LOAD_SIZE > 0 +#define ROM_SIZE (CONFIG_FLASH_LOAD_SIZE - ROM_END_OFFSET) +#endif + #if DT_NODE_HAS_COMPAT_STATUS(DT_CHOSEN(zephyr_flash), soc_nv_flash, okay) -#ifdef CONFIG_FLASH_LOAD_OFFSET -#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + \ - CONFIG_FLASH_LOAD_OFFSET) -#else /* !CONFIG_FLASH_LOAD_OFFSET */ -#define ROM_BASE DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) -#endif /* CONFIG_FLASH_LOAD_OFFSET */ -#define ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) +#define ROM_BASE (DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) + FLASH_LOAD_OFFSET) +#ifndef ROM_SIZE +#define ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - ROM_END_OFFSET) +#endif + #elif DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_flash), jedec_spi_nor) /* For jedec,spi-nor we expect the spi controller to memory map the flash * and for that mapping to be the second register property of the spi * controller. */ #define SPI_CTRL DT_PARENT(DT_CHOSEN(zephyr_flash)) -#define ROM_BASE DT_REG_ADDR_BY_IDX(SPI_CTRL, 1) -#define ROM_SIZE DT_REG_SIZE_BY_IDX(SPI_CTRL, 1) +#define ROM_BASE (DT_REG_ADDR_BY_IDX(SPI_CTRL, 1) + FLASH_LOAD_OFFSET) +#ifndef ROM_SIZE +#define ROM_SIZE (DT_REG_SIZE_BY_IDX(SPI_CTRL, 1) - ROM_END_OFFSET) #endif + +#else /* Use Kconfig to cover the remaining cases */ +#define ROM_BASE (CONFIG_FLASH_BASE_ADDRESS + FLASH_LOAD_OFFSET) +#ifndef ROM_SIZE +#define ROM_SIZE (CONFIG_FLASH_SIZE * 1024 - FLASH_LOAD_OFFSET - ROM_END_OFFSET) +#endif + +#endif /* DT_NODE_HAS_COMPAT_STATUS */ + #else /* CONFIG_XIP */ #define ROM_BASE CONFIG_SRAM_BASE_ADDRESS -#define ROM_SIZE KB(CONFIG_SRAM_SIZE) +#define ROM_SIZE (KB(CONFIG_SRAM_SIZE) - ROM_END_OFFSET) #endif /* CONFIG_XIP */ #define RAM_BASE CONFIG_SRAM_BASE_ADDRESS diff --git a/include/zephyr/arch/riscv/irq.h b/include/zephyr/arch/riscv/irq.h index 77c0d4057aa..d067ccfca23 100644 --- a/include/zephyr/arch/riscv/irq.h +++ b/include/zephyr/arch/riscv/irq.h @@ -14,16 +14,39 @@ #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ #define ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ -#ifndef _ASMLANGUAGE - #ifdef __cplusplus extern "C" { #endif +#ifndef _ASMLANGUAGE #include #include #include -#include +#endif /* !_ASMLANGUAGE */ + +/* Exceptions 0-15 (MCAUSE interrupt=0) */ + +/* Environment Call from U-mode */ +#define RISCV_EXC_ECALLU 8 +/** Environment Call from M-mode */ +#define RISCV_EXC_ECALLM 11 + +/* IRQs 0-15 (MCAUSE interrupt=1) */ + +/** Machine Software Interrupt */ +#define RISCV_IRQ_MSOFT 3 +/** Machine External Interrupt */ +#define RISCV_IRQ_MEXT 11 + +#ifdef CONFIG_64BIT +#define RISCV_MCAUSE_IRQ_POS 63U +#define RISCV_MCAUSE_IRQ_BIT BIT64(RISCV_MCAUSE_IRQ_POS) +#else +#define RISCV_MCAUSE_IRQ_POS 31U +#define RISCV_MCAUSE_IRQ_BIT BIT(RISCV_MCAUSE_IRQ_POS) +#endif + +#ifndef _ASMLANGUAGE extern void arch_irq_enable(unsigned int irq); extern void arch_irq_disable(unsigned int irq); @@ -46,8 +69,8 @@ extern void z_riscv_irq_priority_set(unsigned int irq, #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ - Z_ISR_DECLARE(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ - ISR_FLAG_DIRECT, isr_p, NULL); \ + Z_ISR_DECLARE_DIRECT(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \ + ISR_FLAG_DIRECT, isr_p); \ } #define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header() @@ -76,7 +99,7 @@ static inline void arch_isr_direct_footer(int swap) /* Get the IRQ number */ __asm__ volatile("csrr %0, mcause" : "=r" (mcause)); - mcause &= SOC_MCAUSE_EXP_MASK; + mcause &= CONFIG_RISCV_MCAUSE_EXCEPTION_MASK; /* Clear the pending IRQ */ __soc_handle_irq(mcause); @@ -102,10 +125,10 @@ static inline void arch_isr_direct_footer(int swap) } \ static inline int name##_body(void) +#endif /* _ASMLANGUAGE */ #ifdef __cplusplus } #endif -#endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_IRQ_H_ */ diff --git a/include/zephyr/arch/x86/memory.ld b/include/zephyr/arch/x86/memory.ld index 72b400dd079..c9ede2b9d23 100644 --- a/include/zephyr/arch/x86/memory.ld +++ b/include/zephyr/arch/x86/memory.ld @@ -50,12 +50,18 @@ /* "kernel RAM" for linker VMA allocations starts at the offset */ +#if defined(CONFIG_ROM_END_OFFSET) +#define ROM_END_OFFSET CONFIG_ROM_END_OFFSET +#else +#define ROM_END_OFFSET 0 +#endif + #ifdef CONFIG_XIP /* "ROM" is flash, we leave rodata and text there and just copy in data. * Board-level DTS must specify a flash region that doesn't overlap with * sram0, so that DT_PHYS_LOAD_ADDR is set. */ - #define FLASH_ROM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) + #define FLASH_ROM_SIZE (DT_REG_SIZE(DT_CHOSEN(zephyr_flash)) - ROM_END_OFFSET) #define PHYS_LOAD_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_flash)) #else /* Physical RAM location where the kernel image is loaded */ diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 17bac991f18..03f451a3c8b 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -209,6 +209,7 @@ enum bt_audio_metadata_type { ((struct bt_audio_codec_cfg){ \ /* Use HCI data path as default, can be overwritten by application */ \ .path_id = BT_ISO_DATA_PATH_HCI, \ + .ctlr_transcode = false, \ .id = _id, \ .cid = _cid, \ .vid = _vid, \ @@ -231,6 +232,7 @@ enum bt_audio_metadata_type { ((struct bt_audio_codec_cap){ \ /* Use HCI data path as default, can be overwritten by application */ \ .path_id = BT_ISO_DATA_PATH_HCI, \ + .ctlr_transcode = false, \ .id = (_id), \ .cid = (_cid), \ .vid = (_vid), \ @@ -316,6 +318,12 @@ struct bt_audio_codec_cap { * vendor specific ID. */ uint8_t path_id; + /** Whether or not the local controller should transcode + * + * This effectively sets the coding format for the ISO data path to @ref + * BT_HCI_CODING_FORMAT_TRANSPARENT if false, else uses the @ref bt_audio_codec_cfg.id. + */ + bool ctlr_transcode; /** Codec ID */ uint8_t id; /** Codec Company ID */ @@ -344,6 +352,12 @@ struct bt_audio_codec_cfg { * vendor specific ID. */ uint8_t path_id; + /** Whether or not the local controller should transcode + * + * This effectively sets the coding format for the ISO data path to @ref + * BT_HCI_CODING_FORMAT_TRANSPARENT if false, else uses the @ref bt_audio_codec_cfg.id. + */ + bool ctlr_transcode; /** Codec ID */ uint8_t id; /** Codec Company ID */ diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 09b8321d685..bdc644d82e9 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -479,6 +479,42 @@ struct bt_conn_le_tx_power { int8_t max_level; }; + +/** LE Transmit Power Reporting Structure */ +struct bt_conn_le_tx_power_report { + + /** Reason for Transmit power reporting, + * as documented in Core Spec. Version 5.4 Vol. 4, Part E, 7.7.65.33. + */ + uint8_t reason; + + /** Phy of Transmit power reporting. */ + enum bt_conn_le_tx_power_phy phy; + + /** Transmit power level + * - 0xXX - Transmit power level + * + Range: -127 to 20 + * + Units: dBm + * + * - 0x7E - Remote device is not managing power levels on this PHY. + * - 0x7F - Transmit power level is not available + */ + int8_t tx_power_level; + + /** Bit 0: Transmit power level is at minimum level. + * Bit 1: Transmit power level is at maximum level. + */ + uint8_t tx_power_level_flag; + + /** Change in transmit power level + * - 0xXX - Change in transmit power level (positive indicates increased + * power, negative indicates decreased power, zero indicates unchanged) + * Units: dB + * - 0x7F - Change is not available or is out of range. + */ + int8_t delta; +}; + /** @brief Passkey Keypress Notification type * * The numeric values are the same as in the Core specification for Pairing @@ -530,6 +566,41 @@ int bt_conn_get_remote_info(struct bt_conn *conn, int bt_conn_le_get_tx_power_level(struct bt_conn *conn, struct bt_conn_le_tx_power *tx_power_level); +/** @brief Get local enhanced connection transmit power level. + * + * @param conn Connection object. + * @param tx_power Transmit power level descriptor. + * + * @return Zero on success or (negative) error code on failure. + * @retval -ENOBUFS HCI command buffer is not available. + */ +int bt_conn_le_enhanced_get_tx_power_level(struct bt_conn *conn, + struct bt_conn_le_tx_power *tx_power); + +/** @brief Get remote (peer) transmit power level. + * + * @param conn Connection object. + * @param phy PHY information. + * + * @return Zero on success or (negative) error code on failure. + * @retval -ENOBUFS HCI command buffer is not available. + */ +int bt_conn_le_get_remote_tx_power_level(struct bt_conn *conn, + enum bt_conn_le_tx_power_phy phy); + +/** @brief Enable transmit power reporting. + * + * @param conn Connection object. + * @param local_enable Enable/disable reporting for local. + * @param remote_enable Enable/disable reporting for remote. + * + * @return Zero on success or (negative) error code on failure. + * @retval -ENOBUFS HCI command buffer is not available. + */ +int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, + bool local_enable, + bool remote_enable); + /** @brief Update the connection parameters. * * If the local device is in the peripheral role then updating the connection @@ -1052,6 +1123,22 @@ struct bt_conn_cb { const struct bt_df_conn_iq_samples_report *iq_report); #endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + /** @brief LE Read Remote Transmit Power Level procedure has completed or LE + * Transmit Power Reporting event. + * + * This callback notifies the application that either the remote transmit power level + * has been read from the peer or transmit power level has changed for the local or + * remote controller when transmit power reporting is enabled for the respective side + * using @ref bt_conn_le_set_tx_power_report_enable. + * + * @param conn Connection object. + * @param report Transmit power report. + */ + void (*tx_power_report)(struct bt_conn *conn, + const struct bt_conn_le_tx_power_report *report); +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + struct bt_conn_cb *_next; }; diff --git a/include/zephyr/bluetooth/gatt.h b/include/zephyr/bluetooth/gatt.h index c53422648f0..eb38f765afb 100644 --- a/include/zephyr/bluetooth/gatt.h +++ b/include/zephyr/bluetooth/gatt.h @@ -235,6 +235,37 @@ struct bt_gatt_cb { sys_snode_t node; }; +/** @brief GATT authorization callback structure. */ +struct bt_gatt_authorization_cb { + /** @brief Authorize the GATT read operation. + * + * This callback allows the application to authorize the GATT + * read operation for the attribute that is being read. + * + * @param conn Connection object. + * @param attr The attribute that is being read. + * + * @retval true Authorize the operation and allow it to execute. + * @retval false Reject the operation and prevent it from executing. + */ + bool (*read_operation_authorize)(struct bt_conn *conn, + const struct bt_gatt_attr *attr); + + /** @brief Authorize the GATT write operation. + * + * This callback allows the application to authorize the GATT + * write operation for the attribute that is being written. + * + * @param conn Connection object. + * @param attr The attribute that is being written. + * + * @retval true Authorize the operation and allow it to execute. + * @retval false Reject the operation and prevent it from executing. + */ + bool (*write_operation_authorize)(struct bt_conn *conn, + const struct bt_gatt_attr *attr); +}; + /** Characteristic Properties Bit field values */ /** @@ -377,6 +408,26 @@ struct bt_gatt_cpf { */ void bt_gatt_cb_register(struct bt_gatt_cb *cb); +/** @brief Register GATT authorization callbacks. + * + * Register callbacks to perform application-specific authorization of GATT + * operations on all registered GATT attributes. The callback structure must + * remain valid throughout the entire duration of the Bluetooth subsys + * activity. + * + * The @kconfig{CONFIG_BT_GATT_AUTHORIZATION_CUSTOM} Kconfig must be enabled + * to make this API functional. + * + * This API allows the user to register only one callback structure + * concurrently. Passing NULL unregisters the previous set of callbacks + * and makes it possible to register a new one. + * + * @param cb Callback struct. + * + * @return Zero on success or negative error code otherwise + */ +int bt_gatt_authorization_cb_register(const struct bt_gatt_authorization_cb *cb); + /** @brief Register GATT service. * * Register GATT service. Applications can make use of diff --git a/include/zephyr/bluetooth/hci_types.h b/include/zephyr/bluetooth/hci_types.h index 4d637bbe4e2..f1cb92f372c 100644 --- a/include/zephyr/bluetooth/hci_types.h +++ b/include/zephyr/bluetooth/hci_types.h @@ -571,6 +571,35 @@ struct bt_hci_rp_read_tx_power_level { int8_t tx_power_level; } __packed; +#define BT_HCI_LE_TX_POWER_PHY_1M 0x01 +#define BT_HCI_LE_TX_POWER_PHY_2M 0x02 +#define BT_HCI_LE_TX_POWER_PHY_CODED_S8 0x03 +#define BT_HCI_LE_TX_POWER_PHY_CODED_S2 0x04 +#define BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL BT_OP(BT_OGF_LE, 0x0076) +struct bt_hci_cp_le_read_tx_power_level { + uint16_t handle; + uint8_t phy; +} __packed; + +struct bt_hci_rp_le_read_tx_power_level { + uint8_t status; + uint16_t handle; + uint8_t phy; + int8_t current_tx_power_level; + int8_t max_tx_power_level; +} __packed; + +#define BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL BT_OP(BT_OGF_LE, 0x0077) + +#define BT_HCI_LE_TX_POWER_REPORT_DISABLE 0x00 +#define BT_HCI_LE_TX_POWER_REPORT_ENABLE 0x01 +#define BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE BT_OP(BT_OGF_LE, 0x007A) +struct bt_hci_cp_le_set_tx_power_report_enable { + uint16_t handle; + uint8_t local_enable; + uint8_t remote_enable; +} __packed; + #define BT_HCI_CTL_TO_HOST_FLOW_DISABLE 0x00 #define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01 #define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031) @@ -2905,6 +2934,26 @@ struct bt_hci_evt_le_req_peer_sca_complete { uint8_t sca; } __packed; +/** Reason for Transmit power reporting. + */ +/* Local Transmit power changed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_LOCAL_CHANGED 0x00 +/* Remote Transmit power changed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_REMOTE_CHANGED 0x01 +/* HCI_LE_Read_Remote_Transmit_Power_Level command completed. */ +#define BT_HCI_LE_TX_POWER_REPORT_REASON_READ_REMOTE_COMPLETED 0x02 + +#define BT_HCI_EVT_LE_TRANSMIT_POWER_REPORT 0x21 +struct bt_hci_evt_le_transmit_power_report { + uint8_t status; + uint16_t handle; + uint8_t reason; + uint8_t phy; + int8_t tx_power_level; + uint8_t tx_power_level_flag; + int8_t delta; +} __packed; + #define BT_HCI_EVT_LE_BIGINFO_ADV_REPORT 0x22 struct bt_hci_evt_le_biginfo_adv_report { uint16_t sync_handle; diff --git a/include/zephyr/bluetooth/hci_vs.h b/include/zephyr/bluetooth/hci_vs.h index aea92846e56..3561e20e9aa 100644 --- a/include/zephyr/bluetooth/hci_vs.h +++ b/include/zephyr/bluetooth/hci_vs.h @@ -47,6 +47,8 @@ extern "C" { #define BT_HCI_VS_HW_VAR_NORDIC_NRF51X 0x0001 #define BT_HCI_VS_HW_VAR_NORDIC_NRF52X 0x0002 #define BT_HCI_VS_HW_VAR_NORDIC_NRF53X 0x0003 +#define BT_HCI_VS_HW_VAR_NORDIC_NRF54HX 0x0004 +#define BT_HCI_VS_HW_VAR_NORDIC_NRF54LX 0x0005 #define BT_HCI_VS_FW_VAR_STANDARD_CTLR 0x0001 #define BT_HCI_VS_FW_VAR_VS_CTLR 0x0002 diff --git a/include/zephyr/bluetooth/mesh.h b/include/zephyr/bluetooth/mesh.h index a4ef70dc6de..fc84814fa44 100644 --- a/include/zephyr/bluetooth/mesh.h +++ b/include/zephyr/bluetooth/mesh.h @@ -1,5 +1,5 @@ /** @file - * @brief Bluetooth mesh Profile APIs. + * @brief Bluetooth Mesh Profile APIs. */ /* diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 817fba918ef..a236ede525d 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -713,6 +713,8 @@ struct bt_mesh_model_pub { uint8_t period_div:4, /**< Divisor for the Period. */ count:4; /**< Transmissions left. */ + uint8_t delayable:1; /**< Use random delay for publishing. */ + uint32_t period_start; /**< Start of the current period. */ /** @brief Publication buffer, containing the publication message. @@ -1011,7 +1013,7 @@ const struct bt_mesh_elem *bt_mesh_model_elem(const struct bt_mesh_model *mod); * if no SIG model with the given ID exists in the given element. */ const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, - uint16_t id); + uint16_t id); /** @brief Find a vendor model. * @@ -1023,7 +1025,7 @@ const struct bt_mesh_model *bt_mesh_model_find(const struct bt_mesh_elem *elem, * if no vendor model with the given ID exists in the given element. */ const struct bt_mesh_model *bt_mesh_model_find_vnd(const struct bt_mesh_elem *elem, - uint16_t company, uint16_t id); + uint16_t company, uint16_t id); /** @brief Get whether the model is in the primary element of the device. * diff --git a/include/zephyr/bluetooth/mesh/blob_cli.h b/include/zephyr/bluetooth/mesh/blob_cli.h index 8e239b31457..9b591cfdd35 100644 --- a/include/zephyr/bluetooth/mesh/blob_cli.h +++ b/include/zephyr/bluetooth/mesh/blob_cli.h @@ -265,10 +265,10 @@ struct blob_cli_broadcast_ctx { void (*send)(struct bt_mesh_blob_cli *cli, uint16_t dst); /** Called after every @ref blob_cli_broadcast_ctx::send callback. */ void (*send_complete)(struct bt_mesh_blob_cli *cli, uint16_t dst); - /** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes - * have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called - * after transmission has been completed. - */ + /** If @ref blob_cli_broadcast_ctx::acked is true, called after all Target nodes + * have confirmed reception by @ref blob_cli_broadcast_rsp. Otherwise, called + * after transmission has been completed. + */ void (*next)(struct bt_mesh_blob_cli *cli); /** If true, every transmission needs to be confirmed by @ref blob_cli_broadcast_rsp before * @ref blob_cli_broadcast_ctx::next is called. diff --git a/include/zephyr/bluetooth/mesh/blob_srv.h b/include/zephyr/bluetooth/mesh/blob_srv.h index bf807bad92f..92c809bd6b5 100644 --- a/include/zephyr/bluetooth/mesh/blob_srv.h +++ b/include/zephyr/bluetooth/mesh/blob_srv.h @@ -108,7 +108,7 @@ struct bt_mesh_blob_srv_cb { /** @brief Transfer recovery callback. * - * Called when the Bluetooth mesh subsystem is started if the device is rebooted + * Called when the Bluetooth Mesh subsystem is started if the device is rebooted * in the middle of a transfer. * * Transfers will not be resumed after a reboot if this callback is not diff --git a/include/zephyr/bluetooth/mesh/cdb.h b/include/zephyr/bluetooth/mesh/cdb.h index 800ae07edc4..8ea35ec2e55 100644 --- a/include/zephyr/bluetooth/mesh/cdb.h +++ b/include/zephyr/bluetooth/mesh/cdb.h @@ -231,7 +231,7 @@ enum { * or BT_MESH_CDB_ITER_STOP to stop. */ typedef uint8_t (*bt_mesh_cdb_node_func_t)(struct bt_mesh_cdb_node *node, - void *user_data); + void *user_data); /** @brief Node iterator. * diff --git a/include/zephyr/bluetooth/mesh/cfg.h b/include/zephyr/bluetooth/mesh/cfg.h index 7d1ca4e868f..9bfd067da9b 100644 --- a/include/zephyr/bluetooth/mesh/cfg.h +++ b/include/zephyr/bluetooth/mesh/cfg.h @@ -26,7 +26,7 @@ extern "C" { #endif -/** Bluetooth mesh feature states */ +/** Bluetooth Mesh feature states */ enum bt_mesh_feat_state { /** Feature is supported, but disabled. */ BT_MESH_FEATURE_DISABLED, diff --git a/include/zephyr/bluetooth/mesh/cfg_cli.h b/include/zephyr/bluetooth/mesh/cfg_cli.h index 0e8c26131ff..4aca0c17451 100644 --- a/include/zephyr/bluetooth/mesh/cfg_cli.h +++ b/include/zephyr/bluetooth/mesh/cfg_cli.h @@ -96,8 +96,8 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing subscription addresses. */ void (*mod_sub_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t elem_addr, uint16_t mod_id, uint16_t cid, - struct net_buf_simple *buf); + uint16_t elem_addr, uint16_t mod_id, uint16_t cid, + struct net_buf_simple *buf); /** @brief Optional callback for Node Reset Status messages. * @@ -128,7 +128,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*ttl_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for Friend Status messages. * @@ -139,7 +139,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*friend_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for GATT Proxy Status messages. * @@ -150,7 +150,7 @@ struct bt_mesh_cfg_cli_cb { * @param status Status Code for requesting message. */ void (*gatt_proxy_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - uint8_t status); + uint8_t status); /** @brief Optional callback for Network Transmit Status messages. * @@ -199,7 +199,7 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*net_key_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, - struct net_buf_simple *buf); + struct net_buf_simple *buf); /** @brief Optional callback for AppKey Status messages. * @@ -229,7 +229,7 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*app_key_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t net_idx, struct net_buf_simple *buf); + uint16_t net_idx, struct net_buf_simple *buf); /** @brief Optional callback for Model App Status messages. * @@ -262,8 +262,8 @@ struct bt_mesh_cfg_cli_cb { * @param buf Message buffer containing key indexes. */ void (*mod_app_list)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - uint16_t elem_addr, uint16_t mod_id, uint16_t cid, - struct net_buf_simple *buf); + uint16_t elem_addr, uint16_t mod_id, uint16_t cid, + struct net_buf_simple *buf); /** @brief Optional callback for Node Identity Status messages. * @@ -326,7 +326,7 @@ struct bt_mesh_cfg_cli_cb { * @param sub HB subscription configuration parameters. */ void (*hb_sub_status)(struct bt_mesh_cfg_cli *cli, uint16_t addr, uint8_t status, - struct bt_mesh_cfg_cli_hb_sub *sub); + struct bt_mesh_cfg_cli_hb_sub *sub); }; /** Mesh Configuration Client Model Context */ diff --git a/include/zephyr/bluetooth/mesh/dfu_cli.h b/include/zephyr/bluetooth/mesh/dfu_cli.h index 3cbc220d825..ad8881ebc26 100644 --- a/include/zephyr/bluetooth/mesh/dfu_cli.h +++ b/include/zephyr/bluetooth/mesh/dfu_cli.h @@ -9,7 +9,7 @@ * @defgroup bt_mesh_dfu_cli Firmware Uppdate Client model * @ingroup bt_mesh_dfu * @{ - * @brief API for the Bluetooth mesh Firmware Update Client model + * @brief API for the Bluetooth Mesh Firmware Update Client model */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_CLI_H__ diff --git a/include/zephyr/bluetooth/mesh/dfu_metadata.h b/include/zephyr/bluetooth/mesh/dfu_metadata.h index bec65897ac7..21d032236a7 100644 --- a/include/zephyr/bluetooth/mesh/dfu_metadata.h +++ b/include/zephyr/bluetooth/mesh/dfu_metadata.h @@ -6,10 +6,10 @@ /** * @file - * @defgroup bt_mesh_dfu_metadata Bluetooth mesh Device Firmware Update (DFU) metadata + * @defgroup bt_mesh_dfu_metadata Bluetooth Mesh Device Firmware Update (DFU) metadata * @ingroup bt_mesh_dfu * @{ - * @brief Common types and functions for the Bluetooth mesh DFU metadata. + * @brief Common types and functions for the Bluetooth Mesh DFU metadata. */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_METADATA_H__ diff --git a/include/zephyr/bluetooth/mesh/dfu_srv.h b/include/zephyr/bluetooth/mesh/dfu_srv.h index e136701e664..2beaf2d9772 100644 --- a/include/zephyr/bluetooth/mesh/dfu_srv.h +++ b/include/zephyr/bluetooth/mesh/dfu_srv.h @@ -9,7 +9,7 @@ * @defgroup bt_mesh_dfu_srv Firmware Update Server model * @ingroup bt_mesh_dfu * @{ - * @brief API for the Bluetooth mesh Firmware Update Server model + * @brief API for the Bluetooth Mesh Firmware Update Server model */ #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DFU_SRV_H__ @@ -136,7 +136,7 @@ struct bt_mesh_dfu_srv_cb { /** @brief Transfer recovery callback. * * If the device reboots in the middle of a transfer, the Firmware Update Server - * calls this function when the Bluetooth mesh subsystem is started. + * calls this function when the Bluetooth Mesh subsystem is started. * * This callback is optional, but transfers will not be recovered after * a reboot without it. diff --git a/include/zephyr/bluetooth/mesh/main.h b/include/zephyr/bluetooth/mesh/main.h index a4e98b97f8c..1622ccebbd8 100644 --- a/include/zephyr/bluetooth/mesh/main.h +++ b/include/zephyr/bluetooth/mesh/main.h @@ -1,5 +1,5 @@ /** @file - * @brief Bluetooth mesh Protocol APIs. + * @brief Bluetooth Mesh Protocol APIs. */ /* @@ -550,8 +550,8 @@ bool bt_mesh_is_provisioned(void); */ /** - * @brief Bluetooth mesh - * @defgroup bt_mesh Bluetooth mesh + * @brief Bluetooth Mesh + * @defgroup bt_mesh Bluetooth Mesh * @ingroup bluetooth * @{ */ @@ -607,6 +607,10 @@ void bt_mesh_reset(void); * If at all possible, the Friendship feature should be used instead, to * make the node into a Low Power Node. * + * @note Should not be called from work queue due to undefined behavior. + * This is due to k_work_flush_delayable() being used in disabling of the + * extended advertising. + * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_suspend(void); @@ -779,7 +783,6 @@ struct bt_mesh_snb { uint64_t auth_val; }; -#if defined(CONFIG_BT_MESH_V1d1) struct bt_mesh_prb { /** Random */ uint8_t random[13]; @@ -793,7 +796,6 @@ struct bt_mesh_prb { /** Authentication tag */ uint64_t auth_tag; }; -#endif /** Beacon callback functions. */ struct bt_mesh_beacon_cb { @@ -806,7 +808,6 @@ struct bt_mesh_beacon_cb { */ void (*snb_received)(const struct bt_mesh_snb *snb); -#if defined(CONFIG_BT_MESH_V1d1) /** @brief Private Beacon received. * * This callback notifies the application that Private Beacon @@ -815,7 +816,6 @@ struct bt_mesh_beacon_cb { * @param prb Structure describing received Private Beacon */ void (*priv_received)(const struct bt_mesh_prb *prb); -#endif }; /** diff --git a/include/zephyr/bluetooth/mesh/msg.h b/include/zephyr/bluetooth/mesh/msg.h index e52ca85e3a4..8a7ce1a7128 100644 --- a/include/zephyr/bluetooth/mesh/msg.h +++ b/include/zephyr/bluetooth/mesh/msg.h @@ -98,6 +98,9 @@ struct bt_mesh_msg_ctx { /** Force sending reliably by using segment acknowledgment */ bool send_rel; + /** Send message with a random delay according to the Access layer transmitting rules. */ + bool rnd_delay; + /** TTL, or BT_MESH_TTL_DEFAULT for default TTL. */ uint8_t send_ttl; }; diff --git a/include/zephyr/device.h b/include/zephyr/device.h index 630a059c155..c55958924ff 100644 --- a/include/zephyr/device.h +++ b/include/zephyr/device.h @@ -41,6 +41,10 @@ extern "C" { */ #define Z_DEVICE_DEPS_ENDS INT16_MAX +/** @brief Determine if a DT node is mutable */ +#define Z_DEVICE_IS_MUTABLE(node_id) \ + COND_CODE_1(IS_ENABLED(CONFIG_DEVICE_MUTABLE), (DT_PROP(node_id, zephyr_mutable)), (0)) + /** @endcond */ /** @@ -924,12 +928,13 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * @param api Reference to device API. * @param ... Optional dependencies, manually specified. */ -#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, \ - prio, api, state, deps) \ - COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \ - const STRUCT_SECTION_ITERABLE_NAMED(device, \ - Z_DEVICE_SECTION_NAME(level, prio), \ - DEVICE_NAME_GET(dev_id)) = \ +#define Z_DEVICE_BASE_DEFINE(node_id, dev_id, name, pm, data, config, level, prio, api, state, \ + deps) \ + COND_CODE_1(DT_NODE_EXISTS(node_id), (), (static)) \ + COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), (const)) \ + STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE( \ + device, COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (device_mutable), (device)), \ + Z_DEVICE_SECTION_NAME(level, prio), DEVICE_NAME_GET(dev_id)) = \ Z_DEVICE_INIT(name, pm, data, config, api, state, deps) /* deprecated device initialization levels */ @@ -961,15 +966,18 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * @param level Initialization level. * @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)) \ - Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ - .init_fn = {.dev = (init_fn_)}, \ - .dev = &DEVICE_NAME_GET(dev_id), \ +#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)) \ + Z_INIT_ENTRY_NAME(DEVICE_NAME_GET(dev_id)) = { \ + .init_fn = {COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ + (init_fn_)}, \ + { \ + COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (.dev_rw), (.dev)) = \ + &DEVICE_NAME_GET(dev_id), \ + }, \ } /** @@ -1015,8 +1023,9 @@ static inline bool z_impl_device_is_ready(const struct device *dev) * don't have a corresponding @ref device allocated. There's no way to figure * that out until after we've built the zephyr image, though. */ -#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \ - extern const struct device DEVICE_DT_NAME_GET(node_id); +#define Z_MAYBE_DEVICE_DECLARE_INTERNAL(node_id) \ + extern COND_CODE_1(Z_DEVICE_IS_MUTABLE(node_id), (), \ + (const)) struct device DEVICE_DT_NAME_GET(node_id); DT_FOREACH_STATUS_OKAY_NODE(Z_MAYBE_DEVICE_DECLARE_INTERNAL) diff --git a/include/zephyr/drivers/cellular.h b/include/zephyr/drivers/cellular.h new file mode 100644 index 00000000000..fba05e6e440 --- /dev/null +++ b/include/zephyr/drivers/cellular.h @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2023 Bjarki Arge Andreasen + * Copyright (c) 2023 Lucas Denefle + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file drivers/cellular.h + * @brief Public cellular network API + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_ + +/** + * @brief Cellular interface + * @defgroup cellular_interface Cellular Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Cellular access technologies */ +enum cellular_access_technology { + CELLULAR_ACCESS_TECHNOLOGY_GSM = 0, + CELLULAR_ACCESS_TECHNOLOGY_GPRS, + CELLULAR_ACCESS_TECHNOLOGY_UMTS, + CELLULAR_ACCESS_TECHNOLOGY_EDGE, + CELLULAR_ACCESS_TECHNOLOGY_LTE, + CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M1, + CELLULAR_ACCESS_TECHNOLOGY_LTE_CAT_M2, + CELLULAR_ACCESS_TECHNOLOGY_NB_IOT, +}; + +/** Cellular network structure */ +struct cellular_network { + /** Cellular access technology */ + enum cellular_access_technology technology; + /** + * List of bands, as defined by the specified cellular access technology, + * to enables. All supported bands are enabled if none are provided. + */ + uint16_t *bands; + /** Size of bands */ + uint16_t size; +}; + +/** Cellular signal type */ +enum cellular_signal_type { + CELLULAR_SIGNAL_RSSI, + CELLULAR_SIGNAL_RSRP, + CELLULAR_SIGNAL_RSRQ, +}; + +/** Cellular modem info type */ +enum cellular_modem_info_type { + /** International Mobile Equipment Identity */ + CELLULAR_MODEM_INFO_IMEI, + /** Modem model ID */ + CELLULAR_MODEM_INFO_MODEL_ID, + /** Modem manufacturer */ + CELLULAR_MODEM_INFO_MANUFACTURER, + /** Modem fw version */ + CELLULAR_MODEM_INFO_FW_VERSION, + /** International Mobile Subscriber Identity */ + CELLULAR_MODEM_INFO_SIM_IMSI, + /** Integrated Circuit Card Identification Number (SIM) */ + CELLULAR_MODEM_INFO_SIM_ICCID, +}; + +/** API for configuring networks */ +typedef int (*cellular_api_configure_networks)(const struct device *dev, + const struct cellular_network *networks, + uint8_t size); + +/** API for getting supported networks */ +typedef int (*cellular_api_get_supported_networks)(const struct device *dev, + const struct cellular_network **networks, + uint8_t *size); + +/** API for getting network signal strength */ +typedef int (*cellular_api_get_signal)(const struct device *dev, + const enum cellular_signal_type type, int16_t *value); + +/** API for getting modem information */ +typedef int (*cellular_api_get_modem_info)(const struct device *dev, + const enum cellular_modem_info_type type, + char *info, size_t size); + +/** Cellular driver API */ +__subsystem struct cellular_driver_api { + cellular_api_configure_networks configure_networks; + cellular_api_get_supported_networks get_supported_networks; + cellular_api_get_signal get_signal; + cellular_api_get_modem_info get_modem_info; +}; + +/** + * @brief Configure cellular networks for the device + * + * @details Cellular network devices support at least one cellular access technology. + * Each cellular access technology defines a set of bands, of which the cellular device + * will support all or a subset of. + * + * The cellular device can only use one cellular network technology at a time. It must + * exclusively use the cellular network configurations provided, and will prioritize + * the cellular network configurations in the order they are provided in case there are + * multiple (the first cellular network configuration has the highest priority). + * + * @param dev Cellular network device instance. + * @param networks List of cellular network configurations to apply. + * @param size Size of list of cellular network configurations. + * + * @retval 0 if successful. + * @retval -EINVAL if any provided cellular network configuration is invalid or unsupported. + * @retval -ENOTSUP if API is not supported by cellular network device. + * @retval Negative errno-code otherwise. + */ +static inline int cellular_configure_networks(const struct device *dev, + const struct cellular_network *networks, uint8_t size) +{ + const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api; + + if (api->configure_networks == NULL) { + return -ENOSYS; + } + + return api->configure_networks(dev, networks, size); +} + +/** + * @brief Get supported cellular networks for the device + * + * @param dev Cellular network device instance + * @param networks Pointer to list of supported cellular network configurations. + * @param size Size of list of cellular network configurations. + * + * @retval 0 if successful. + * @retval -ENOTSUP if API is not supported by cellular network device. + * @retval Negative errno-code otherwise. + */ +static inline int cellular_get_supported_networks(const struct device *dev, + const struct cellular_network **networks, + uint8_t *size) +{ + const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api; + + if (api->get_supported_networks == NULL) { + return -ENOSYS; + } + + return api->get_supported_networks(dev, networks, size); +} + +/** + * @brief Get signal for the device + * + * @param dev Cellular network device instance + * @param type Type of the signal information requested + * @param value Signal strength destination (one of RSSI, RSRP, RSRQ) + * + * @retval 0 if successful. + * @retval -ENOTSUP if API is not supported by cellular network device. + * @retval -ENODATA if device is not in a state where signal can be polled + * @retval Negative errno-code otherwise. + */ +static inline int cellular_get_signal(const struct device *dev, + const enum cellular_signal_type type, int16_t *value) +{ + const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api; + + if (api->get_signal == NULL) { + return -ENOSYS; + } + + return api->get_signal(dev, type, value); +} + +/** + * @brief Get modem info for the device + * + * @param dev Cellular network device instance + * @param type Type of the modem info requested + * @param info Info string destination + * @param size Info string size + * + * @retval 0 if successful. + * @retval -ENOTSUP if API is not supported by cellular network device. + * @retval -ENODATA if modem does not provide info requested + * @retval Negative errno-code from chat module otherwise. + */ +static inline int cellular_get_modem_info(const struct device *dev, + const enum cellular_modem_info_type type, char *info, + size_t size) +{ + const struct cellular_driver_api *api = (const struct cellular_driver_api *)dev->api; + + if (api->get_modem_info == NULL) { + return -ENOSYS; + } + + return api->get_modem_info(dev, type, info, size); +} + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CELLULAR_H_ */ diff --git a/drivers/gnss/gnss_publish.h b/include/zephyr/drivers/gnss/gnss_publish.h similarity index 100% rename from drivers/gnss/gnss_publish.h rename to include/zephyr/drivers/gnss/gnss_publish.h diff --git a/include/zephyr/drivers/misc/devmux/devmux.h b/include/zephyr/drivers/misc/devmux/devmux.h new file mode 100644 index 00000000000..1772d719d96 --- /dev/null +++ b/include/zephyr/drivers/misc/devmux/devmux.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Public APIs for the Device Multiplexer driver + */ + +#ifndef INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ +#define INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Devmux Driver APIs + * @defgroup demux_interface Devmux Driver APIs + * @ingroup misc_interfaces + * + * @details + * Devmux operates as a device multiplexer, forwarding the characteristics of + * the selected device. + * + * ``` + * +----------+ +----------+ + * | devmux | | devmux | + * | | | | + * dev0 | | dev0 | | + * +----------> \ | +----------> | + * | \ | | | + * dev1 | \ | dev0 dev1 | | dev2 + * +----------> O +----------> +----------> O +----------> + * | | | / | + * dev2 | | dev2 | / | + * +----------> | +----------> / | + * | | | | + * | | | | + * | | | | + * +-----^----+ +-----^----+ + * | | + * select == 0 | select == 2 | + * +--------------+ +---------------+ + * ``` + * @{ + */ + +/** + * @brief Get the current selection of a devmux device. + * + * Return the index of the currently selected device. + * + * @param dev the devmux device + * @return The index (>= 0) of the currently active multiplexed device on success + * @retval -EINVAL If @p dev is invalid + */ +__syscall ssize_t devmux_select_get(const struct device *dev); + +/** + * @brief Set the selection of a devmux device. + * + * Select the device at @p index. + * + * @param[in] dev the devmux device + * @param index the index representing the desired selection + * @retval 0 On success + * @retval -EINVAL If @p dev is invalid + * @retval -ENODEV If the multiplexed device at @p index is not ready + */ +__syscall int devmux_select_set(struct device *dev, size_t index); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* INCLUDE_ZEPHYR_DRIVERS_MISC_DEVMUX_H_ */ diff --git a/include/zephyr/drivers/serial/uart_async_to_irq.h b/include/zephyr/drivers/serial/uart_async_to_irq.h new file mode 100644 index 00000000000..d5116dee2c0 --- /dev/null +++ b/include/zephyr/drivers/serial/uart_async_to_irq.h @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ +#define ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ + +#include +#include +#include +#include +#include + +/** + * @brief UART Asynchronous to Interrupt driven API adaptation layer + * @ingroup uart_interface + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declarations. */ + +/** @brief Data structure used by the adaptation layer. + * + * Pointer to that data must be the first element of the UART device data structure. + */ +struct uart_async_to_irq_data; + +/** @brief Configuration structure used by the adaptation layer. + * + * Pointer to this data must be the first element of the UART device configuration structure. + */ +struct uart_async_to_irq_config; + +/* @brief Function that triggers trampoline to the interrupt context. + * + * This context is used to call user UART interrupt handler. It is to used to + * fulfill the requirement that UART interrupt driven API shall be called from + * the UART interrupt. Trampoline context shall have the same priority as UART. + * + * One option may be to use k_timer configured to expire immediately. + */ +typedef void (*uart_async_to_irq_trampoline)(const struct device *dev); + +/** @brief Callback to be called from trampoline context. + * + * @param dev UART device. + */ +void uart_async_to_irq_trampoline_cb(const struct device *dev); + +/** @brief Interrupt driven API initializer. + * + * It should be used in the initialization of the UART API structure in the + * driver to provide interrupt driven API functions. + */ +#define UART_ASYNC_TO_IRQ_API_INIT() \ + .fifo_fill = z_uart_async_to_irq_fifo_fill, \ + .fifo_read = z_uart_async_to_irq_fifo_read, \ + .irq_tx_enable = z_uart_async_to_irq_irq_tx_enable, \ + .irq_tx_disable = z_uart_async_to_irq_irq_tx_disable, \ + .irq_tx_ready = z_uart_async_to_irq_irq_tx_ready, \ + .irq_rx_enable = z_uart_async_to_irq_irq_rx_enable, \ + .irq_rx_disable = z_uart_async_to_irq_irq_rx_disable, \ + .irq_tx_complete = z_uart_async_to_irq_irq_tx_complete,\ + .irq_rx_ready = z_uart_async_to_irq_irq_rx_ready, \ + .irq_err_enable = z_uart_async_to_irq_irq_err_enable, \ + .irq_err_disable = z_uart_async_to_irq_irq_err_disable,\ + .irq_is_pending = z_uart_async_to_irq_irq_is_pending, \ + .irq_update = z_uart_async_to_irq_irq_update, \ + .irq_callback_set = z_uart_async_to_irq_irq_callback_set + +/** @brief Configuration structure initializer. + * + * @param _api Structure with UART asynchronous API. + * @param _trampoline Function that trampolines to the interrupt context. + * @param _baudrate UART baudrate. + * @param _tx_buf TX buffer. + * @param _tx_len TX buffer length. + * @param _rx_buf RX buffer. + * @param _rx_len RX buffer length. + * @param _rx_cnt Number of chunks into which RX buffer is divided. + * @param _log Logging instance, if not provided (empty) then default is used. + */ +#define UART_ASYNC_TO_IRQ_API_CONFIG_INITIALIZER(_api, _trampoline, _baudrate, _tx_buf, \ + _tx_len, _rx_buf, _rx_len, _rx_cnt, _log) \ + { \ + .tx_buf = _tx_buf, \ + .tx_len = _tx_len, \ + .async_rx = { \ + .buffer = _rx_buf, \ + .length = _rx_len, \ + .buf_cnt = _rx_cnt \ + }, \ + .api = _api, \ + .trampoline = _trampoline, \ + .baudrate = _baudrate, \ + LOG_OBJECT_PTR_INIT(log, \ + COND_CODE_1(IS_EMPTY(_log), \ + (LOG_OBJECT_PTR(UART_ASYNC_TO_IRQ_LOG_NAME)), \ + (_log) \ + ) \ + ) \ + } + +/** @brief Initialize the adaptation layer. + * + * @param data Data associated with the given adaptation layer instance. + * @param config Configuration structure. Must be persistent. + * + * @retval 0 On successful initialization. + */ +int uart_async_to_irq_init(struct uart_async_to_irq_data *data, + const struct uart_async_to_irq_config *config); + +/* @brief Enable RX for interrupt driven API. + * + * @param dev UART device. Device must support asynchronous API. + * + * @retval 0 on successful operation. + * @retval -EINVAL if adaption layer has wrong configuration. + * @retval negative value Error reported by the UART API. + */ +int uart_async_to_irq_rx_enable(const struct device *dev); + +/* @brief Disable RX for interrupt driven API. + * + * @param dev UART device. Device must support asynchronous API. + * + * @retval 0 on successful operation. + * @retval -EINVAL if adaption layer has wrong configuration. + * @retval negative value Error reported by the UART API. + */ +int uart_async_to_irq_rx_disable(const struct device *dev); + +/* Starting from here API is internal only. */ + +/** @cond INTERNAL_HIDDEN + * @brief Structure used by the adaptation layer. + */ +struct uart_async_to_irq_config { + /** Pointer to the TX buffer. */ + uint8_t *tx_buf; + + /** TX buffer length. */ + size_t tx_len; + + /** UART Asynchronous RX helper configuration. */ + struct uart_async_rx_config async_rx; + + /** Async API used by the a2i layer. */ + const struct uart_async_to_irq_async_api *api; + + /** Trampoline callback. */ + uart_async_to_irq_trampoline trampoline; + + /** Initial baudrate. */ + uint32_t baudrate; + + /** Instance logging handler. */ + LOG_INSTANCE_PTR_DECLARE(log); +}; + +/** @brief Asynchronous API used by the adaptation layer. */ +struct uart_async_to_irq_async_api { + int (*callback_set)(const struct device *dev, + uart_callback_t callback, + void *user_data); + + int (*tx)(const struct device *dev, const uint8_t *buf, size_t len, + int32_t timeout); + int (*tx_abort)(const struct device *dev); + + int (*rx_enable)(const struct device *dev, uint8_t *buf, size_t len, + int32_t timeout); + int (*rx_buf_rsp)(const struct device *dev, uint8_t *buf, size_t len); + int (*rx_disable)(const struct device *dev); +}; + +/** @brief Structure holding receiver data. */ +struct uart_async_to_irq_rx_data { + /** Asynchronous RX helper data. */ + struct uart_async_rx async_rx; + + /** Semaphore for pending on RX disable. */ + struct k_sem sem; + + /** Number of pending buffer requests which weren't handled because lack of free buffers. */ + atomic_t pending_buf_req; +}; + +/** @brief Structure holding transmitter data. */ +struct uart_async_to_irq_tx_data { + /** TX buffer. */ + uint8_t *buf; + + /** Length of the buffer. */ + size_t len; +}; + +/** @briref Data associated with the asynchronous to the interrupt driven API adaptation layer. */ +struct uart_async_to_irq_data { + /** User callback for interrupt driven API. */ + uart_irq_callback_user_data_t callback; + + /** User data. */ + void *user_data; + + /** Interrupt request counter. */ + atomic_t irq_req; + + /** RX specific data. */ + struct uart_async_to_irq_rx_data rx; + + /** TX specific data. */ + struct uart_async_to_irq_tx_data tx; + + /** Spinlock. */ + struct k_spinlock lock; + + /** Internally used flags for holding the state of the a2i layer. */ + atomic_t flags; +}; + +/** Interrupt driven FIFO fill function. */ +int z_uart_async_to_irq_fifo_fill(const struct device *dev, + const uint8_t *buf, + int len); + +/** Interrupt driven FIFO read function. */ +int z_uart_async_to_irq_fifo_read(const struct device *dev, + uint8_t *buf, + const int len); + +/** Interrupt driven transfer enabling function. */ +void z_uart_async_to_irq_irq_tx_enable(const struct device *dev); + +/** Interrupt driven transfer disabling function */ +void z_uart_async_to_irq_irq_tx_disable(const struct device *dev); + +/** Interrupt driven transfer ready function */ +int z_uart_async_to_irq_irq_tx_ready(const struct device *dev); + +/** Interrupt driven receiver enabling function */ +void z_uart_async_to_irq_irq_rx_enable(const struct device *dev); + +/** Interrupt driven receiver disabling function */ +void z_uart_async_to_irq_irq_rx_disable(const struct device *dev); + +/** Interrupt driven transfer complete function */ +int z_uart_async_to_irq_irq_tx_complete(const struct device *dev); + +/** Interrupt driven receiver ready function */ +int z_uart_async_to_irq_irq_rx_ready(const struct device *dev); + +/** Interrupt driven error enabling function */ +void z_uart_async_to_irq_irq_err_enable(const struct device *dev); + +/** Interrupt driven error disabling function */ +void z_uart_async_to_irq_irq_err_disable(const struct device *dev); + +/** Interrupt driven pending status function */ +int z_uart_async_to_irq_irq_is_pending(const struct device *dev); + +/** Interrupt driven interrupt update function */ +int z_uart_async_to_irq_irq_update(const struct device *dev); + +/** Set the irq callback function */ +void z_uart_async_to_irq_irq_callback_set(const struct device *dev, + uart_irq_callback_user_data_t cb, + void *user_data); + +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* ZEPHYR_DRIVERS_SERIAL_UART_ASYNC_TO_IRQ_H_ */ diff --git a/include/zephyr/drivers/timer/nrf_grtc_timer.h b/include/zephyr/drivers/timer/nrf_grtc_timer.h new file mode 100644 index 00000000000..172a904fdef --- /dev/null +++ b/include/zephyr/drivers/timer/nrf_grtc_timer.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H +#define ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** @brief GRTC timer compare event handler. + * + * Called from GRTC ISR context when processing a compare event. + * + * @param id Compare channel ID. + * + * @param expire_time An actual absolute expiration time set for a compare + * channel. It can differ from the requested target time + * and the difference can be used to determine whether the + * time set was delayed. + * + * @param user_data Pointer to a user context data. + */ +typedef void (*z_nrf_grtc_timer_compare_handler_t)(int32_t id, uint64_t expire_time, + void *user_data); + +/** @brief Allocate GRTC capture/compare channel. + * + * @retval >=0 Non-negative indicates allocated channel ID. + * @retval -ENOMEM if channel cannot be allocated. + */ +int32_t z_nrf_grtc_timer_chan_alloc(void); + +/** @brief Free GRTC capture/compare channel. + * + * @param chan Previously allocated channel ID. + */ +void z_nrf_grtc_timer_chan_free(int32_t chan); + +/** @brief Read current absolute time. + * + * @return Current absolute time. + */ +uint64_t z_nrf_grtc_timer_read(void); + +/** @brief Check COMPARE event state. + * + * @param chan Channel ID. + * + * @retval true The event has been generated. + * @retval false The event has not been generated. + */ +bool z_nrf_grtc_timer_compare_evt_check(int32_t chan); + +/** @brief Get COMPARE event register address. + * + * Address can be used for DPPIC. + * + * @param chan Channel ID. + * + * @return Register address. + */ +uint32_t z_nrf_grtc_timer_compare_evt_address_get(int32_t chan); + +/** @brief Get CAPTURE task register address. + * + * Address can be used for DPPIC. + * + * @param chan Channel ID. + * + * @return Register address. + */ +uint32_t z_nrf_grtc_timer_capture_task_address_get(int32_t chan); + +/** @brief Safely disable compare event interrupt. + * + * Function returns key indicating whether interrupt was already disabled. + * + * @param chan Channel ID. + * + * @return key passed to z_nrf_grtc_timer_compare_int_unlock(). + */ +bool z_nrf_grtc_timer_compare_int_lock(int32_t chan); + +/** @brief Safely enable compare event interrupt. + * + * Event interrupt is conditionally enabled based on @p key. + * + * @param chan Channel ID. + * + * @param key Key returned by z_nrf_grtc_timer_compare_int_lock(). + */ +void z_nrf_grtc_timer_compare_int_unlock(int32_t chan, bool key); + +/** @brief Read compare register value. + * + * @param chan Channel ID. + * + * @retval >=0 Positive is a Value set in the compare register + * @retval -EAGAIN if compare for given channel is not set. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +uint64_t z_nrf_grtc_timer_compare_read(int32_t chan); + +/** @brief Set compare channel to given value. + * + * @param chan Channel ID. + * + * @param target_time Absolute target time in ticks. + * + * @param handler User function called in the context of the GRTC interrupt. + * + * @param user_data Data passed to the handler. + * + * @retval 0 if the compare channel was set successfully. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +int z_nrf_grtc_timer_set(int32_t chan, uint64_t target_time, + z_nrf_grtc_timer_compare_handler_t handler, void *user_data); + +/** @brief Abort a timer requested with z_nrf_grtc_timer_set(). + * + * If an abort operation is performed too late it is still possible for an event + * to fire. The user can detect a spurious event by comparing absolute time + * provided in callback and a result of z_nrf_grtc_timer_read(). During this + * operation interrupt from that compare channel is disabled. Other interrupts + * are not locked during this operation. + * + * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. + */ +void z_nrf_grtc_timer_abort(int32_t chan); + +/** @brief Convert system clock time to GRTC ticks. + * + * @p t can be absolute or relative. + * + * @retval >=0 Positive value represents @p t in GRTC tick value. + * @retval -EINVAL if @p t is out of range. + */ +uint64_t z_nrf_grtc_timer_get_ticks(k_timeout_t t); + +/** @brief Prepare channel for timestamp capture. + * + * Use z_nrf_grtc_timer_capture_task_address_get() to determine the register + * address that is used to trigger capture. + * + * @note Capture and compare are mutually exclusive features - they cannot be + * used simultaneously on the same GRTC channel. + * + * @param chan Channel ID. + * + * @retval 0 if the channel was successfully prepared. + * @retval -EPERM if either channel is unavailable or SYSCOUNTER is not running. + */ +int z_nrf_grtc_timer_capture_prepare(int32_t chan); + +/** @brief Read timestamp value captured on the channel. + * + * The @p chan must be prepared using z_nrf_grtc_timer_capture_prepare(). + * + * @param chan Channel ID. + * + * @param captured_time Pointer to store the value. + * + * @retval 0 if the timestamp was successfully caught and read. + * @retval -EBUSY if capturing has not been triggered. + */ +int z_nrf_grtc_timer_capture_read(int32_t chan, uint64_t *captured_time); + +/** @brief Prepare GRTC as a source of wake up event and set the wake up time. + * + * @note Calling this function should be immediately followed by low-power mode enter + * (if it executed successfully). + * + * @param wake_time_us Relative wake up time in microseconds. + * + * @retval 0 if wake up time was successfully set. + * @retval -EPERM if the SYSCOUNTER is not running. + * @retval -ENOMEM if no available GRTC channels were found. + * @retval -EINVAL if @p wake_time_us is too low. + */ +int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us); + +/** + * @brief Initialize the GRTC clock timer driver from an application- + * defined function. + * + * @retval 0 on success. + * @retval -errno Negative error code on failure. + */ +int nrf_grtc_timer_clock_driver_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_TIMER_NRF_GRTC_TIMER_H */ diff --git a/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h b/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h new file mode 100644 index 00000000000..60b788a3516 --- /dev/null +++ b/include/zephyr/dt-bindings/misc/nordic-nrf-ficr-nrf54h20-enga.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/* autogenerated using Nordic HAL utils/gen_offsets.py script */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ + +#define NRF_FICR_BLE_ADDRTYPE 0x00CU +#define NRF_FICR_BLE_ADDR_0 0x010U +#define NRF_FICR_BLE_ADDR_1 0x014U +#define NRF_FICR_BLE_ER_0 0x018U +#define NRF_FICR_BLE_ER_1 0x01CU +#define NRF_FICR_BLE_ER_2 0x020U +#define NRF_FICR_BLE_ER_3 0x024U +#define NRF_FICR_BLE_IR_0 0x028U +#define NRF_FICR_BLE_IR_1 0x02CU +#define NRF_FICR_BLE_IR_2 0x030U +#define NRF_FICR_BLE_IR_3 0x034U +#define NRF_FICR_NFC_TAGHEADER_0 0x040U +#define NRF_FICR_NFC_TAGHEADER_1 0x044U +#define NRF_FICR_NFC_TAGHEADER_2 0x048U +#define NRF_FICR_NFC_TAGHEADER_3 0x04CU +#define NRF_FICR_INFO_CONFIGID 0x050U +#define NRF_FICR_INFO_PART 0x054U +#define NRF_FICR_INFO_VARIANT 0x058U +#define NRF_FICR_INFO_PACKAGE 0x05CU +#define NRF_FICR_INFO_RAM 0x060U +#define NRF_FICR_INFO_MRAM 0x064U +#define NRF_FICR_INFO_CODEPAGESIZE 0x068U +#define NRF_FICR_INFO_CODESIZE 0x06CU +#define NRF_FICR_INFO_DEVICETYPE 0x070U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALVREF 0x384U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_0 0x388U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_1 0x38CU +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALGAIN_2 0x390U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALOFFSET 0x394U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_0 0x398U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_1 0x39CU +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_2 0x3A0U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_3 0x3A4U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_4 0x3A8U +#define NRF_FICR_TRIM_GLOBAL_SAADC_LINCALCOEFF_5 0x3ACU +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALIREF 0x3B0U +#define NRF_FICR_TRIM_GLOBAL_SAADC_CALVREFTC 0x3B4U +#define NRF_FICR_TRIM_GLOBAL_NFCT_BIASCFG 0x3BCU +#define NRF_FICR_TRIM_GLOBAL_CANPLL_TRIM_CTUNE 0x3C0U +#define NRF_FICR_TRIM_GLOBAL_COMP_REFTRIM 0x3D0U +#define NRF_FICR_TRIM_GLOBAL_COMP_RCALTRIM 0x3D4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP 0x3D8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0 0x3DCU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_1 0x3E0U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_2 0x3E4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_3 0x3E8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_4 0x3ECU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_5 0x3F0U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0 0x3F4U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_1 0x3F8U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_2 0x3FCU +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_3 0x400U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_4 0x404U +#define NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_5 0x408U +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_0_TRIM 0x40CU +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_1_TRIM 0x410U +#define NRF_FICR_TRIM_APPLICATION_MEMCONF_BLOCKTYPE_2_TRIM 0x414U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_VSUP 0x418U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_0 0x41CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_1 0x420U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_2 0x424U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_3 0x428U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_4 0x42CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_COARSE_5 0x430U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_0 0x434U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_1 0x438U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_2 0x43CU +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_3 0x440U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_4 0x444U +#define NRF_FICR_TRIM_RADIOCORE_HSFLL_TRIM_FINE_5 0x448U +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_0_TRIM 0x44CU +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_1_TRIM 0x450U +#define NRF_FICR_TRIM_RADIOCORE_MEMCONF_BLOCKTYPE_2_TRIM 0x454U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL0 0x458U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL1 0x45CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_FSCTRL2 0x460U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_RXCTRL 0x464U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_SPHYNXANA_OVRRXTRIMCODE 0x468U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_RXAGC_CALIBRATION 0x46CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_PVTTOT 0x470U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_KDTC 0x474U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_TXHFGAIN 0x478U +#define NRF_FICR_TRIM_RADIOCORE_RADIO_PVTTOFIX 0x47CU +#define NRF_FICR_TRIM_RADIOCORE_RADIO_LOOPGAIN 0x480U + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_MISC_NORDIC_NRF_FICR_NRF54H20_ENGA_H_ */ diff --git a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h index b2dcd7ae6c9..9d7f8c2312f 100644 --- a/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h +++ b/include/zephyr/dt-bindings/pinctrl/nrf-pinctrl.h @@ -131,7 +131,6 @@ /** * @name nRF pinctrl output drive. - * @note Values match nrf_gpio_pin_drive_t constants. * @{ */ @@ -152,7 +151,7 @@ /** High drive '0', disconnect '1'. */ #define NRF_DRIVE_H0D1 7U /** Extra high drive '0', extra high drive '1'. */ -#define NRF_DRIVE_E0E1 11U +#define NRF_DRIVE_E0E1 8U /** @} */ diff --git a/include/zephyr/init.h b/include/zephyr/init.h index 9b0d2993d62..78ec454f27c 100644 --- a/include/zephyr/init.h +++ b/include/zephyr/init.h @@ -73,6 +73,17 @@ union init_function { * @retval -errno If device initialization fails. */ int (*dev)(const struct device *dev); +#ifdef CONFIG_DEVICE_MUTABLE + /** + * Device initialization function (rw). + * + * @param dev Device instance. + * + * @retval 0 On success + * @retval -errno If device initialization fails. + */ + int (*dev_rw)(struct device *dev); +#endif }; /** @@ -96,7 +107,12 @@ struct init_entry { * If the init entry belongs to a device, this fields stores a * reference to it, otherwise it is set to NULL. */ - const struct device *dev; + union { + const struct device *dev; +#ifdef CONFIG_DEVICE_MUTABLE + struct device *dev_rw; +#endif + }; }; /** @cond INTERNAL_HIDDEN */ @@ -189,10 +205,7 @@ struct init_entry { #define SYS_INIT_NAMED(name, init_fn_, level, prio) \ static const Z_DECL_ALIGN(struct init_entry) \ Z_INIT_ENTRY_SECTION(level, prio, 0) __used __noasan \ - Z_INIT_ENTRY_NAME(name) = { \ - .init_fn = {.sys = (init_fn_)}, \ - .dev = NULL, \ - } + Z_INIT_ENTRY_NAME(name) = {.init_fn = {.sys = (init_fn_)}} /** @} */ diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index c03351abf98..7bb6e55f1c1 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -137,6 +137,10 @@ ITERABLE_SECTION_RAM(zbus_channel_observation_mask, 1) #endif /* CONFIG_ZBUS */ +#if defined(CONFIG_DEVICE_MUTABLE) + ITERABLE_SECTION_RAM(device_mutable, 4) +#endif + #ifdef CONFIG_USERSPACE _static_kernel_objects_end = .; #endif diff --git a/include/zephyr/linker/common-rom/common-rom-net.ld b/include/zephyr/linker/common-rom/common-rom-net.ld index 71c1c1e089f..2aa46dfecf5 100644 --- a/include/zephyr/linker/common-rom/common-rom-net.ld +++ b/include/zephyr/linker/common-rom/common-rom-net.ld @@ -21,3 +21,7 @@ #if defined(CONFIG_COAP_SERVER) ITERABLE_SECTION_ROM(coap_service, 4) #endif + +#if defined(CONFIG_NET_SOCKETS_SERVICE) + ITERABLE_SECTION_ROM(net_socket_service_desc, 4) +#endif diff --git a/include/zephyr/linker/irq-vector-table-section.ld b/include/zephyr/linker/irq-vector-table-section.ld index 17c483db98f..141eee4d28d 100644 --- a/include/zephyr/linker/irq-vector-table-section.ld +++ b/include/zephyr/linker/irq-vector-table-section.ld @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: Apache-2.0 */ +#if !(LINKER_ZEPHYR_FINAL && CONFIG_ISR_TABLES_LOCAL_DECLARATION) . = ALIGN(CONFIG_ARCH_IRQ_VECTOR_TABLE_ALIGN); KEEP(*(_IRQ_VECTOR_TABLE_SECTION_SYMS)) +#endif /* * Some ARM platforms require this symbol to be placed after the IRQ vector diff --git a/include/zephyr/linker/isr-local-drop-unused.ld b/include/zephyr/linker/isr-local-drop-unused.ld new file mode 100644 index 00000000000..9b6e1272413 --- /dev/null +++ b/include/zephyr/linker/isr-local-drop-unused.ld @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#if LINKER_ZEPHYR_FINAL && CONFIG_ISR_TABLES_LOCAL_DECLARATION +/DISCARD/ : +{ + KEEP(*(.vectors)) + KEEP(*(_IRQ_VECTOR_TABLE_SECTION_SYMS)) +} +#endif 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/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/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. * 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 0b12ccdb684..ba63c136f50 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 @@ -45,11 +45,12 @@ void os_mgmt_client_init(struct os_mgmt_client *client, struct smp_client_object * * @param client OS mgmt client object * @param echo_string Echo string + * @param max_len Max length of @p echo_string * * @return 0 on success. * @return @ref mcumgr_err_t code on failure. */ -int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string); +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string, size_t max_len); /** * @brief Send SMP Reset command. diff --git a/include/zephyr/modem/backend/uart.h b/include/zephyr/modem/backend/uart.h index 0ddef4df734..5f9f99370a0 100644 --- a/include/zephyr/modem/backend/uart.h +++ b/include/zephyr/modem/backend/uart.h @@ -43,6 +43,7 @@ struct modem_backend_uart { const struct device *uart; struct modem_pipe pipe; struct k_work receive_ready_work; + struct k_work transmit_idle_work; union { struct modem_backend_uart_isr isr; diff --git a/include/zephyr/modem/chat.h b/include/zephyr/modem/chat.h index d46ffc7c24a..28a2bc6bf9f 100644 --- a/include/zephyr/modem/chat.h +++ b/include/zephyr/modem/chat.h @@ -240,9 +240,9 @@ struct modem_chat { struct k_sem script_stopped_sem; /* Script sending */ - uint16_t script_send_request_pos; - uint16_t script_send_delimiter_pos; - struct k_work_delayable script_send_work; + enum modem_chat_script_send_state script_send_state; + uint16_t script_send_pos; + struct k_work script_send_work; struct k_work_delayable script_send_timeout_work; /* Match parsing */ @@ -252,8 +252,7 @@ struct modem_chat { uint16_t parse_match_type; /* Process received data */ - struct k_work_delayable process_work; - k_timeout_t process_timeout; + struct k_work receive_work; }; /** @@ -282,8 +281,6 @@ struct modem_chat_config { const struct modem_chat_match *unsol_matches; /** Elements in array of unsolicited matches */ uint16_t unsol_matches_size; - /** Delay from receive ready event to pipe receive occurs */ - k_timeout_t process_timeout; }; /** diff --git a/include/zephyr/modem/cmux.h b/include/zephyr/modem/cmux.h index 4562cb544d9..58959d6136b 100644 --- a/include/zephyr/modem/cmux.h +++ b/include/zephyr/modem/cmux.h @@ -63,10 +63,7 @@ enum modem_cmux_state { enum modem_cmux_receive_state { MODEM_CMUX_RECEIVE_STATE_SOF = 0, - MODEM_CMUX_RECEIVE_STATE_RESYNC_0, - MODEM_CMUX_RECEIVE_STATE_RESYNC_1, - MODEM_CMUX_RECEIVE_STATE_RESYNC_2, - MODEM_CMUX_RECEIVE_STATE_RESYNC_3, + MODEM_CMUX_RECEIVE_STATE_RESYNC, MODEM_CMUX_RECEIVE_STATE_ADDRESS, MODEM_CMUX_RECEIVE_STATE_ADDRESS_CONT, MODEM_CMUX_RECEIVE_STATE_CONTROL, diff --git a/include/zephyr/modem/pipe.h b/include/zephyr/modem/pipe.h index abf8d74918e..60e877e44a3 100644 --- a/include/zephyr/modem/pipe.h +++ b/include/zephyr/modem/pipe.h @@ -25,6 +25,7 @@ extern "C" { enum modem_pipe_event { MODEM_PIPE_EVENT_OPENED = 0, MODEM_PIPE_EVENT_RECEIVE_READY, + MODEM_PIPE_EVENT_TRANSMIT_IDLE, MODEM_PIPE_EVENT_CLOSED, }; @@ -73,7 +74,8 @@ struct modem_pipe { enum modem_pipe_state state; struct k_mutex lock; struct k_condvar condvar; - bool receive_ready_pending; + uint8_t receive_ready_pending : 1; + uint8_t transmit_idle_pending : 1; }; /** @@ -96,6 +98,10 @@ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api * * @retval 0 if pipe was successfully opened or was already open * @retval -errno code otherwise + * + * @warning Be cautious when using this synchronous version of the call. + * It may block the calling thread, which in the case of the system workqueue + * can result in a deadlock until this call times out waiting for the pipe to be open. */ int modem_pipe_open(struct modem_pipe *pipe); @@ -128,25 +134,27 @@ void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback * @brief Transmit data through pipe * * @param pipe Pipe to transmit through - * @param buf Destination for reveived data - * @param size Capacity of destination for recevied data + * @param buf Data to transmit + * @param size Number of bytes to transmit * - * @return Number of bytes placed in pipe + * @retval Number of bytes placed in pipe + * @retval -EPERM if pipe is closed + * @retval -errno code on error * * @warning This call must be non-blocking */ int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size); /** - * @brief Reveive data through pipe + * @brief Receive data through pipe * * @param pipe Pipe to receive from - * @param buf Destination for reveived data - * @param size Capacity of destination for recevied data + * @param buf Destination for received data; must not be already in use in a modem module. + * @param size Capacity of destination for received data * - * @return Number of bytes received from pipe if any - * @return -EPERM if pipe is closed - * @return -errno code on error + * @retval Number of bytes received from pipe + * @retval -EPERM if pipe is closed + * @retval -errno code on error * * @warning This call must be non-blocking */ @@ -166,6 +174,10 @@ void modem_pipe_release(struct modem_pipe *pipe); * * @retval 0 if pipe open was called closed or pipe was already closed * @retval -errno code otherwise + * + * @warning Be cautious when using this synchronous version of the call. + * It may block the calling thread, which in the case of the system workqueue + * can result in a deadlock until this call times out waiting for the pipe to be closed. */ int modem_pipe_close(struct modem_pipe *pipe); @@ -213,6 +225,15 @@ void modem_pipe_notify_closed(struct modem_pipe *pipe); */ void modem_pipe_notify_receive_ready(struct modem_pipe *pipe); +/** + * @brief Notify user of pipe that pipe has no more data to transmit + * + * @param pipe Pipe instance + * + * @note Invoked from instance which initialized the pipe instance + */ +void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe); + /** * @endcond */ diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index a907d1311e1..cd57c560bee 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -238,29 +238,6 @@ 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. * @@ -275,13 +252,6 @@ 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 }; /** @@ -339,6 +309,18 @@ typedef int (*coap_reply_t)(const struct coap_packet *response, struct coap_reply *reply, const struct sockaddr *from); +/** + * @brief CoAP transmission parameters. + */ +struct coap_transmission_parameters { + /** Initial ACK timeout. Value is used as a base value to retry pending CoAP packets. */ + uint32_t ack_timeout; + /** Set CoAP retry backoff factor. A value of 200 means a factor of 2.0. */ + uint16_t coap_backoff_percent; + /** Maximum number of retransmissions. */ + uint8_t max_retransmission; +}; + /** * @brief Represents a request awaiting for an acknowledgment (ACK). */ @@ -350,6 +332,7 @@ struct coap_pending { 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 coap_transmission_parameters params; /**< Transmission parameters */ }; /** @@ -1019,14 +1002,15 @@ void coap_reply_init(struct coap_reply *reply, * confirmation message, initialized with data from @a request * @param request Message waiting for confirmation * @param addr Address to send the retransmission - * @param retries Maximum number of retransmissions of the message. + * @param params Pointer to the CoAP transmission parameters struct, + * or NULL to use default values * * @return 0 in case of success or negative in case of error. */ int coap_pending_init(struct coap_pending *pending, const struct coap_packet *request, const struct sockaddr *addr, - uint8_t retries); + const struct coap_transmission_parameters *params); /** * @brief Returns the next available pending struct, that can be used @@ -1128,6 +1112,15 @@ void coap_pending_clear(struct coap_pending *pending); */ void coap_pendings_clear(struct coap_pending *pendings, size_t len); +/** + * @brief Count number of pending requests. + * + * @param len Number of elements in array. + * @param pendings Array of pending requests. + * @return count of elements where timeout is not zero. + */ +size_t coap_pendings_count(struct coap_pending *pendings, size_t len); + /** * @brief Cancels awaiting for this reply, so it becomes available * again. User responsibility to free the memory associated with data. @@ -1164,6 +1157,20 @@ int coap_resource_notify(struct coap_resource *resource); */ bool coap_request_is_observe(const struct coap_packet *request); +/** + * @brief Get currently active CoAP transmission parameters. + * + * @return CoAP transmission parameters structure. + */ +struct coap_transmission_parameters coap_get_transmission_parameters(void); + +/** + * @brief Set CoAP transmission parameters. + * + * @param params Pointer to the transmission parameters structure. + */ +void coap_set_transmission_parameters(const struct coap_transmission_parameters *params); + #ifdef __cplusplus } #endif diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h index c3de1abee27..e48048d5c26 100644 --- a/include/zephyr/net/coap_client.h +++ b/include/zephyr/net/coap_client.h @@ -83,7 +83,6 @@ struct coap_client_internal_request { uint32_t offset; uint32_t last_id; uint8_t request_tkl; - uint8_t retry_count; bool request_ongoing; struct coap_block_context recv_blk_ctx; struct coap_block_context send_blk_ctx; @@ -131,12 +130,12 @@ int coap_client_init(struct coap_client *client, const char *info); * @param sock Open socket file descriptor. * @param addr the destination address of the request, NULL if socket is already connected. * @param req CoAP request structure - * @param retries How many times to retry or -1 to use default. + * @param params Pointer to transmission parameters structure or NULL to use default values. * @return zero when operation started successfully or negative error code otherwise. */ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries); + struct coap_client_request *req, struct coap_transmission_parameters *params); /** * @} diff --git a/include/zephyr/net/coap_mgmt.h b/include/zephyr/net/coap_mgmt.h new file mode 100644 index 00000000000..f19eec6eb4b --- /dev/null +++ b/include/zephyr/net/coap_mgmt.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief CoAP Events code public header + */ + +#ifndef ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ +#define ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief CoAP Manager Events + * @defgroup coap_mgmt CoAP Manager Events + * @ingroup networking + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +/* CoAP events */ +#define _NET_COAP_LAYER NET_MGMT_LAYER_L4 +#define _NET_COAP_CODE 0x1c0 +#define _NET_COAP_IF_BASE (NET_MGMT_EVENT_BIT | \ + NET_MGMT_LAYER(_NET_COAP_LAYER) | \ + NET_MGMT_LAYER_CODE(_NET_COAP_CODE)) + +struct coap_service; +struct coap_resource; +struct coap_observer; + +/** @endcond */ + +enum net_event_coap_cmd { + /* Service events */ + NET_EVENT_COAP_CMD_SERVICE_STARTED = 1, + NET_EVENT_COAP_CMD_SERVICE_STOPPED, + /* Observer events */ + NET_EVENT_COAP_CMD_OBSERVER_ADDED, + NET_EVENT_COAP_CMD_OBSERVER_REMOVED, +}; + +/** + * @brief coap_mgmt event raised when a service has started + */ +#define NET_EVENT_COAP_SERVICE_STARTED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STARTED) + +/** + * @brief coap_mgmt event raised when a service has stopped + */ +#define NET_EVENT_COAP_SERVICE_STOPPED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_SERVICE_STOPPED) + +/** + * @brief coap_mgmt event raised when an observer has been added to a resource + */ +#define NET_EVENT_COAP_OBSERVER_ADDED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_ADDED) + +/** + * @brief coap_mgmt event raised when an observer has been removed from a resource + */ +#define NET_EVENT_COAP_OBSERVER_REMOVED \ + (_NET_COAP_IF_BASE | NET_EVENT_COAP_CMD_OBSERVER_REMOVED) + +/** + * @brief CoAP Service event structure. + */ +struct net_event_coap_service { + /* The CoAP service for which the event is emitted */ + const struct coap_service *service; +}; + +/** + * @brief CoAP Observer event structure. + */ +struct net_event_coap_observer { + /* The CoAP resource for which the event is emitted */ + struct coap_resource *resource; + /* The observer that is added/removed */ + struct coap_observer *observer; +}; + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_COAP_MGMT_H_ */ diff --git a/include/zephyr/net/coap_service.h b/include/zephyr/net/coap_service.h index 3e3201308b9..b894fecf519 100644 --- a/include/zephyr/net/coap_service.h +++ b/include/zephyr/net/coap_service.h @@ -57,7 +57,9 @@ struct coap_service { }; #define __z_coap_service_define(_name, _host, _port, _flags, _res_begin, _res_end) \ - static struct coap_service_data coap_service_data_##_name; \ + static struct coap_service_data coap_service_data_##_name = { \ + .sock_fd = -1, \ + }; \ const STRUCT_SECTION_ITERABLE(coap_service, _name) = { \ .name = STRINGIFY(_name), \ .host = _host, \ @@ -197,7 +199,7 @@ struct coap_service { * @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. + * @retval -ENOTSUP in case the server has no valid host and port configuration. */ int coap_service_start(const struct coap_service *service); @@ -212,6 +214,18 @@ int coap_service_start(const struct coap_service *service); */ int coap_service_stop(const struct coap_service *service); +/** + * @brief Query the provided @p service running state. + * + * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE. + * + * @param service Pointer to CoAP service + * @retval 1 if the service is running + * @retval 0 if the service is stopped + * @retval negative in case of an error. + */ +int coap_service_is_running(const struct coap_service *service); + /** * @brief Send a CoAP message from the provided @p service . * @@ -221,10 +235,12 @@ int coap_service_stop(const struct coap_service *service); * @param cpkt CoAP Packet to send * @param addr Peer address * @param addr_len Peer address length + * @param params Pointer to transmission parameters structure or NULL to use default values. * @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); + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params); /** * @brief Send a CoAP message from the provided @p resource . @@ -235,10 +251,12 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack * @param cpkt CoAP Packet to send * @param addr Peer address * @param addr_len Peer address length + * @param params Pointer to transmission parameters structure or NULL to use default values. * @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); + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params); /** * @brief Parse a CoAP observe request for the provided @p resource . diff --git a/include/zephyr/net/dhcpv4_server.h b/include/zephyr/net/dhcpv4_server.h new file mode 100644 index 00000000000..18c4af114cd --- /dev/null +++ b/include/zephyr/net/dhcpv4_server.h @@ -0,0 +1,118 @@ +/** @file + * @brief DHCPv4 Server API + */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ +#define ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief DHCPv4 server + * @defgroup dhcpv4_server DHCPv4 server + * @ingroup networking + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +struct net_if; + +#define DHCPV4_CLIENT_ID_MAX_SIZE 20 + +enum dhcpv4_server_addr_state { + DHCPV4_SERVER_ADDR_FREE, + DHCPV4_SERVER_ADDR_RESERVED, + DHCPV4_SERVER_ADDR_ALLOCATED, + DHCPV4_SERVER_ADDR_DECLINED, +}; + +struct dhcpv4_client_id { + uint8_t buf[DHCPV4_CLIENT_ID_MAX_SIZE]; + uint8_t len; +}; + +struct dhcpv4_addr_slot { + enum dhcpv4_server_addr_state state; + struct dhcpv4_client_id client_id; + struct in_addr addr; + uint32_t lease_time; + k_timepoint_t expiry; +}; + +/** @endcond */ + +/** + * @brief Start DHCPv4 server instance on an iface + * + * @details Start DHCPv4 server on a given interface. The server will start + * listening for DHCPv4 Discover/Request messages on the interface and assign + * IPv4 addresses from the configured address pool accordingly. + * + * @param iface A valid pointer on an interface + * @param base_addr First IPv4 address from the DHCPv4 address pool. The number + * of addresses in the pool is configured statically with Kconfig + * (CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT). + * + * @return 0 on success, a negative error code otherwise. + */ +int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr); + +/** + * @brief Stop DHCPv4 server instance on an iface + * + * @details Stop DHCPv4 server on a given interface. DHCPv4 requests will no + * longer be handled on the interface, and all of the allocations are cleared. + * + * @param iface A valid pointer on an interface + * + * @return 0 on success, a negative error code otherwise. + */ +int net_dhcpv4_server_stop(struct net_if *iface); + +/** + * @typedef net_dhcpv4_lease_cb_t + * @brief Callback used while iterating over active DHCPv4 address leases + * + * @param iface Pointer to the network interface + * @param lease Pointer to the DHPCv4 address lease slot + * @param user_data A valid pointer to user data or NULL + */ +typedef void (*net_dhcpv4_lease_cb_t)(struct net_if *iface, + struct dhcpv4_addr_slot *lease, + void *user_data); + +/** + * @brief Iterate over all DHCPv4 address leases on a given network interface + * and call callback for each lease. In case no network interface is provided + * (NULL interface pointer), will iterate over all interfaces running DHCPv4 + * server instance. + * + * @param iface Pointer to the network interface, can be NULL + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +int net_dhcpv4_server_foreach_lease(struct net_if *iface, + net_dhcpv4_lease_cb_t cb, + void *user_data); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_DHCPV4_SERVER_H_ */ diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index a47ec767a60..faa6cf7fc0b 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -179,6 +179,9 @@ enum ethernet_hw_caps { /** TXTIME supported */ ETHERNET_TXTIME = BIT(19), + + /** TX-Injection supported */ + ETHERNET_TXINJECTION_MODE = BIT(20), }; /** @cond INTERNAL_HIDDEN */ @@ -196,6 +199,8 @@ enum ethernet_config_type { ETHERNET_CONFIG_TYPE_PRIORITY_QUEUES_NUM, ETHERNET_CONFIG_TYPE_FILTER, ETHERNET_CONFIG_TYPE_PORTS_NUM, + ETHERNET_CONFIG_TYPE_T1S_PARAM, + ETHERNET_CONFIG_TYPE_TXINJECTION_MODE, }; enum ethernet_qav_param_type { @@ -206,7 +211,53 @@ enum ethernet_qav_param_type { ETHERNET_QAV_PARAM_TYPE_STATUS, }; +enum ethernet_t1s_param_type { + ETHERNET_T1S_PARAM_TYPE_PLCA_CONFIG, +}; + /** @endcond */ +struct ethernet_t1s_param { + /** Type of T1S parameter */ + enum ethernet_t1s_param_type type; + union { + /* PLCA is the Physical Layer (PHY) Collision + * Avoidance technique employed with multidrop + * 10Base-T1S standard. + * + * The PLCA parameters are described in standard [1] + * as registers in memory map 4 (MMS = 4) (point 9.6). + * + * IDVER (PLCA ID Version) + * CTRL0 (PLCA Control 0) + * CTRL1 (PLCA Control 1) + * STATUS (PLCA Status) + * TOTMR (PLCA TO Control) + * BURST (PLCA Burst Control) + * + * Those registers are implemented by each OA TC6 + * compliant vendor (like for e.g. LAN865x - e.g. [2]). + * + * Documents: + * [1] - "OPEN Alliance 10BASE-T1x MAC-PHY Serial + * Interface" (ver. 1.1) + * [2] - "DS60001734C" - LAN865x data sheet + */ + struct { + /** T1S PLCA enabled */ + bool enable; + /** T1S PLCA node id range: 0 to 254 */ + uint8_t node_id; + /** T1S PLCA node count range: 1 to 255 */ + uint8_t node_count; + /** T1S PLCA burst count range: 0x0 to 0xFF */ + uint8_t burst_count; + /** T1S PLCA burst timer */ + uint8_t burst_timer; + /** T1S PLCA TO value */ + uint8_t to_timer; + } plca; + }; +}; struct ethernet_qav_param { /** ID of the priority queue to use */ @@ -395,6 +446,7 @@ struct ethernet_config { bool auto_negotiation; bool full_duplex; bool promisc_mode; + bool txinjection_mode; struct { bool link_10bt; @@ -404,6 +456,7 @@ struct ethernet_config { struct net_eth_addr mac_address; + struct ethernet_t1s_param t1s_param; struct ethernet_qav_param qav_param; struct ethernet_qbv_param qbv_param; struct ethernet_qbu_param qbu_param; @@ -981,6 +1034,17 @@ void net_eth_carrier_off(struct net_if *iface); */ int net_eth_promisc_mode(struct net_if *iface, bool enable); +/** + * @brief Set TX-Injection mode either ON or OFF. + * + * @param iface Network interface + * + * @param enable on (true) or off (false) + * + * @return 0 if mode set or unset was successful, <0 otherwise. + */ +int net_eth_txinjection_mode(struct net_if *iface, bool enable); + /** * @brief Return PTP clock that is tied to this ethernet network interface. * diff --git a/include/zephyr/net/ethernet_mgmt.h b/include/zephyr/net/ethernet_mgmt.h index 9d95fa7a42e..18039e9f3aa 100644 --- a/include/zephyr/net/ethernet_mgmt.h +++ b/include/zephyr/net/ethernet_mgmt.h @@ -51,6 +51,9 @@ enum net_request_ethernet_cmd { NET_REQUEST_ETHERNET_CMD_GET_QBV_PARAM, NET_REQUEST_ETHERNET_CMD_GET_QBU_PARAM, NET_REQUEST_ETHERNET_CMD_GET_TXTIME_PARAM, + NET_REQUEST_ETHERNET_CMD_SET_T1S_PARAM, + NET_REQUEST_ETHERNET_CMD_SET_TXINJECTION_MODE, + NET_REQUEST_ETHERNET_CMD_GET_TXINJECTION_MODE, }; #define NET_REQUEST_ETHERNET_SET_AUTO_NEGOTIATION \ @@ -128,6 +131,21 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBU_PARAM); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXTIME_PARAM); +#define NET_REQUEST_ETHERNET_SET_T1S_PARAM \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_T1S_PARAM) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_T1S_PARAM); + +#define NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_SET_TXINJECTION_MODE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE); + +#define NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE \ + (_NET_ETHERNET_BASE | NET_REQUEST_ETHERNET_CMD_GET_TXINJECTION_MODE) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE); + struct net_eth_addr; struct ethernet_qav_param; struct ethernet_qbv_param; @@ -139,6 +157,7 @@ struct ethernet_req_params { bool auto_negotiation; bool full_duplex; bool promisc_mode; + bool txinjection_mode; struct { bool link_10bt; @@ -152,6 +171,7 @@ struct ethernet_req_params { struct ethernet_qbv_param qbv_param; struct ethernet_qbu_param qbu_param; struct ethernet_txtime_param txtime_param; + struct ethernet_t1s_param t1s_param; int priority_queues_num; int ports_num; diff --git a/include/zephyr/net/ieee802154_pkt.h b/include/zephyr/net/ieee802154_pkt.h index d5fdc712b49..3270f994248 100644 --- a/include/zephyr/net/ieee802154_pkt.h +++ b/include/zephyr/net/ieee802154_pkt.h @@ -59,12 +59,6 @@ struct net_pkt_cb_ieee802154 { */ uint8_t rssi; }; -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - /* TX packets */ - struct { - int8_t txpwr; /* TX power in dBm. */ - }; -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ }; /* Flags */ @@ -185,18 +179,6 @@ static inline void net_pkt_set_ieee802154_rssi_dbm(struct net_pkt *pkt, int16_t CODE_UNREACHABLE; } -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) -static inline int8_t net_pkt_ieee802154_txpwr(struct net_pkt *pkt) -{ - return net_pkt_cb_ieee802154(pkt)->txpwr; -} - -static inline void net_pkt_set_ieee802154_txpwr(struct net_pkt *pkt, int8_t txpwr) -{ - net_pkt_cb_ieee802154(pkt)->txpwr = txpwr; -} -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ - static inline bool net_pkt_ieee802154_ack_fpb(struct net_pkt *pkt) { return net_pkt_cb_ieee802154(pkt)->ack_fpb; diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 59608fac391..259d67b4321 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -592,11 +592,16 @@ struct ieee802154_filter { * IEEE802154_CONFIG_MAC_KEYS. */ struct ieee802154_key { + /** Key material */ uint8_t *key_value; + /** Initial value of frame counter associated with the key, see section 9.4.3 */ uint32_t key_frame_counter; + /** Indicates if per-key frame counter should be used, see section 9.4.3 */ bool frame_counter_per_key; + /** Key Identifier Mode, see section 9.4.2.3, Table 9-7 */ uint8_t key_id_mode; - uint8_t key_index; + /** Key Identifier, see section 9.4.4 */ + uint8_t *key_id; }; /** IEEE 802.15.4 Transmission mode. */ @@ -1236,6 +1241,15 @@ struct ieee802154_config { * in CPU byte order */ uint16_t short_addr; + + /** + * Flag for purging enh ACK header IEs. + * When flag is set to true, driver should remove all existing + * header IEs, and all other entries in config should be ignored. + * This means that purging current header IEs and + * configuring a new one in the same call is not allowed. + */ + bool purge_ie; } ack_ie; }; }; diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index a57b5542f88..c643c32f0bf 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -134,6 +134,22 @@ typedef void (*lwm2m_ctx_event_cb_t)(struct lwm2m_ctx *ctx, enum lwm2m_rd_client_event event); +/** + * @brief Different traffic states of the LwM2M socket. + * + * This information can be used to give hints for the network interface + * that can decide what kind of power management should be used. + * + * These hints are given from CoAP layer messages, so usage of DTLS might affect the + * actual number of expected datagrams. + */ +enum lwm2m_socket_states { + LWM2M_SOCKET_STATE_ONGOING, /**< Ongoing traffic is expected. */ + LWM2M_SOCKET_STATE_ONE_RESPONSE, /**< One response is expected for the next message. */ + LWM2M_SOCKET_STATE_LAST, /**< Next message is the last one. */ + LWM2M_SOCKET_STATE_NO_DATA, /**< No more data is expected. */ +}; + /** * @brief LwM2M context structure to maintain information for a single * LwM2M connection. @@ -249,6 +265,14 @@ struct lwm2m_ctx { * copied into the actual resource buffer. */ uint8_t validate_buf[CONFIG_LWM2M_ENGINE_VALIDATION_BUFFER_SIZE]; + + /** + * Callback to indicate transmission states. + * Client application may request LwM2M engine to indicate hints about + * transmission states and use that information to control various power + * saving modes. + */ + void (*set_socket_state)(int fd, enum lwm2m_socket_states state); }; /** @@ -551,7 +575,6 @@ void lwm2m_firmware_set_cancel_cb_inst(uint16_t obj_inst_id, lwm2m_engine_user_c */ lwm2m_engine_user_cb_t lwm2m_firmware_get_cancel_cb_inst(uint16_t obj_inst_id); -#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set data callback to handle firmware update execute events. * @@ -588,8 +611,6 @@ void lwm2m_firmware_set_update_cb_inst(uint16_t obj_inst_id, lwm2m_engine_execut */ lwm2m_engine_execute_cb_t lwm2m_firmware_get_update_cb_inst(uint16_t obj_inst_id); #endif -#endif - #if defined(CONFIG_LWM2M_SWMGMT_OBJ_SUPPORT) || defined(__DOXYGEN__) @@ -988,11 +1009,16 @@ int lwm2m_engine_set_u64(const char *pathstr, uint64_t value); /** * @brief Set resource (instance) value (u64) * + * @deprecated Unsigned 64bit value type does not exits. + * This is internally handled as a int64_t. + * Use lwm2m_set_s64() instead. + * * @param[in] path LwM2M path as a struct * @param[in] value u64 value * * @return 0 for success or negative in case of error. */ +__deprecated int lwm2m_set_u64(const struct lwm2m_obj_path *path, uint64_t value); /** @@ -1314,11 +1340,16 @@ int lwm2m_engine_get_u64(const char *pathstr, uint64_t *value); /** * @brief Get resource (instance) value (u64) * + * @deprecated Unsigned 64bit value type does not exits. + * This is internally handled as a int64_t. + * Use lwm2m_get_s64() instead. + * @param[in] path LwM2M path as a struct * @param[out] value u64 buffer to copy data into * * @return 0 for success or negative in case of error. */ +__deprecated int lwm2m_get_u64(const struct lwm2m_obj_path *path, uint64_t *value); /** @@ -2075,6 +2106,7 @@ enum lwm2m_rd_client_event { LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, LWM2M_RD_CLIENT_EVENT_REG_UPDATE, LWM2M_RD_CLIENT_EVENT_DEREGISTER, + LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED, }; /** diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index f1071af64f2..906cd8f6be6 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -356,6 +356,9 @@ struct mqtt_sec_config { /** Indicates the list of security tags to be used for the session. */ const sec_tag_t *sec_tag_list; + /** Indicates the preference for enabling TLS session caching. */ + int session_cache; + /** Peer hostname for ceritificate verification. * May be NULL to skip hostname verification. */ @@ -363,6 +366,9 @@ struct mqtt_sec_config { /** Indicates the preference for copying certificates to the heap. */ int cert_nocopy; + + /** Set socket to native TLS */ + bool set_native_tls; }; /** @brief MQTT transport type. */ diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 788c3316391..f1e5be67cf7 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -2217,6 +2217,15 @@ struct in_addr *net_if_ipv4_get_ll(struct net_if *iface, struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface, enum net_addr_state addr_state); +/** + * @brief Get IPv4 netmask of an interface. + * + * @param iface Interface to use. + * + * @return The netmask set on the interface, unspecified address if not found. + */ +struct in_addr net_if_ipv4_get_netmask(struct net_if *iface); + /** * @brief Set IPv4 netmask for an interface. * diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 91f9193bbf8..f32753a7952 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h new file mode 100644 index 00000000000..0023cd9bd48 --- /dev/null +++ b/include/zephyr/net/socket_ncs.h @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ + +/** + * @file + * @brief NCS specific additions to the BSD sockets API definitions + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* When CONFIG_NET_SOCKETS_OFFLOAD is enabled, offloaded sockets take precedence + * when creating a new socket. Combine this flag with a socket type when + * creating a socket, to enforce native socket creation (e. g. SOCK_STREAM | SOCK_NATIVE). + * If it's desired to create a native TLS socket, but still offload the + * underlying TCP/UDP socket, use e. g. SOCK_STREAM | SOCK_NATIVE_TLS. + */ +#define SOCK_NATIVE 0x80000000 +#define SOCK_NATIVE_TLS 0x40000000 + +/* NCS specific TLS level socket options */ + +/** Socket option to set DTLS handshake timeout, specifically for nRF sockets. + * The option accepts an integer, indicating the total handshake timeout, + * including retransmissions, in seconds. + * Accepted values for the option are: 1, 3, 7, 15, 31, 63, 123. + */ +#define TLS_DTLS_HANDSHAKE_TIMEO 18 + +/** Socket option to save DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_SAVE 19 + +/** Socket option to load DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_LOAD 20 + +/** Socket option to get result of latest TLS/DTLS completed handshakes end status, + * specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0 and 1. + */ +#define TLS_DTLS_HANDSHAKE_STATUS 21 + +/* Valid values for TLS_SESSION_CACHE option */ +#define TLS_SESSION_CACHE_DISABLED 0 /**< Disable TLS session caching. */ +#define TLS_SESSION_CACHE_ENABLED 1 /**< Enable TLS session caching. */ + +/* Valid values for TLS_DTLS_HANDSHAKE_TIMEO option */ +#define TLS_DTLS_HANDSHAKE_TIMEO_NONE 0 /**< No timeout */ +#define TLS_DTLS_HANDSHAKE_TIMEO_1S 1 /**< 1 second */ +#define TLS_DTLS_HANDSHAKE_TIMEO_3S 3 /**< 1s + 2s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_7S 7 /**< 1s + 2s + 4s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_15S 15 /**< 1s + 2s + 4s + 8s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_31S 31 /**< 1s + 2s + 4s + 8s + 16s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_63S 63 /**< 1s + 2s + 4s + 8s + 16s + 32s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_123S 123 /**< 1s + 2s + 4s + 8s + 16s + 32s + 60s */ + +/* Valid values for TLS_DTLS_HANDSHAKE_STATUS option */ +#define TLS_DTLS_HANDSHAKE_STATUS_FULL 0 +#define TLS_DTLS_HANDSHAKE_STATUS_CACHED 1 + +/* NCS specific socket options */ + +/** sockopt: enable sending data as part of exceptional events */ +#define SO_EXCEPTIONAL_DATA 33 +/** sockopt: Keep socket open when its PDN connection is lost + * or the device is put into flight mode. + */ +#define SO_KEEPOPEN 34 +/** sockopt: bind to PDN */ +#define SO_BINDTOPDN 40 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * application will not send any more data. + * + * @note This socket option requires the socket to be connected. + * + * @deprecated use @ref SO_RAI with value @ref RAI_NO_DATA instead. + */ +#define SO_RAI_NO_DATA 50 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * next call to send/sendto will be the last one for some time. + * + * @deprecated use @ref SO_RAI with value @ref RAI_LAST instead. + */ +#define SO_RAI_LAST 51 +/** sockopt: Release Assistance Indication feature: This will indicate that + * after the next call to send/sendto, the application is expecting to receive + * one more data packet before this socket will not be used again for some time. + * + * @deprecated use @ref SO_RAI with value @ref RAI_ONE_RESP instead. + */ +#define SO_RAI_ONE_RESP 52 +/** sockopt: Release Assistance Indication feature: If a client application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call which will keep the network up longer. + * + * @deprecated use @ref SO_RAI with value @ref RAI_ONGOING instead. + */ +#define SO_RAI_ONGOING 53 +/** sockopt: Release Assistance Indication feature: If a server application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call. + * + * @deprecated use @ref SO_RAI with value @ref RAI_WAIT_MORE instead. + */ +#define SO_RAI_WAIT_MORE 54 + +/** sockopt: Release assistance indication (RAI). + * The option accepts an integer, indicating the type of RAI. + * Accepted values for the option are: @ref RAI_NO_DATA, @ref RAI_LAST, @ref RAI_ONE_RESP, + * @ref RAI_ONGOING, @ref RAI_WAIT_MORE. + */ +#define SO_RAI 61 + +/** Release assistance indication (RAI). + * Indicate that the application does not intend to send more data. + * This applies immediately and lets the modem exit connected mode more + * quickly. + * + * @note This requires the socket to be connected. + */ +#define RAI_NO_DATA 1 +/** Release assistance indication (RAI). + * Indicate that the application does not intend to send more data + * after the next call to send() or sendto(). + * This lets the modem exit connected mode more quickly after sending the data. + */ +#define RAI_LAST 2 +/** Release assistance indication (RAI). + * Indicate that the application is expecting to receive just one data packet + * after the next call to send() or sendto(). + * This lets the modem exit connected mode more quickly after having received the data. + */ +#define RAI_ONE_RESP 3 +/** Release assistance indication (RAI). + * Indicate that the socket is in active use by a client application. + * This lets the modem stay in connected mode longer. + */ +#define RAI_ONGOING 4 +/** Release assistance indication (RAI). + * Indicate that the socket is in active use by a server application. + * This lets the modem stay in connected mode longer. + */ +#define RAI_WAIT_MORE 5 + +/* NCS specific IPPROTO_ALL level socket options */ + +/** IPv4 and IPv6 protocol level (pseudo-val) for nRF sockets. */ +#define IPPROTO_ALL 512 +/** sockopt: disable all replies to unexpected traffics */ +#define SO_SILENCE_ALL 30 + +/* NCS specific IPPROTO_IP level socket options */ + +/** sockopt: enable IPv4 ICMP replies */ +#define SO_IP_ECHO_REPLY 31 + +/* NCS specific IPPROTO_IPV6 level socket options */ + +/** sockopt: enable IPv6 ICMP replies */ +#define SO_IPV6_ECHO_REPLY 32 + +/* NCS specific TCP level socket options */ + +/** sockopt: Configurable TCP server session timeout in minutes. + * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). + */ +#define SO_TCP_SRV_SESSTIMEO 55 + +/* NCS specific gettaddrinfo() flags */ + +/** Assume `service` contains a Packet Data Network (PDN) ID. + * When specified together with the AI_NUMERICSERV flag, + * `service` shall be formatted as follows: "port:pdn_id" + * where "port" is the port number and "pdn_id" is the PDN ID. + * Example: "8080:1", port 8080 PDN ID 1. + * Example: "42:0", port 42 PDN ID 0. + */ +#define AI_PDNSERV 0x1000 + +/* NCS specific send() and sendto() flags */ + +/** Request a blocking send operation until the request is acknowledged. + * When used in send() or sendto(), the request will not return until the + * send operation is completed by lower layers, or until the timeout, given by the SO_SNDTIMEO + * socket option, is reached. Valid timeout values are 1 to 600 seconds. + */ +#define MSG_WAITACK 0x200 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ */ diff --git a/include/zephyr/net/socket_service.h b/include/zephyr/net/socket_service.h new file mode 100644 index 00000000000..a4e21f00a33 --- /dev/null +++ b/include/zephyr/net/socket_service.h @@ -0,0 +1,246 @@ +/** + * @file + * @brief BSD Socket service API + * + * API can be used to install a k_work that is called + * if there is data received to a socket. + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ + +/** + * @brief BSD socket service API + * @defgroup bsd_socket_service BSD socket service API + * @ingroup networking + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * This struct contains information which socket triggered + * calls to the callback function. + */ +struct net_socket_service_event { + /** k_work that is done when there is desired activity in file descriptor. */ + struct k_work work; + /** Callback to be called for desired socket activity */ + k_work_handler_t callback; + /** Socket information that triggered this event. */ + struct zsock_pollfd event; + /** User data */ + void *user_data; + /** Service back pointer */ + struct net_socket_service_desc *svc; +}; + +/** + * Main structure holding socket service configuration information. + * The k_work item is created so that when there is data coming + * to those fds, the k_work callback is then called. + * The workqueue can be set NULL in which case system workqueue is used. + * The service descriptor should be created at built time, and then used + * as a parameter to register the sockets to be monitored. + * User should create needed sockets and then setup the poll struct and + * then register the sockets to be monitored at runtime. + */ +struct net_socket_service_desc { +#if CONFIG_NET_SOCKETS_LOG_LEVEL >= LOG_LEVEL_DBG + /** + * Owner name. This can be used in debugging to see who has + * registered this service. + */ + const char *owner; +#endif + /** Workqueue where the work is submitted. */ + struct k_work_q *work_q; + /** Pointer to the list of services that we are listening */ + struct net_socket_service_event *pev; + /** Length of the pollable socket array for this service. */ + int pev_len; + /** Where are my pollfd entries in the global list */ + int *idx; +}; + +#define __z_net_socket_svc_get_name(_svc_id) __z_net_socket_service_##_svc_id +#define __z_net_socket_svc_get_idx(_svc_id) __z_net_socket_service_idx_##_svc_id +#define __z_net_socket_svc_get_owner __FILE__ ":" STRINGIFY(__LINE__) + +extern void net_socket_service_callback(struct k_work *work); + +#if CONFIG_NET_SOCKETS_LOG_LEVEL >= LOG_LEVEL_DBG +#define NET_SOCKET_SERVICE_OWNER .owner = __z_net_socket_svc_get_owner, +#else +#define NET_SOCKET_SERVICE_OWNER +#endif + +#define NET_SOCKET_SERVICE_CALLBACK_MODE(_flag) \ + IF_ENABLED(_flag, \ + (.work = Z_WORK_INITIALIZER(net_socket_service_callback),)) + +#define __z_net_socket_service_define(_name, _work_q, _cb, _count, _async, ...) \ + static int __z_net_socket_svc_get_idx(_name); \ + static struct net_socket_service_event \ + __z_net_socket_svc_get_name(_name)[_count] = { \ + [0 ... ((_count) - 1)] = { \ + .event.fd = -1, /* Invalid socket */ \ + NET_SOCKET_SERVICE_CALLBACK_MODE(_async) \ + .callback = _cb, \ + } \ + }; \ + COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), (), __VA_ARGS__) \ + const STRUCT_SECTION_ITERABLE(net_socket_service_desc, _name) = { \ + NET_SOCKET_SERVICE_OWNER \ + .work_q = (_work_q), \ + .pev = __z_net_socket_svc_get_name(_name), \ + .pev_len = (_count), \ + .idx = &__z_net_socket_svc_get_idx(_name), \ + } + +/** + * @brief Statically define a network socket service. + * The user callback is called asynchronously for this service meaning that + * the service API will not wait until the user callback returns before continuing + * with next socket service. + * + * The socket service can be accessed outside the module where it is defined using: + * + * @code extern struct net_socket_service_desc ; @endcode + * + * @note This macro cannot be used together with a static keyword. + * If such a use-case is desired, use NET_SOCKET_SERVICE_ASYNC_DEFINE_STATIC + * instead. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_ASYNC_DEFINE(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 1) + +/** + * @brief Statically define a network socket service in a private (static) scope. + * The user callback is called asynchronously for this service meaning that + * the service API will not wait until the user callback returns before continuing + * with next socket service. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_ASYNC_DEFINE_STATIC(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 1, static) + +/** + * @brief Statically define a network socket service. + * The user callback is called synchronously for this service meaning that + * the service API will wait until the user callback returns before continuing + * with next socket service. + * + * The socket service can be accessed outside the module where it is defined using: + * + * @code extern struct net_socket_service_desc ; @endcode + * + * @note This macro cannot be used together with a static keyword. + * If such a use-case is desired, use NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC + * instead. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_SYNC_DEFINE(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 0) + +/** + * @brief Statically define a network socket service in a private (static) scope. + * The user callback is called synchronously for this service meaning that + * the service API will wait until the user callback returns before continuing + * with next socket service. + * + * @param name Name of the service. + * @param work_q Pointer to workqueue where the work is done. Can be null in which case + * system workqueue is used. + * @param cb Callback function that is called for socket activity. + * @param count How many pollable sockets is needed for this service. + */ +#define NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(name, work_q, cb, count) \ + __z_net_socket_service_define(name, work_q, cb, count, 0, static) + +/** + * @brief Register pollable sockets. + * + * @param service Pointer to a service description. + * @param fds Socket array to poll. + * @param len Length of the socket array. + * @param user_data User specific data. + * + * @retval 0 No error + * @retval -ENOENT Service is not found. + * @retval -ENINVAL Invalid parameter. + */ +__syscall int net_socket_service_register(const struct net_socket_service_desc *service, + struct zsock_pollfd *fds, int len, void *user_data); + +/** + * @brief Unregister pollable sockets. + * + * @param service Pointer to a service description. + * + * @retval 0 No error + * @retval -ENOENT Service is not found. + * @retval -ENINVAL Invalid parameter. + */ +static inline int net_socket_service_unregister(const struct net_socket_service_desc *service) +{ + return net_socket_service_register(service, NULL, 0, NULL); +} + +/** + * @typedef net_socket_service_cb_t + * @brief Callback used while iterating over socket services. + * + * @param svc Pointer to current socket service. + * @param user_data A valid pointer to user data or NULL + */ +typedef void (*net_socket_service_cb_t)(const struct net_socket_service_desc *svc, + void *user_data); + +/** + * @brief Go through all the socket services and call callback for each service. + * + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +void net_socket_service_foreach(net_socket_service_cb_t cb, void *user_data); + +#ifdef __cplusplus +} +#endif + +#include + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_SERVICE_H_ */ diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 5c7d5b493fa..c49d6ad0f66 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -345,6 +345,14 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; +/** Wi-Fi Target Wake Time (TWT) teradown status. */ +enum wifi_twt_teardown_status { + /** TWT teardown success */ + WIFI_TWT_TEARDOWN_SUCCESS = 0, + /** TWT teardown failure */ + WIFI_TWT_TEARDOWN_FAILED, +}; + /** @cond INTERNAL_HIDDEN */ static const char * const wifi_twt_err_code_tbl[] = { [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index faf83b42b84..c287db650cb 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -81,6 +81,10 @@ enum net_request_wifi_cmd { NET_REQUEST_WIFI_CMD_PACKET_FILTER, /** Set or get Wi-Fi channel for Monitor or TX-Injection mode */ NET_REQUEST_WIFI_CMD_CHANNEL, + /** Disconnect a STA from AP */ + NET_REQUEST_WIFI_CMD_AP_STA_DISCONNECT, + /** Get Wi-Fi driver and Firmware versions */ + NET_REQUEST_WIFI_CMD_VERSION, NET_REQUEST_WIFI_CMD_MAX }; @@ -158,6 +162,16 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PACKET_FILTER); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL); +#define NET_REQUEST_WIFI_AP_STA_DISCONNECT \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_AP_STA_DISCONNECT) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT); + +#define NET_REQUEST_WIFI_VERSION \ + (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_VERSION) + +NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION); + /** Wi-Fi management events */ enum net_event_wifi_cmd { /** Scan results available */ @@ -180,6 +194,14 @@ 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, + /** 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 \ @@ -209,6 +231,26 @@ 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) + +#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) + +/** Wi-Fi version */ +struct wifi_version { + /** Driver version */ + const char *drv_version; + /** Firmware version */ + const char *fw_version; +}; + /** * @brief Wi-Fi structure to uniquely identify a band-channel pair */ @@ -321,9 +363,66 @@ struct wifi_connect_req_params { int timeout; }; +/** Wi-Fi connect result codes. To be overlaid on top of \ref wifi_status + * in the connect result event for detailed status. + */ +enum wifi_conn_status { + /** Connection successful */ + WIFI_STATUS_CONN_SUCCESS = 0, + /** Connection failed - generic failure */ + WIFI_STATUS_CONN_FAIL, + /** Connection failed - wrong password */ + WIFI_STATUS_CONN_WRONG_PASSWORD, + /** Connection timed out */ + WIFI_STATUS_CONN_TIMEOUT, + /** Connection failed - AP not found */ + WIFI_STATUS_CONN_AP_NOT_FOUND, +}; + +/** Wi-Fi disconnect reason codes. To be overlaid on top of \ref wifi_status + * in the disconnect result event for detailed reason. + */ +enum wifi_disconn_reason { + /** Unspecified reason */ + WIFI_REASON_DISCONN_UNSPECIFIED = 0, + /** Disconnected due to user request */ + WIFI_REASON_DISCONN_USER_REQUEST, + /** Disconnected due to AP leaving */ + WIFI_REASON_DISCONN_AP_LEAVING, + /** Disconnected due to inactivity */ + 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 { - int status; + union { + int status; + enum wifi_conn_status conn_status; + enum wifi_disconn_reason disconn_reason; + enum wifi_ap_status ap_status; + }; }; /** Wi-Fi interface status */ @@ -393,6 +492,8 @@ struct wifi_twt_params { enum wifi_twt_setup_cmd setup_cmd; /** TWT setup response status, see enum wifi_twt_setup_resp_status */ enum wifi_twt_setup_resp_status resp_status; + /** TWT teardown cmd status, see enum wifi_twt_teardown_status */ + enum wifi_twt_teardown_status teardown_status; /** Dialog token, used to map requests to responses */ uint8_t dialog_token; /** Flow ID, used to map setup with teardown */ @@ -412,6 +513,12 @@ struct wifi_twt_params { bool announce; /** Wake up time */ uint32_t twt_wake_interval; + /* Wake ahead notification is sent earlier than + * TWT Service period (SP) start based on this duration. + * This should give applications ample time to + * prepare the data before TWT SP starts. + */ + uint32_t twt_wake_ahead_duration; } setup; /** Teardown specific parameters */ struct { @@ -428,6 +535,7 @@ struct wifi_twt_params { #define WIFI_MAX_TWT_INTERVAL_US (LONG_MAX - 1) /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 +#define WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US (LONG_MAX - 1) /** Wi-Fi TWT flow information */ struct wifi_twt_flow_info { @@ -449,6 +557,8 @@ struct wifi_twt_flow_info { bool announce; /** Wake up time */ uint32_t twt_wake_interval; + /* wake ahead duration */ + uint32_t twt_wake_ahead_duration; }; /** Wi-Fi power save configuration */ @@ -469,6 +579,22 @@ enum wifi_mgmt_op { WIFI_MGMT_SET = 1, }; +#define MAX_REG_CHAN_NUM 42 + +/** Per-channel regulatory attributes */ +struct wifi_reg_chan_info { + /** Center frequency in MHz */ + unsigned short center_frequency; + /** Maximum transmission power (in dBm) */ + unsigned short max_power:8; + /** Is channel supported or not */ + unsigned short supported:1; + /** Passive transmissions only */ + unsigned short passive_only:1; + /** Is a DFS channel */ + unsigned short dfs:1; +} __packed; + /** Regulatory domain information or configuration */ struct wifi_reg_domain { /* Regulatory domain operation */ @@ -477,6 +603,10 @@ struct wifi_reg_domain { bool force; /** Country code: ISO/IEC 3166-1 alpha-2 */ uint8_t country_code[WIFI_COUNTRY_CODE_LEN]; + /** Number of channels supported */ + unsigned int num_channels; + /** Channels information */ + struct wifi_reg_chan_info *chan_info; }; /** Wi-Fi TWT sleep states */ @@ -501,6 +631,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; @@ -510,6 +652,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 */ @@ -614,6 +757,14 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*ap_disable)(const struct device *dev); + /** Disconnect a STA from AP + * + * @param dev Pointer to the device structure for the driver instance. + * @param mac MAC address of the STA to disconnect + * + * @return 0 if ok, < 0 if error + */ + int (*ap_sta_disconnect)(const struct device *dev, const uint8_t *mac); /** Get interface status * * @param dev Pointer to the device structure for the driver instance. @@ -688,6 +839,19 @@ struct wifi_mgmt_ops { * @return 0 if ok, < 0 if error */ int (*channel)(const struct device *dev, struct wifi_channel_info *channel); + /** Get Version of WiFi driver and Firmware + * + * The driver that implements the get_version function must not use stack to allocate the + * version information pointers that are returned as params struct members. + * The version pointer parameters should point to a static memory either in ROM (preferred) + * or in RAM. + * + * @param dev Pointer to the device structure for the driver instance + * @param params Version parameters + * + * @return 0 if ok, < 0 if error + */ + int (*get_version)(const struct device *dev, struct wifi_version *params); }; /** Wi-Fi management offload API */ @@ -768,6 +932,35 @@ 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); + +/** 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/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index c16eef0e5b2..537db787648 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -103,6 +103,49 @@ int wifi_utils_parse_scan_chan(char *scan_chan_str, struct wifi_band_channel *chan, uint8_t max_channels); + +/** + * @brief Validate a channel against a band. + * + * @param band Band to validate the channel against. + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan(uint8_t band, + uint16_t chan); + +/** + * @brief Validate a channel against the 2.4 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_2g(uint16_t chan); + +/** + * @brief Validate a channel against the 5 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_5g(uint16_t chan); + +/** + * @brief Validate a channel against the 6 GHz band. + * + * @param chan Channel to validate. + * + * @retval true if the channel is valid for the band. + * @retval false if the channel is not valid for the band. + */ +bool wifi_utils_validate_chan_6g(uint16_t chan); + /** * @} */ 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/include/zephyr/sw_isr_table.h b/include/zephyr/sw_isr_table.h index f43efafad49..7b1bfddb2cb 100644 --- a/include/zephyr/sw_isr_table.h +++ b/include/zephyr/sw_isr_table.h @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -56,6 +57,9 @@ struct _irq_parent_entry { * uses it to create the IRQ vector table and the _sw_isr_table. * * More discussion in include/linker/intlist.ld + * + * This is a version used when CONFIG_ISR_TABLES_LOCAL_DECLARATION is disabled. + * See _isr_list_sname used otherwise. */ struct _isr_list { /** IRQ line number */ @@ -68,14 +72,27 @@ struct _isr_list { const void *param; }; -#ifdef CONFIG_SHARED_INTERRUPTS -struct z_shared_isr_client { - void (*isr)(const void *arg); - const void *arg; +/* + * Data structure created in a special binary .intlist section for each + * configured interrupt. gen_isr_tables.py pulls this out of the binary and + * uses it to create linker script chunks that would place interrupt table entries + * in the right place in the memory. + * + * This is a version used when CONFIG_ISR_TABLES_LOCAL_DECLARATION is enabled. + * See _isr_list used otherwise. + */ +struct _isr_list_sname { + /** IRQ line number */ + int32_t irq; + /** Flags for this IRQ, see ISR_FLAG_* definitions */ + int32_t flags; + /** The section name */ + const char sname[]; }; +#ifdef CONFIG_SHARED_INTERRUPTS struct z_shared_isr_table_entry { - struct z_shared_isr_client clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS]; + struct _isr_table_entry clients[CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS]; size_t client_num; }; @@ -90,6 +107,90 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; #define _MK_ISR_NAME(x, y) __MK_ISR_NAME(x, y) #define __MK_ISR_NAME(x, y) __isr_ ## x ## _irq_ ## y + +#if IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) + +#define _MK_ISR_ELEMENT_NAME(func, id) __MK_ISR_ELEMENT_NAME(func, id) +#define __MK_ISR_ELEMENT_NAME(func, id) __isr_table_entry_ ## func ## _irq_ ## id + +#define _MK_IRQ_ELEMENT_NAME(func, id) __MK_ISR_ELEMENT_NAME(func, id) +#define __MK_IRQ_ELEMENT_NAME(func, id) __irq_table_entry_ ## func ## _irq_ ## id + +#define _MK_ISR_SECTION_NAME(prefix, file, counter) \ + "." Z_STRINGIFY(prefix)"."file"." Z_STRINGIFY(counter) + +#define _MK_ISR_ELEMENT_SECTION(counter) _MK_ISR_SECTION_NAME(irq, __FILE__, counter) +#define _MK_IRQ_ELEMENT_SECTION(counter) _MK_ISR_SECTION_NAME(isr, __FILE__, counter) + +/* Separated macro to create ISR table entry only. + * Used by Z_ISR_DECLARE and ISR tables generation script. + */ +#define _Z_ISR_TABLE_ENTRY(irq, func, param, sect) \ + static Z_DECL_ALIGN(struct _isr_table_entry) \ + __attribute__((section(sect))) \ + __used _MK_ISR_ELEMENT_NAME(func, __COUNTER__) = { \ + .arg = (const void *)(param), \ + .isr = (void (*)(const void *))(void *)(func) \ + } + +#define Z_ISR_DECLARE_C(irq, flags, func, param, counter) \ + _Z_ISR_DECLARE_C(irq, flags, func, param, counter) + +#define _Z_ISR_DECLARE_C(irq, flags, func, param, counter) \ + _Z_ISR_TABLE_ENTRY(irq, func, param, _MK_ISR_ELEMENT_SECTION(counter)); \ + static struct _isr_list_sname Z_GENERIC_SECTION(.intList) \ + __used _MK_ISR_NAME(func, counter) = \ + {irq, flags, _MK_ISR_ELEMENT_SECTION(counter)} + +/* Create an entry for _isr_table to be then placed by the linker. + * An instance of struct _isr_list which gets put in the .intList + * section is created with the name of the section where _isr_table entry is placed to be then + * used by isr generation script to create linker script chunk. + */ +#define Z_ISR_DECLARE(irq, flags, func, param) \ + BUILD_ASSERT(((flags) & ISR_FLAG_DIRECT) == 0, "Use Z_ISR_DECLARE_DIRECT macro"); \ + Z_ISR_DECLARE_C(irq, flags, func, param, __COUNTER__) + + +/* Separated macro to create ISR Direct table entry only. + * Used by Z_ISR_DECLARE_DIRECT and ISR tables generation script. + */ +#define _Z_ISR_DIRECT_TABLE_ENTRY(irq, func, sect) \ + COND_CODE_1(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS, ( \ + static Z_DECL_ALIGN(uintptr_t) \ + __attribute__((section(sect))) \ + __used _MK_IRQ_ELEMENT_NAME(func, __COUNTER__) = ((uintptr_t)(func)); \ + ), ( \ + static void __attribute__((section(sect))) __attribute__((naked)) \ + __used _MK_IRQ_ELEMENT_NAME(func, __COUNTER__)(void) { \ + __asm(ARCH_IRQ_VECTOR_JUMP_CODE(func)); \ + } \ + )) + +#define Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) \ + _Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) + +#define _Z_ISR_DECLARE_DIRECT_C(irq, flags, func, counter) \ + _Z_ISR_DIRECT_TABLE_ENTRY(irq, func, _MK_IRQ_ELEMENT_SECTION(counter)); \ + static struct _isr_list_sname Z_GENERIC_SECTION(.intList) \ + __used _MK_ISR_NAME(func, counter) = { \ + irq, \ + ISR_FLAG_DIRECT | (flags), \ + _MK_IRQ_ELEMENT_SECTION(counter)} + +/* Create an entry to irq table and place it in specific section which name is then placed + * in an instance of struct _isr_list to be then used by the isr generation script to create + * the linker script chunks. + */ +#define Z_ISR_DECLARE_DIRECT(irq, flags, func) \ + BUILD_ASSERT(IS_ENABLED(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS) || \ + IS_ENABLED(CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE), \ + "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_{ADDRESS,CODE} not set"); \ + Z_ISR_DECLARE_DIRECT_C(irq, flags, func, __COUNTER__) + + +#else /* IS_ENABLED(CONFIG_ISR_TABLES_LOCAL_DECLARATION) */ + /* Create an instance of struct _isr_list which gets put in the .intList * section. This gets consumed by gen_isr_tables.py which creates the vector * and/or SW ISR tables. @@ -99,6 +200,14 @@ extern struct z_shared_isr_table_entry z_shared_sw_isr_table[]; __used _MK_ISR_NAME(func, __COUNTER__) = \ {irq, flags, (void *)&func, (const void *)param} +/* The version of the Z_ISR_DECLARE that should be used for direct ISR declaration. + * It is here for the API match the version with CONFIG_ISR_TABLES_LOCAL_DECLARATION enabled. + */ +#define Z_ISR_DECLARE_DIRECT(irq, flags, func) \ + Z_ISR_DECLARE(irq, ISR_FLAG_DIRECT | (flags), func, NULL) + +#endif + #define IRQ_TABLE_SIZE (CONFIG_NUM_IRQS - CONFIG_GEN_IRQ_START_VECTOR) #ifdef CONFIG_DYNAMIC_INTERRUPTS diff --git a/include/zephyr/sys/arch_interface.h b/include/zephyr/sys/arch_interface.h index e694bce55cc..722bacd76d5 100644 --- a/include/zephyr/sys/arch_interface.h +++ b/include/zephyr/sys/arch_interface.h @@ -495,6 +495,9 @@ static inline uint32_t arch_proc_id(void); */ void arch_sched_ipi(void); + +int arch_smp_init(void); + #endif /* CONFIG_SMP */ /** diff --git a/include/zephyr/sys/iterable_sections.h b/include/zephyr/sys/iterable_sections.h index fe1976363ca..3ec4af5e9a0 100644 --- a/include/zephyr/sys/iterable_sections.h +++ b/include/zephyr/sys/iterable_sections.h @@ -234,6 +234,16 @@ extern "C" { #define STRUCT_SECTION_ITERABLE_NAMED(struct_type, name, varname) \ TYPE_SECTION_ITERABLE(struct struct_type, varname, struct_type, name) +/** + * @brief Defines a new element for an iterable section with a custom name, + * placed in a custom section. + * + * The name can be used to customize how iterable section entries are sorted. + * @see STRUCT_SECTION_ITERABLE_NAMED() + */ +#define STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(struct_type, secname, name, varname) \ + TYPE_SECTION_ITERABLE(struct struct_type, varname, secname, name) + /** * @brief Iterate over a specified iterable section (alternate). * diff --git a/kernel/Kconfig b/kernel/Kconfig index 6280e80a400..d5e737e7655 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1260,6 +1260,13 @@ config DEVICE_DEPS_DYNAMIC Option that makes it possible to manipulate device dependencies at runtime. +config DEVICE_MUTABLE + bool "Mutable devices [EXPERIMENTAL]" + select EXPERIMENTAL + help + Support mutable devices. Mutable devices are instantiated in SRAM + instead of Flash and are runtime modifiable in kernel mode. + endmenu rsource "Kconfig.vm" 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/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/libc/newlib/CMakeLists.txt b/lib/libc/newlib/CMakeLists.txt index 6556a3e814c..35c6a9b6337 100644 --- a/lib/libc/newlib/CMakeLists.txt +++ b/lib/libc/newlib/CMakeLists.txt @@ -3,6 +3,9 @@ zephyr_library() zephyr_library_sources(libc-hooks.c) +# Do not allow LTO when compiling libc-hooks.c file +set_source_files_properties(libc-hooks.c PROPERTIES COMPILE_OPTIONS $) + # Zephyr normally uses -ffreestanding, which with current GNU toolchains # means that the flag macros used by newlib 3.x to signal # support for PRI.64 macros are not present. To make them available we diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt index 232e4ba8fc1..719ff70f49d 100644 --- a/lib/libc/picolibc/CMakeLists.txt +++ b/lib/libc/picolibc/CMakeLists.txt @@ -3,6 +3,9 @@ zephyr_library() zephyr_library_sources(libc-hooks.c) +# Do not allow LTO when compiling libc-hooks.c file +set_source_files_properties(libc-hooks.c PROPERTIES COMPILE_OPTIONS $) + # define __LINUX_ERRNO_EXTENSIONS__ so we get errno defines like -ESHUTDOWN # used by the network stack zephyr_compile_definitions(__LINUX_ERRNO_EXTENSIONS__) 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/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/modules/Kconfig.mcuboot b/modules/Kconfig.mcuboot index 8df4bde8829..4849b456f22 100644 --- a/modules/Kconfig.mcuboot +++ b/modules/Kconfig.mcuboot @@ -103,7 +103,7 @@ config MCUBOOT_ENCRYPTION_KEY_FILE config MCUBOOT_IMGTOOL_SIGN_VERSION string "Version to pass to imgtool when signing" - default "$(VERSION_MAJOR).$(VERSION_MINOR).$(PATCHLEVEL)+$(VERSION_TWEAK)" if "$(VERSION_MAJOR)" != "" + default "$(APP_VERSION_TWEAK_STRING)" if "$(VERSION_MAJOR)" != "" default "0.0.0+0" help When signing with imgtool then this setting will be passed as version diff --git a/modules/cmsis/Kconfig b/modules/cmsis/Kconfig index 4b5a8ee2855..eff0be6f40c 100644 --- a/modules/cmsis/Kconfig +++ b/modules/cmsis/Kconfig @@ -21,4 +21,11 @@ config HAS_CMSIS_CORE_R config HAS_CMSIS_CORE_M bool +config CMSIS_M_CHECK_DEVICE_DEFINES + bool "Check device defines" + default n + depends on HAS_CMSIS_CORE_M + help + This options enables the validation of CMSIS configuration flags. + endif diff --git a/modules/cmsis/cmsis_core_m.h b/modules/cmsis/cmsis_core_m.h index 880ff614b5b..e7382633945 100644 --- a/modules/cmsis/cmsis_core_m.h +++ b/modules/cmsis/cmsis_core_m.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2023 Arm Limited * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,95 +15,57 @@ #ifndef ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ #define ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ +#if defined(CONFIG_CMSIS_M_CHECK_DEVICE_DEFINES) && CONFIG_CMSIS_M_CHECK_DEVICE_DEFINES == 1U +#define __CHECK_DEVICE_DEFINES 1U +#endif + #include #include -#ifdef __cplusplus -extern "C" { +#if __NVIC_PRIO_BITS != NUM_IRQ_PRIO_BITS +#error "NUM_IRQ_PRIO_BITS and __NVIC_PRIO_BITS are not set to the same value" +#endif + +#if __MPU_PRESENT != CONFIG_CPU_HAS_ARM_MPU +#error "__MPU_PRESENT and CONFIG_CPU_HAS_ARM_MPU are not set to the same value" +#endif + +#if __FPU_PRESENT != CONFIG_CPU_HAS_FPU +#error "__FPU_PRESENT and CONFIG_CPU_HAS_FPU are not set to the same value" #endif -/* Fill in CMSIS required values for non-CMSIS compliant SoCs. - * Use __NVIC_PRIO_BITS as it is required and simple to check, but - * ultimately all SoCs will define their own CMSIS types and constants. + +/* VTOR is only optional on armv6-m and armv8-m baseline. __VTOR_PRESENT is often + * left undefined on platform where it is not optional. */ -#ifndef __NVIC_PRIO_BITS -typedef enum { - Reset_IRQn = -15, - NonMaskableInt_IRQn = -14, - HardFault_IRQn = -13, -#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) - MemoryManagement_IRQn = -12, - BusFault_IRQn = -11, - UsageFault_IRQn = -10, -#if defined(CONFIG_ARM_SECURE_FIRMWARE) - SecureFault_IRQn = -9, -#endif /* CONFIG_ARM_SECURE_FIRMWARE */ -#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ - SVCall_IRQn = -5, - DebugMonitor_IRQn = -4, - PendSV_IRQn = -2, - SysTick_IRQn = -1, - Max_IRQn = CONFIG_NUM_IRQS, -} IRQn_Type; - -#if defined(CONFIG_CPU_CORTEX_M0) -#define __CM0_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M0PLUS) -#define __CM0PLUS_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M1) -#define __CM1_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M3) -#define __CM3_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M4) -#define __CM4_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M7) -#define __CM7_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M23) -#define __CM23_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M33) -#define __CM33_REV 0 -#elif defined(CONFIG_CPU_CORTEX_M55) -#define __CM55_REV 0 -#else -#error "Unknown Cortex-M device" +#if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) && \ + (__VTOR_PRESENT != CONFIG_CPU_CORTEX_M_HAS_VTOR) +#error "__VTOR_PRESENT and CONFIG_CPU_CORTEX_M_HAS_VTOR are not set to the same value." #endif -#ifndef __MPU_PRESENT -#define __MPU_PRESENT 0U +/* Some platform’s sdk incorrectly define __DSP_PRESENT for Cortex-M4 & Cortex-M7 + * DSP extension. __ARM_FEATURE_DSP is set by the compiler for these. So ignore + * __DSP_PRESENT discrepancy when __ARM_FEATURE_DSP is defined. + */ +#if !defined(__ARM_FEATURE_DSP) && (__DSP_PRESENT != CONFIG_ARMV8_M_DSP) +#error "__DSP_PRESENT and CONFIG_ARMV8_M_DSP are not set to the same value" #endif -#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS -#define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ -#endif /* __NVIC_PRIO_BITS */ -#if __NVIC_PRIO_BITS != NUM_IRQ_PRIO_BITS -#error "NUM_IRQ_PRIO_BITS and __NVIC_PRIO_BITS are not set to the same value" +#if __ICACHE_PRESENT != CONFIG_CPU_HAS_ICACHE +#error "__ICACHE_PRESENT and CONFIG_CPU_HAS_ICACHE are not set to the same value" +#endif + +#if __DCACHE_PRESENT != CONFIG_CPU_HAS_DCACHE +#error "__DCACHE_PRESENT and CONFIG_CPU_HAS_DCACHE are not set to the same value" #endif -#ifdef __cplusplus -} +#if __MVE_PRESENT != CONFIG_ARMV8_1_M_MVEI +#error "__MVE_PRESENT and CONFIG_ARMV8_1_M_MVEI are not set to the same value" #endif -#if defined(CONFIG_CPU_CORTEX_M0) -#include -#elif defined(CONFIG_CPU_CORTEX_M0PLUS) -#include -#elif defined(CONFIG_CPU_CORTEX_M1) -#include -#elif defined(CONFIG_CPU_CORTEX_M3) -#include -#elif defined(CONFIG_CPU_CORTEX_M4) -#include -#elif defined(CONFIG_CPU_CORTEX_M7) -#include -#elif defined(CONFIG_CPU_CORTEX_M23) -#include -#elif defined(CONFIG_CPU_CORTEX_M33) -#include -#elif defined(CONFIG_CPU_CORTEX_M55) -#include -#else -#error "Unknown Cortex-M device" +#if __SAUREGION_PRESENT != CONFIG_CPU_HAS_ARM_SAU +#error "__SAUREGION_PRESENT and CONFIG_CPU_HAS_ARM_SAU are not set to the same value" #endif #endif /* ZEPHYR_MODULES_CMSIS_CMSIS_M_H_ */ diff --git a/modules/cmsis/cmsis_core_m_defaults.h b/modules/cmsis/cmsis_core_m_defaults.h new file mode 100644 index 00000000000..bef62665493 --- /dev/null +++ b/modules/cmsis/cmsis_core_m_defaults.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2023 Arm Limited + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief CMSIS interface file + * + * This header populates the default values required to configure the + * ARM CMSIS Core headers. + */ + +#ifndef ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ +#define ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Fill in CMSIS required values for non-CMSIS compliant SoCs. + * Use __NVIC_PRIO_BITS as it is required and simple to check, but + * ultimately all SoCs will define their own CMSIS types and constants. + */ +#ifndef __NVIC_PRIO_BITS +typedef enum { + Reset_IRQn = -15, + NonMaskableInt_IRQn = -14, + HardFault_IRQn = -13, +#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + MemoryManagement_IRQn = -12, + BusFault_IRQn = -11, + UsageFault_IRQn = -10, +#if defined(CONFIG_ARM_SECURE_FIRMWARE) + SecureFault_IRQn = -9, +#endif /* CONFIG_ARM_SECURE_FIRMWARE */ +#endif /* CONFIG_ARMV7_M_ARMV8_M_MAINLINE */ + SVCall_IRQn = -5, + DebugMonitor_IRQn = -4, + PendSV_IRQn = -2, + SysTick_IRQn = -1, + Max_IRQn = CONFIG_NUM_IRQS, +} IRQn_Type; + +#if defined(CONFIG_CPU_CORTEX_M0) +#define __CM0_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M0PLUS) +#define __CM0PLUS_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M1) +#define __CM1_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M3) +#define __CM3_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M4) +#define __CM4_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M7) +#define __CM7_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M23) +#define __CM23_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M33) +#define __CM33_REV 0 +#elif defined(CONFIG_CPU_CORTEX_M55) +#define __CM55_REV 0 +#else +#error "Unknown Cortex-M device" +#endif + +#define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS +#define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ +#endif /* __NVIC_PRIO_BITS */ + +#ifndef __MPU_PRESENT +#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#endif + +#ifndef __FPU_PRESENT +#define __FPU_PRESENT CONFIG_CPU_HAS_FPU +#endif + +#ifndef __FPU_DP +#define __FPU_DP CONFIG_CPU_HAS_FPU_DOUBLE_PRECISION +#endif + +#ifndef __VTOR_PRESENT +#define __VTOR_PRESENT CONFIG_CPU_CORTEX_M_HAS_VTOR +#endif + +#ifndef __DSP_PRESENT +#define __DSP_PRESENT CONFIG_ARMV8_M_DSP +#endif + +#ifndef __ICACHE_PRESENT +#define __ICACHE_PRESENT CONFIG_CPU_HAS_ICACHE +#endif + +#ifndef __DCACHE_PRESENT +#define __DCACHE_PRESENT CONFIG_CPU_HAS_DCACHE +#endif + +#ifndef __MVE_PRESENT +#define __MVE_PRESENT CONFIG_ARMV8_1_M_MVEI +#endif + +#ifndef __SAUREGION_PRESENT +#define __SAUREGION_PRESENT CONFIG_CPU_HAS_ARM_SAU +#endif + +#ifndef __PMU_PRESENT +#define __PMU_PRESENT CONFIG_ARMV8_1_M_PMU +#define __PMU_NUM_EVENTCNT CONFIG_ARMV8_1_M_PMU_EVENTCNT +#endif + +#ifdef __cplusplus +} +#endif + +#if defined(CONFIG_CPU_CORTEX_M0) +#include +#elif defined(CONFIG_CPU_CORTEX_M0PLUS) +#include +#elif defined(CONFIG_CPU_CORTEX_M1) +#include +#elif defined(CONFIG_CPU_CORTEX_M3) +#include +#elif defined(CONFIG_CPU_CORTEX_M4) +#include +#elif defined(CONFIG_CPU_CORTEX_M7) +#include +#elif defined(CONFIG_CPU_CORTEX_M23) +#include +#elif defined(CONFIG_CPU_CORTEX_M33) +#include +#elif defined(CONFIG_CPU_CORTEX_M55) +#include +#else +#error "Unknown Cortex-M device" +#endif + +#endif /* ZEPHYR_MODULES_CMSIS_CMSIS_M_DEFAULTS_H_ */ diff --git a/modules/hal_nordic/CMakeLists.txt b/modules/hal_nordic/CMakeLists.txt index 693400aba76..7f46997c697 100644 --- a/modules/hal_nordic/CMakeLists.txt +++ b/modules/hal_nordic/CMakeLists.txt @@ -6,3 +6,19 @@ if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) endif (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) add_subdirectory_ifdef(CONFIG_HAS_NRFX nrfx) + +if(CONFIG_NRF_REGTOOL_GENERATE_UICR) + list(APPEND nrf_regtool_components GENERATE:UICR) +endif() +if(DEFINED nrf_regtool_components) + find_package(nrf-regtool 5.1.0 REQUIRED + COMPONENTS ${nrf_regtool_components} + PATHS ${CMAKE_CURRENT_LIST_DIR}/nrf-regtool + NO_CMAKE_PATH + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_PACKAGE_REGISTRY + NO_CMAKE_SYSTEM_PATH + NO_CMAKE_SYSTEM_PACKAGE_REGISTRY + ) +endif() diff --git a/modules/hal_nordic/Kconfig b/modules/hal_nordic/Kconfig index f842d2cb646..c9cc93e9329 100644 --- a/modules/hal_nordic/Kconfig +++ b/modules/hal_nordic/Kconfig @@ -43,30 +43,6 @@ config NRF_802154_MULTIPROTOCOL_SUPPORT in the driver, this option must be enabled. Otherwise, the driver assumes that access to the radio peripheral is granted indefinitely. -config NRF_802154_ENCRYPTION - bool "nRF 802.15.4 AES-CCM* authentication & encryption" - depends on !CRYPTO_NRF_ECB - -choice NRF_802154_CCA_MODE - prompt "nRF IEEE 802.15.4 CCA mode" - default NRF_802154_CCA_MODE_ED - help - CCA mode - -config NRF_802154_CCA_MODE_ED - bool "Energy Above Threshold" - -config NRF_802154_CCA_MODE_CARRIER - bool "Carrier Seen" - -config NRF_802154_CCA_MODE_CARRIER_AND_ED - bool "Energy Above Threshold AND Carrier Seen" - -config NRF_802154_CCA_MODE_CARRIER_OR_ED - bool "Energy Above Threshold OR Carrier Seen" - -endchoice - choice NRF_802154_SL_TYPE prompt "nRF IEEE 802.15.4 Service Layer Type" @@ -77,43 +53,6 @@ config NRF_802154_SL_OPENSOURCE endchoice -config NRF_802154_CCA_ED_THRESHOLD - int "nRF IEEE 802.15.4 CCA Energy Detection threshold" - default 45 - help - If energy detected in a given channel is above the value then the - channel is deemed busy. The unit is defined as per 802.15.4-2006 spec. - -config NRF_802154_CCA_CORR_THRESHOLD - int "nRF IEEE 802.15.4 CCA Correlator threshold" - default 45 - -config NRF_802154_CCA_CORR_LIMIT - int "nRF IEEE 802.15.4 CCA Correlator limit" - default 2 - help - Limit for occurrences above correlator threshold. When not equal to - zero the correlator based signal detect is enabled. - -config NRF_802154_PENDING_SHORT_ADDRESSES - int "nRF 802.15.4 pending short addresses" - default 16 - help - Number of slots containing short addresses of nodes for which pending data is stored - -config NRF_802154_PENDING_EXTENDED_ADDRESSES - int "nRF 802.15.4 pending extended addresses" - default 16 - help - Number of slots containing extended addresses of nodes for which pending data is stored - -config NRF_802154_RX_BUFFERS - int "nRF 802.15.4 receive buffers" - default 16 - help - Number of buffers in nRF 802.15.4 driver receive queue. If this value is modified, - its serialization host counterpart must be set to the exact same value. - config NRF_802154_TEMPERATURE_UPDATE bool "nRF 802.15.4 temperature update" default y @@ -192,7 +131,47 @@ config NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT This option specifies default timeout of spinel status response in milliseconds. -if NRF_802154_SER_HOST +endmenu # NRF_802154_SER_HOST || NRF_802154_SER_RADIO + +if NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION + +choice NRF_802154_CCA_MODE + prompt "nRF IEEE 802.15.4 CCA mode" + default NRF_802154_CCA_MODE_ED + help + CCA mode + +config NRF_802154_CCA_MODE_ED + bool "Energy Above Threshold" + +config NRF_802154_CCA_MODE_CARRIER + bool "Carrier Seen" + +config NRF_802154_CCA_MODE_CARRIER_AND_ED + bool "Energy Above Threshold AND Carrier Seen" + +config NRF_802154_CCA_MODE_CARRIER_OR_ED + bool "Energy Above Threshold OR Carrier Seen" + +endchoice + +config NRF_802154_CCA_ED_THRESHOLD + int "nRF IEEE 802.15.4 CCA Energy Detection threshold" + default 45 + help + If energy detected in a given channel is above the value then the + channel is deemed busy. The unit is defined as per 802.15.4-2006 spec. + +config NRF_802154_CCA_CORR_THRESHOLD + int "nRF IEEE 802.15.4 CCA Correlator threshold" + default 45 + +config NRF_802154_CCA_CORR_LIMIT + int "nRF IEEE 802.15.4 CCA Correlator limit" + default 2 + help + Limit for occurrences above correlator threshold. When not equal to + zero the correlator based signal detect is enabled. config NRF_802154_RX_BUFFERS int "nRF 802.15.4 receive buffers" @@ -201,17 +180,60 @@ config NRF_802154_RX_BUFFERS Number of buffers in nRF 802.15.4 driver serialization host's receive queue. If this value is modified, its remote counterpart must be set to the exact same value. -endif +config NRF_802154_PENDING_SHORT_ADDRESSES + int "nRF 802.15.4 pending short addresses" + default 16 + help + Number of slots containing short addresses of nodes for which pending data is stored -endmenu # NRF_802154_SER_HOST || NRF_802154_SER_RADIO +config NRF_802154_PENDING_EXTENDED_ADDRESSES + int "nRF 802.15.4 pending extended addresses" + default 16 + help + Number of slots containing extended addresses of nodes for which pending data is stored + +config NRF_802154_ENCRYPTION + bool "nRF 802.15.4 AES-CCM* authentication & encryption" + depends on !CRYPTO_NRF_ECB + +config NRF_802154_SECURITY_KEY_STORAGE_SIZE + int "nRF 802.15.4 security key storage size" + default 3 + help + Number of encryption keys that the nRF 802.15.4 Radio Driver can store simultaneously. config NRF_802154_CARRIER_FUNCTIONS bool "nRF 802.15.4 carrier functions" - depends on NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION help This option enables functions such as modulated carrier and continuous carrier. If this option is modified on a multicore SoC, its remote counterpart must be set to the exact same value. +choice NRF_802154_ASSERT_CHOICE + prompt "nRF 802.15.4 assert implementation" + default NRF_802154_ASSERT_ZEPHYR_MINIMAL + +config NRF_802154_ASSERT_ZEPHYR_MINIMAL + bool "nRF 802.15.4 minimal assertions" + help + This option provides minimal run-time checking of the nRF 802.15.4 Radio Driver's operation, + even if kernel-wide CONFIG_ASSERT is disabled. In case of an abnormal condition the function + `nrf_802154_assert_handler()` is called. File and line debug information are not provided + to save memory of the image file. Default implementation of the `nrf_802154_assert_handler` + involves a call to `k_panic`/`k_oops` and allows further tweaking of the behavior. + You can also provide your own implementation of `nrf_802154_assert_handler`. + +config NRF_802154_ASSERT_ZEPHYR + bool "nRF 802.15.4 Radio Driver assertions as Zephyr's standard __ASERT_NO_MSG" + help + The run-time checking of the nRF 802.15.4 Radio Driver depends fully on the configuration + of the `__ASSERT_NO_MSG` macro, including the ability to completely turn off the run-time + checking. + +endchoice # NRF_802154_ASSERT_CHOICE + +endif # NRF_802154_RADIO_DRIVER || NRF_802154_SERIALIZATION + endmenu # HAS_NORDIC_DRIVERS rsource "nrfx/Kconfig" +rsource "Kconfig.nrf_regtool" diff --git a/modules/hal_nordic/Kconfig.nrf_regtool b/modules/hal_nordic/Kconfig.nrf_regtool new file mode 100644 index 00000000000..81659bcf0bb --- /dev/null +++ b/modules/hal_nordic/Kconfig.nrf_regtool @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "nrf-regtool options" + depends on SOC_SERIES_NRF54HX + +config NRF_REGTOOL_GENERATE_UICR + bool "Generate UICR" + help + Generate a UICR hex based on devicetree contents using nrf-regtool. + CPU domains that require UICR allocation aren't bootable without it + being programmed alongside the firmware. + +config NRF_REGTOOL_VERBOSITY + int "Verbosity level of console output" + range 0 3 + default 0 + help + Level of verbose output that nrf-regtool will print to the console. + + 0. Only critical information and warnings. + 1. Print a pretty, human-readable representation of a peripheral's + configuration. This is recommended for inspecting register values. + 2. Print extra details for debugging purposes, such as memory maps of + the peripheral configurations, but in a less readable format. + 3. Print even more details, which are typically only useful for + nrf-regtool developers. + +config NRF_REGTOOL_EXTRA_GENERATE_ARGS + string "Extra arguments to 'nrf-regtool generate'" + help + List of additional arguments to every nrf-regtool invocation used for + generating hex files. Example value: "--fill all --fill-byte 0xff". + Run "nrf-regtool generate -h" to see all of the available options. + +endmenu diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake new file mode 100644 index 00000000000..d057c735e3f --- /dev/null +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfig.cmake @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +function(nrf_regtool_generate_hex_from_dts peripheral) + string(TOLOWER "${peripheral}.hex" generated_hex_name) + string(TOLOWER "${peripheral}_merged.hex" merged_hex_name) + + # Prepare common argument sub-lists. + string(REPEAT "-v;" ${CONFIG_NRF_REGTOOL_VERBOSITY} verbosity) + list(TRANSFORM CACHED_DTS_ROOT_BINDINGS PREPEND "--bindings-dir;" OUTPUT_VARIABLE bindings_dirs) + separate_arguments(extra_args UNIX_COMMAND "${CONFIG_NRF_REGTOOL_EXTRA_GENERATE_ARGS}") + + set(generated_hex_file ${PROJECT_BINARY_DIR}/${generated_hex_name}) + execute_process( + COMMAND ${NRF_REGTOOL} ${verbosity} generate + --peripheral ${peripheral} + --svd-file ${SOC_SVD_FILE} + --dts-file ${ZEPHYR_DTS} + ${bindings_dirs} + --output-file ${generated_hex_file} + ${extra_args} + WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} + COMMAND_ERROR_IS_FATAL ANY + ) + message(STATUS "Generated ${peripheral} hex file: ${generated_hex_file}") + + set(merged_hex_file ${PROJECT_BINARY_DIR}/${merged_hex_name}) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${merged_hex_file} + ${generated_hex_file} + ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} + ) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file ${merged_hex_file}) +endfunction() + + +foreach(component IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS) + string(REGEX MATCH "(^.*):(.*$)" match ${component}) + set(operation "${CMAKE_MATCH_1}") + set(peripheral "${CMAKE_MATCH_2}") + + if(operation STREQUAL "GENERATE") + nrf_regtool_generate_hex_from_dts(${peripheral}) + else() + message(FATAL_ERROR "Unrecognized package component: \"${component}\"") + endif() +endforeach() diff --git a/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake new file mode 100644 index 00000000000..e147d1b0532 --- /dev/null +++ b/modules/hal_nordic/nrf-regtool/nrf-regtoolConfigVersion.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +find_program(NRF_REGTOOL nrf-regtool) + +if(NRF_REGTOOL) + execute_process( + COMMAND ${NRF_REGTOOL} --version + OUTPUT_VARIABLE version + RESULT_VARIABLE result + ) + + if(result EQUAL 0 AND version MATCHES "version ([0-9]+[.][0-9]+[.][0-9]+)") + set(PACKAGE_VERSION ${CMAKE_MATCH_1}) + if(PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if(PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif() + + message(STATUS + "Found nrf-regtool (found suitable version \"${PACKAGE_VERSION}\", " + "minimum required is \"${PACKAGE_FIND_VERSION}\")" + ) + return() + endif() + endif() +endif() + +# We only get here if we don't pass the version check. +set(PACKAGE_VERSION_UNSUITABLE TRUE) +set(NRF_REGTOOL NRF_REGTOOL-NOTFOUND CACHE INTERNAL "Path to a program") diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index c338981b651..763f9625be8 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -12,24 +12,6 @@ if (CONFIG_NRF_802154_RADIO_DRIVER) sl_opensource/platform/nrf_802154_irq_zephyr.c sl_opensource/platform/nrf_802154_temperature_zephyr.c ) - - target_compile_definitions(zephyr-802154-interface - INTERFACE - # CCA mode options - NRF_802154_CCA_CORR_LIMIT_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_LIMIT} - NRF_802154_CCA_CORR_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_THRESHOLD} - NRF_802154_CCA_ED_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_ED_THRESHOLD} - ) - - if (CONFIG_NRF_802154_CCA_MODE_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_ED) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_AND_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_AND_ED) - elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_OR_ED) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_OR_ED) - endif() endif () if (CONFIG_NRF_802154_SERIALIZATION) @@ -69,8 +51,26 @@ target_compile_definitions(zephyr-802154-interface # ACK timeout NRF_802154_ACK_TIMEOUT_ENABLED=1 + + # CCA mode options + NRF_802154_CCA_CORR_LIMIT_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_LIMIT} + NRF_802154_CCA_CORR_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_CORR_THRESHOLD} + NRF_802154_CCA_ED_THRESHOLD_DEFAULT=${CONFIG_NRF_802154_CCA_ED_THRESHOLD} + + # Key storage size + NRF_802154_SECURITY_KEY_STORAGE_SIZE=${CONFIG_NRF_802154_SECURITY_KEY_STORAGE_SIZE} ) +if (CONFIG_NRF_802154_CCA_MODE_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_ED) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_AND_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_AND_ED) +elseif (CONFIG_NRF_802154_CCA_MODE_CARRIER_OR_ED) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CCA_MODE_DEFAULT=NRF_RADIO_CCA_MODE_CARRIER_OR_ED) +endif() + if (CONFIG_NRF_802154_ENCRYPTION) target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENCRYPTION_ENABLED=1) target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_SECURITY_WRITER_ENABLED=1) @@ -93,8 +93,12 @@ else() target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CARRIER_FUNCTIONS_ENABLED=0) endif() -if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) - target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENERGY_DETECTED_VERSION=1) +target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENERGY_DETECTED_VERSION=1) + +if (CONFIG_NRF_802154_ASSERT_ZEPHYR OR CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + target_include_directories(zephyr-802154-interface INTERFACE include) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_PLATFORM_ASSERT_INCLUDE=\"nrf_802154_assert_zephyr.h\") + target_sources(nrf-802154-platform PRIVATE nrf_802154_assert_handler.c) endif() set(NRF52_SERIES ${CONFIG_SOC_SERIES_NRF52X}) diff --git a/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h b/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h new file mode 100644 index 00000000000..ecd09de609a --- /dev/null +++ b/modules/hal_nordic/nrf_802154/include/nrf_802154_assert_zephyr.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRF_802154_ASSERT_ZEPHYR_H__ +#define NRF_802154_ASSERT_ZEPHYR_H__ + +#if defined(CONFIG_NRF_802154_ASSERT_ZEPHYR) + +#include + +#define NRF_802154_ASSERT(condition) __ASSERT_NO_MSG(condition) + +#elif defined(CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + +extern void nrf_802154_assert_handler(void); + +#define NRF_802154_ASSERT(condition) \ + do { \ + if (!(condition)) { \ + nrf_802154_assert_handler(); \ + } \ + } while (0) + +#endif /* CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL */ + +#endif /* NRF_802154_ASSERT_ZEPHYR_H__*/ diff --git a/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c b/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c new file mode 100644 index 00000000000..14d964724c6 --- /dev/null +++ b/modules/hal_nordic/nrf_802154/nrf_802154_assert_handler.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "nrf_802154_assert_zephyr.h" + +#if defined(CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL) + +__weak void nrf_802154_assert_handler(void) +{ +#ifdef CONFIG_USERSPACE + /* User threads aren't allowed to induce kernel panics; generate + * an oops instead. + */ + if (k_is_user_context()) { + k_oops(); + } +#endif + + k_panic(); +} + +#endif /* CONFIG_NRF_802154_ASSERT_ZEPHYR_MINIMAL */ diff --git a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c index 06ad1f003e6..b2629eef67b 100644 --- a/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c +++ b/modules/hal_nordic/nrf_802154/serialization/platform/nrf_802154_spinel_backend_ipc.c @@ -9,6 +9,7 @@ #include #include +#include "nrf_802154.h" #include "nrf_802154_spinel_backend_callouts.h" #include "nrf_802154_serialization_error.h" #include "../../spinel_base/spinel.h" @@ -71,9 +72,11 @@ nrf_802154_ser_err_t nrf_802154_backend_init(void) } /* Send packet thread details */ -#define RING_BUFFER_LEN 16 #define SEND_THREAD_STACK_SIZE 1024 +/* Make the ring buffer long enough to hold all notifications that the driver can produce */ +#define RING_BUFFER_LEN (NRF_802154_MAX_PENDING_NOTIFICATIONS + 1) + static K_SEM_DEFINE(send_sem, 0, RING_BUFFER_LEN); K_THREAD_STACK_DEFINE(send_thread_stack, SEND_THREAD_STACK_SIZE); struct k_thread send_thread_data; diff --git a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c index c9260bf278a..3a3d9501d0c 100644 --- a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c +++ b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_clock_zephyr.c @@ -109,11 +109,6 @@ bool nrf_802154_clock_lfclk_is_running(void) return lfclk_is_running; } -__WEAK void nrf_802154_clock_hfclk_ready(void) -{ - /* Intentionally empty. */ -} - __WEAK void nrf_802154_clock_lfclk_ready(void) { /* Intentionally empty. */ diff --git a/modules/hal_nordic/nrfx/CMakeLists.txt b/modules/hal_nordic/nrfx/CMakeLists.txt index 69afbcc9c51..71d57814f36 100644 --- a/modules/hal_nordic/nrfx/CMakeLists.txt +++ b/modules/hal_nordic/nrfx/CMakeLists.txt @@ -31,9 +31,18 @@ zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF5340_CPUAPP NRF5340_XXAA_APP 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_NRF54L15_ENGA NRF54L15_ENGA_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54L15_ENGA_CPUAPP NRF_APPLICATION) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9120 NRF9120_XXAA) zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF9160 NRF9160_XXAA) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUAPP NRF54H20_ENGA_XXAA + NRF_APPLICATION) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPURAD NRF54H20_ENGA_XXAA + NRF_RADIOCORE) +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUPPR NRF54H20_ENGA_XXAA + NRF_PPR) + zephyr_compile_definitions_ifdef(CONFIG_NRF_APPROTECT_LOCK ENABLE_APPROTECT) zephyr_compile_definitions_ifdef(CONFIG_NRF_APPROTECT_USER_HANDLING @@ -64,6 +73,8 @@ zephyr_library_sources_ifdef(CONFIG_SOC_NRF52833 ${MDK_DIR}/system_nrf5283 zephyr_library_sources_ifdef(CONFIG_SOC_NRF52840 ${MDK_DIR}/system_nrf52840.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUAPP ${MDK_DIR}/system_nrf5340_application.c) zephyr_library_sources_ifdef(CONFIG_SOC_NRF5340_CPUNET ${MDK_DIR}/system_nrf5340_network.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54HX ${MDK_DIR}/system_nrf54h.c) +zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF54LX ${MDK_DIR}/system_nrf54l.c) zephyr_library_sources_ifdef(CONFIG_SOC_SERIES_NRF91X ${MDK_DIR}/system_nrf91.c) zephyr_library_sources(nrfx_glue.c) @@ -79,6 +90,7 @@ zephyr_library_sources_ifdef(CONFIG_NRFX_COMP ${SRC_DIR}/nrfx_comp.c) zephyr_library_sources_ifdef(CONFIG_NRFX_DPPI ${SRC_DIR}/nrfx_dppi.c) zephyr_library_sources_ifdef(CONFIG_NRFX_EGU ${SRC_DIR}/nrfx_egu.c) zephyr_library_sources_ifdef(CONFIG_NRFX_GPIOTE ${SRC_DIR}/nrfx_gpiote.c) +zephyr_library_sources_ifdef(CONFIG_NRFX_GRTC ${SRC_DIR}/nrfx_grtc.c) zephyr_library_sources_ifdef(CONFIG_NRFX_I2S ${SRC_DIR}/nrfx_i2s.c) zephyr_library_sources_ifdef(CONFIG_NRFX_IPC ${SRC_DIR}/nrfx_ipc.c) zephyr_library_sources_ifdef(CONFIG_NRFX_LPCOMP ${SRC_DIR}/nrfx_lpcomp.c) @@ -111,6 +123,10 @@ if(CONFIG_NRFX_TWI OR CONFIG_NRFX_TWIM) zephyr_library_sources(${SRC_DIR}/nrfx_twi_twim.c) endif() +if (CONFIG_NRF_GRTC_TIMER AND CONFIG_NRF_GRTC_TIMER_CLOCK_MANAGEMENT) + zephyr_library_compile_definitions(NRF_GRTC_HAS_EXTENDED=1) +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 @@ -128,3 +144,39 @@ if(DEFINED uicr_path) zephyr_library_compile_definitions(CONFIG_GPIO_AS_PINRESET) endif() endif() + +if(CONFIG_SOC_NRF54L15) + dt_prop(clock_frequency PATH "/cpus/cpu@0" PROPERTY "clock-frequency") + math(EXPR clock_frequency_mhz "${clock_frequency} / 1000000") + zephyr_compile_definitions("NRF_CONFIG_CPU_FREQ_MHZ=${clock_frequency_mhz}") +endif() + +zephyr_compile_definitions_ifdef(CONFIG_SOC_NRF54LX_SKIP_CLOCK_CONFIG NRF_SKIP_CLOCK_CONFIGURATION) + +if(CONFIG_SOC_SERIES_NRF54LX AND CONFIG_NRFX_DPPI) + zephyr_library_sources(${HELPERS_DIR}/nrfx_gppi_dppi_ppib_lumos.c) + zephyr_library_sources(${NRFX_DIR}/soc/interconnect/dppic_ppib/nrfx_interconnect_dppic_ppib.c) +endif() + +# Get the SVD file for the current SoC +macro(mdk_svd_ifdef feature_toggle filename) + if(${feature_toggle}) + set(SOC_SVD_FILE ${MDK_DIR}/${filename} CACHE FILEPATH "Path to a CMSIS-SVD file") + endif() +endmacro() + +mdk_svd_ifdef(CONFIG_SOC_SERIES_NRF51X nrf51.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52805 nrf52805.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52810 nrf52810.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52811 nrf52811.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52820 nrf52820.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52832 nrf52.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52833 nrf52833.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF52840 nrf52840.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF5340_CPUAPP nrf5340_application.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF5340_CPUNET nrf5340_network.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUAPP nrf54h20_enga_application.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPUPPR nrf54h20_enga_ppr.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF54H20_ENGA_CPURAD nrf54h20_enga_radiocore.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF9120 nrf9120.svd) +mdk_svd_ifdef(CONFIG_SOC_NRF9160 nrf9160.svd) diff --git a/modules/hal_nordic/nrfx/Kconfig b/modules/hal_nordic/nrfx/Kconfig index 5dcda73c9be..3f9fb54bdfe 100644 --- a/modules/hal_nordic/nrfx/Kconfig +++ b/modules/hal_nordic/nrfx/Kconfig @@ -62,9 +62,43 @@ config NRFX_EGU5 depends on $(dt_nodelabel_has_compat,egu5,$(DT_COMPAT_NORDIC_NRF_EGU)) select NRFX_EGU +config NRFX_EGU020 + bool "EGU020 driver instance" + depends on $(dt_nodelabel_has_compat,egu020,$(DT_COMPAT_NORDIC_NRF_EGU)) + select NRFX_EGU + config NRFX_GPIOTE - bool "GPIOTE driver" - depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + bool + +config NRFX_GPIOTE0 + bool "GPIOTE0 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote0,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE1 + bool "GPIOTE1 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote1,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE20 + bool "NRFX_GPIOTE20 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote20,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE30 + bool "NRFX_GPIOTE30 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote30,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE130 + bool "NRFX_GPIOTE130 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote130,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE + +config NRFX_GPIOTE131 + bool "NRFX_GPIOTE131 driver instance" + depends on $(dt_nodelabel_has_compat,gpiote131,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + select NRFX_GPIOTE config NRFX_GPIOTE_NUM_OF_EVT_HANDLERS int "Number of event handlers" @@ -74,6 +108,10 @@ config NRFX_GPIOTE_NUM_OF_EVT_HANDLERS Specifies number of handlers that can be registered to nrfx_gpiote driver by the user. +config NRFX_GRTC + bool "GRTC driver" + depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_GRTC)) + config NRFX_I2S bool @@ -106,6 +144,7 @@ config NRFX_NVMC depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF51_FLASH_CONTROLLER)) \ || $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF52_FLASH_CONTROLLER)) \ || $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF53_FLASH_CONTROLLER)) \ + || $(dt_has_compat,$(DT_COMPAT_NORDIC_RRAM_CONTROLLER)) \ || $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF91_FLASH_CONTROLLER)) config NRFX_PDM @@ -205,6 +244,16 @@ config NRFX_RTC2 depends on $(dt_nodelabel_has_compat,rtc2,$(DT_COMPAT_NORDIC_NRF_RTC)) select NRFX_RTC +config NRFX_RTC130 + bool "RTC130 driver instance" + depends on $(dt_nodelabel_has_compat,rtc130,$(DT_COMPAT_NORDIC_NRF_RTC)) + select NRFX_RTC + +config NRFX_RTC131 + bool "RTC131 driver instance" + depends on $(dt_nodelabel_has_compat,rtc131,$(DT_COMPAT_NORDIC_NRF_RTC)) + select NRFX_RTC + config NRFX_SAADC bool "SAADC driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_SAADC)) @@ -389,6 +438,106 @@ config NRFX_TIMER4 depends on $(dt_nodelabel_has_compat,timer4,$(DT_COMPAT_NORDIC_NRF_TIMER)) select NRFX_TIMER +config NRFX_TIMER00 + bool "TIMER00 driver instance" + depends on $(dt_nodelabel_has_compat,timer00,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER10 + bool "TIMER10 driver instance" + depends on $(dt_nodelabel_has_compat,timer10,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER20 + bool "TIMER20 driver instance" + depends on $(dt_nodelabel_has_compat,timer20,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER21 + bool "TIMER21 driver instance" + depends on $(dt_nodelabel_has_compat,timer21,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER22 + bool "TIMER22 driver instance" + depends on $(dt_nodelabel_has_compat,timer22,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER23 + bool "TIMER23 driver instance" + depends on $(dt_nodelabel_has_compat,timer23,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER24 + bool "TIMER24 driver instance" + depends on $(dt_nodelabel_has_compat,timer24,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER020 + bool "TIMER020 driver instance" + depends on $(dt_nodelabel_has_compat,timer020,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER021 + bool "TIMER021 driver instance" + depends on $(dt_nodelabel_has_compat,timer021,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER022 + bool "TIMER022 driver instance" + depends on $(dt_nodelabel_has_compat,timer022,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER120 + bool "TIMER120 driver instance" + depends on $(dt_nodelabel_has_compat,timer120,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER121 + bool "TIMER121 driver instance" + depends on $(dt_nodelabel_has_compat,timer121,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER130 + bool "TIMER130 driver instance" + depends on $(dt_nodelabel_has_compat,timer130,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER131 + bool "TIMER131 driver instance" + depends on $(dt_nodelabel_has_compat,timer131,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER132 + bool "TIMER132 driver instance" + depends on $(dt_nodelabel_has_compat,timer132,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER133 + bool "TIMER133 driver instance" + depends on $(dt_nodelabel_has_compat,timer133,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER134 + bool "TIMER134 driver instance" + depends on $(dt_nodelabel_has_compat,timer134,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER135 + bool "TIMER135 driver instance" + depends on $(dt_nodelabel_has_compat,timer135,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER136 + bool "TIMER136 driver instance" + depends on $(dt_nodelabel_has_compat,timer136,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + +config NRFX_TIMER137 + bool "TIMER137 driver instance" + depends on $(dt_nodelabel_has_compat,timer137,$(DT_COMPAT_NORDIC_NRF_TIMER)) + select NRFX_TIMER + config NRFX_TWI bool @@ -544,6 +693,97 @@ config NRFX_UARTE3 depends on $(dt_nodelabel_has_compat,uart3,$(DT_COMPAT_NORDIC_NRF_UARTE)) select NRFX_UARTE +config NRFX_UARTE00 + bool "UARTE00 driver instance" + depends on $(dt_nodelabel_has_compat,uart00,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE20 + bool "UARTE20 driver instance" + depends on $(dt_nodelabel_has_compat,uart20,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE21 + bool "UARTE21 driver instance" + depends on $(dt_nodelabel_has_compat,uart21,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE22 + bool "UARTE22 driver instance" + depends on $(dt_nodelabel_has_compat,uart22,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE30 + bool "UARTE30 driver instance" + depends on $(dt_nodelabel_has_compat,uart30,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE120 + bool "UARTE120 driver instance" + depends on $(dt_nodelabel_has_compat,uart120,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE130 + bool "UARTE130 driver instance" + depends on $(dt_nodelabel_has_compat,uart130,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE131 + bool "UARTE131 driver instance" + depends on $(dt_nodelabel_has_compat,uart131,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE132 + bool "UARTE132 driver instance" + depends on $(dt_nodelabel_has_compat,uart132,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE133 + bool "UARTE133 driver instance" + depends on $(dt_nodelabel_has_compat,uart133,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE134 + bool "UARTE134 driver instance" + depends on $(dt_nodelabel_has_compat,uart134,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE135 + bool "UARTE135 driver instance" + depends on $(dt_nodelabel_has_compat,uart135,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE136 + bool "UARTE136 driver instance" + depends on $(dt_nodelabel_has_compat,uart136,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE137 + bool "UARTE137 driver instance" + depends on $(dt_nodelabel_has_compat,uart137,$(DT_COMPAT_NORDIC_NRF_UARTE)) + select NRFX_UARTE + +config NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG + bool "UARTE GPIO configuration support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG + bool "UARTE PSEL configuration support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_TX_LINK + bool "UARTE TX transfer linking support" + depends on NRFX_UARTE + +config NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + bool "UARTE RX caching support" + default y if $(dt_nodelabel_has_compat,ram3x,$(DT_COMPAT_MMIO_SRAM)) + depends on NRFX_UARTE + help + Feature might be enabled on platforms which has limitations regarding addresses + to which receiver can write data. If enabled then internal driver buffers + (cache buffers) are used for DMA transfers and data is copied to the user buffer. + config NRFX_USBREG bool "USBREG driver" depends on $(dt_has_compat,$(DT_COMPAT_NORDIC_NRF_USBREG)) @@ -561,6 +801,31 @@ config NRFX_WDT1 depends on $(dt_nodelabel_has_compat,wdt1,$(DT_COMPAT_NORDIC_NRF_WDT)) select NRFX_WDT +config NRFX_WDT30 + bool "WDT30 driver instance" + depends on $(dt_nodelabel_has_compat,wdt30,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT31 + bool "WDT31 driver instance" + depends on $(dt_nodelabel_has_compat,wdt31,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT130 + bool "WDT130 driver instance" + depends on $(dt_nodelabel_has_compat,wdt130,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT131 + bool "WDT131 driver instance" + depends on $(dt_nodelabel_has_compat,wdt131,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + +config NRFX_WDT132 + bool "WDT132 driver instance" + depends on $(dt_nodelabel_has_compat,wdt132,$(DT_COMPAT_NORDIC_NRF_WDT)) + select NRFX_WDT + menu "Peripheral Resource Sharing module" config NRFX_PRS diff --git a/modules/hal_nordic/nrfx/Kconfig.logging b/modules/hal_nordic/nrfx/Kconfig.logging index 7f7b785e70c..b24d683d3de 100644 --- a/modules/hal_nordic/nrfx/Kconfig.logging +++ b/modules/hal_nordic/nrfx/Kconfig.logging @@ -28,6 +28,10 @@ config NRFX_GPIOTE_LOG bool "GPIOTE driver logging" depends on NRFX_GPIOTE +config NRFX_GRTC_LOG + bool "GRTC driver logging" + depends on NRFX_GRTC + config NRFX_I2S_LOG bool "I2S driver logging" depends on NRFX_I2S diff --git a/modules/hal_nordic/nrfx/nrfx_config.h b/modules/hal_nordic/nrfx/nrfx_config.h index aaf31751004..5ebc243541e 100644 --- a/modules/hal_nordic/nrfx/nrfx_config.h +++ b/modules/hal_nordic/nrfx/nrfx_config.h @@ -9,12 +9,6 @@ #include -/* - * NRFX API version 2.10 flag. - * When the flag is set NRFX API is compatible with the newest NRFX release. - */ -#define NRFX_CONFIG_API_VER_2_10 1 - /* * These are mappings of Kconfig options enabling nrfx drivers and particular * peripheral instances to the corresponding symbols used inside of nrfx. @@ -114,18 +108,37 @@ #ifdef CONFIG_NRFX_EGU5 #define NRFX_EGU5_ENABLED 1 #endif +#ifdef CONFIG_NRFX_EGU020 +#define NRFX_EGU020_ENABLED 1 +#endif + +#ifdef CONFIG_NRFX_GRTC +#define NRFX_GRTC_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GRTC_LOG +#define NRFX_GRTC_CONFIG_LOG_ENABLED 1 +#endif #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 +#endif +#ifdef CONFIG_NRFX_GPIOTE0 #define NRFX_GPIOTE0_ENABLED 1 #endif +#ifdef CONFIG_NRFX_GPIOTE1 +#define NRFX_GPIOTE1_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE20 +#define NRFX_GPIOTE20_ENABLED 1 #endif -#ifdef CONFIG_NRFX_GPIOTE_LOG -#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 1 +#ifdef CONFIG_NRFX_GPIOTE30 +#define NRFX_GPIOTE30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE130 +#define NRFX_GPIOTE130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_GPIOTE131 +#define NRFX_GPIOTE131_ENABLED 1 #endif #ifdef CONFIG_NRFX_GPIOTE_NUM_OF_EVT_HANDLERS @@ -289,6 +302,12 @@ #ifdef CONFIG_NRFX_RTC2 #define NRFX_RTC2_ENABLED 1 #endif +#ifdef CONFIG_NRFX_RTC130 +#define NRFX_RTC130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_RTC131 +#define NRFX_RTC131_ENABLED 1 +#endif #ifdef CONFIG_NRFX_SAADC #define NRFX_SAADC_ENABLED 1 @@ -441,6 +460,66 @@ #ifdef CONFIG_NRFX_TIMER4 #define NRFX_TIMER4_ENABLED 1 #endif +#ifdef CONFIG_NRFX_TIMER00 +#define NRFX_TIMER00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER10 +#define NRFX_TIMER10_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER20 +#define NRFX_TIMER20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER21 +#define NRFX_TIMER21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER22 +#define NRFX_TIMER22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER23 +#define NRFX_TIMER23_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER24 +#define NRFX_TIMER24_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER020 +#define NRFX_TIMER020_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER021 +#define NRFX_TIMER021_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER022 +#define NRFX_TIMER022_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER120 +#define NRFX_TIMER120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER121 +#define NRFX_TIMER121_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER130 +#define NRFX_TIMER130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER131 +#define NRFX_TIMER131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER132 +#define NRFX_TIMER132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER133 +#define NRFX_TIMER133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER134 +#define NRFX_TIMER134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER135 +#define NRFX_TIMER135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER136 +#define NRFX_TIMER136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_TIMER137 +#define NRFX_TIMER137_ENABLED 1 +#endif #ifdef CONFIG_NRFX_TWI #define NRFX_TWI_ENABLED 1 @@ -560,6 +639,60 @@ #ifdef CONFIG_NRFX_UARTE3 #define NRFX_UARTE3_ENABLED 1 #endif +#ifdef CONFIG_NRFX_UARTE00 +#define NRFX_UARTE00_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE20 +#define NRFX_UARTE20_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE21 +#define NRFX_UARTE21_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE22 +#define NRFX_UARTE22_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE30 +#define NRFX_UARTE30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE120 +#define NRFX_UARTE120_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE130 +#define NRFX_UARTE130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE131 +#define NRFX_UARTE131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE132 +#define NRFX_UARTE132_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE133 +#define NRFX_UARTE133_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE134 +#define NRFX_UARTE134_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE135 +#define NRFX_UARTE135_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE136 +#define NRFX_UARTE136_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE137 +#define NRFX_UARTE137_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif +#ifdef CONFIG_NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif #ifdef CONFIG_NRFX_USBREG #define NRFX_USBREG_ENABLED 1 @@ -580,12 +713,29 @@ #ifdef CONFIG_NRFX_WDT1 #define NRFX_WDT1_ENABLED 1 #endif +#ifdef CONFIG_NRFX_WDT30 +#define NRFX_WDT30_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT31 +#define NRFX_WDT31_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT130 +#define NRFX_WDT130_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT131 +#define NRFX_WDT131_ENABLED 1 +#endif +#ifdef CONFIG_NRFX_WDT132 +#define NRFX_WDT132_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 +#define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE \ + CONFIG_NRF52_ANOMALY_109_WORKAROUND_EGU_INSTANCE #endif #if defined(CONFIG_SOC_SERIES_BSIM_NRFXX) @@ -606,6 +756,27 @@ #define NRF_PERIPH(P) P##_S #endif +/* If the GRTC system timer driver is to be used, prepare definitions required + * by the nrfx_grtc driver (NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK and + * NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS) based on information from devicetree. + */ +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) +#define NRFX_CONFIG_BIT_DT(node_id, prop, idx) \ + BIT(DT_PROP_BY_IDX(node_id, prop, idx)) +#define NRFX_CONFIG_GRTC_MASK_DT(prop) \ + (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST(0, nordic_nrf_grtc), prop), \ + (DT_FOREACH_PROP_ELEM_SEP(DT_INST(0, nordic_nrf_grtc), prop, \ + NRFX_CONFIG_BIT_DT, (|))), \ + (0))) + +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK \ + (NRFX_CONFIG_GRTC_MASK_DT(owned_channels) & \ + ~NRFX_CONFIG_GRTC_MASK_DT(child_owned_channels)) +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS \ + (DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), owned_channels, 0) - \ + DT_PROP_LEN_OR(DT_INST(0, nordic_nrf_grtc), child_owned_channels, 0)) +#endif /* DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_grtc) */ + #include #if defined(NRF51) #include @@ -627,8 +798,16 @@ #include #elif defined(NRF5340_XXAA_NETWORK) #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_APPLICATION) + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_RADIOCORE) + #include +#elif defined(NRF54H20_ENGA_XXAA) && defined(NRF_PPR) + #include #elif defined(NRF9120_XXAA) || defined(NRF9160_XXAA) #include +#elif defined(NRF54L15_ENGA_XXAA) && defined(NRF_APPLICATION) + #include #else #error "Unknown device." #endif diff --git a/modules/hal_nordic/nrfx/nrfx_config_common.h b/modules/hal_nordic/nrfx/nrfx_config_common.h index 8c0a58713a0..28a3a15b0de 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_common.h +++ b/modules/hal_nordic/nrfx/nrfx_config_common.h @@ -18,7 +18,7 @@ /** @brief Symbol specifying minor version of the nrfx API to be used. */ #ifndef NRFX_CONFIG_API_VER_MINOR -#define NRFX_CONFIG_API_VER_MINOR 0 +#define NRFX_CONFIG_API_VER_MINOR 2 #endif /** @brief Symbol specifying micro version of the nrfx API to be used. */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h index 4a42f92ca98..18bcc40b2ac 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf5340_application.h @@ -83,6 +83,7 @@ * between secure and non-secure mapping. */ #if defined(NRF_TRUSTZONE_NONSECURE) +#define NRF_GPIOTE NRF_GPIOTE1 #define NRF_GPIOTE1 NRF_GPIOTE1_NS #else #define NRF_CACHE NRF_CACHE_S @@ -91,20 +92,14 @@ #define NRF_CRYPTOCELL NRF_CRYPTOCELL_S #define NRF_CTI NRF_CTI_S #define NRF_FICR NRF_FICR_S +#define NRF_GPIOTE NRF_GPIOTE0 #define NRF_GPIOTE0 NRF_GPIOTE0_S +#define NRF_GPIOTE1 NRF_GPIOTE1_NS #define NRF_SPU NRF_SPU_S #define NRF_TAD NRF_TAD_S #define NRF_UICR NRF_UICR_S #endif -/* Fixups for the GPIOTE driver. */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#else -#define NRF_GPIOTE NRF_GPIOTE0 -#endif - - /** * @brief NRFX_DEFAULT_IRQ_PRIORITY * diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h new file mode 100644 index 00000000000..e6c79341b9a --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_application.h @@ -0,0 +1,1935 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_APPLICATION_H__ +#define NRFX_CONFIG_NRF54H20_ENGA_APPLICATION_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 7 +#endif + +/** + * @brief NRFX_BELLBOARD_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD_ENABLED +#define NRFX_BELLBOARD_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_BELLBOARD0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD0_ENABLED +#define NRFX_BELLBOARD0_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD1_ENABLED +#define NRFX_BELLBOARD1_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD2_ENABLED +#define NRFX_BELLBOARD2_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD3_ENABLED +#define NRFX_BELLBOARD3_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e +#endif + +/** + * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 +#endif + +/** + * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 +#endif + +/** + * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 +#endif + +/** + * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f +#endif + +/** + * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 +#endif + +/** + * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df +#endif + +/** + * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf +#endif + +/** + * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0. Maximum: 15. + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_GPIOTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE130_ENABLED +#define NRFX_GPIOTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED +#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL +#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_ENABLED +#define NRFX_I2S_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_CONFIG_LOG_ENABLED +#define NRFX_I2S_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_I2S_CONFIG_LOG_LEVEL +#define NRFX_I2S_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S130_ENABLED +#define NRFX_I2S130_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S131_ENABLED +#define NRFX_I2S131_ENABLED 0 +#endif + +/** + * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_MVDMA_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA_ENABLED +#define NRFX_MVDMA_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. + * + * Integer value. Minimum: 0. Maximum: 5. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_6_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_6_ENABLED +#define NRFX_PRS_BOX_6_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_7_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_7_ENABLED +#define NRFX_PRS_BOX_7_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_8_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_8_ENABLED +#define NRFX_PRS_BOX_8_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_9_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_9_ENABLED +#define NRFX_PRS_BOX_9_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PWM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM120_ENABLED +#define NRFX_PWM120_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM130_ENABLED +#define NRFX_PWM130_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM131_ENABLED +#define NRFX_PWM131_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM132_ENABLED +#define NRFX_PWM132_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM133_ENABLED +#define NRFX_PWM133_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_QDEC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC130_ENABLED +#define NRFX_QDEC130_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC131_ENABLED +#define NRFX_QDEC131_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_RTC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC130_ENABLED +#define NRFX_RTC130_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC131_ENABLED +#define NRFX_RTC131_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM120_ENABLED +#define NRFX_SPIM120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM121_ENABLED +#define NRFX_SPIM121_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM130_ENABLED +#define NRFX_SPIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM131_ENABLED +#define NRFX_SPIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM132_ENABLED +#define NRFX_SPIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM133_ENABLED +#define NRFX_SPIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM134_ENABLED +#define NRFX_SPIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM135_ENABLED +#define NRFX_SPIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM136_ENABLED +#define NRFX_SPIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM137_ENABLED +#define NRFX_SPIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIS120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS120_ENABLED +#define NRFX_SPIS120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS130_ENABLED +#define NRFX_SPIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS131_ENABLED +#define NRFX_SPIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS132_ENABLED +#define NRFX_SPIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS133_ENABLED +#define NRFX_SPIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS134_ENABLED +#define NRFX_SPIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS135_ENABLED +#define NRFX_SPIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS136_ENABLED +#define NRFX_SPIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS137_ENABLED +#define NRFX_SPIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_SYSTICK_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SYSTICK_ENABLED +#define NRFX_SYSTICK_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED +#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL +#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER120_ENABLED +#define NRFX_TIMER120_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER121_ENABLED +#define NRFX_TIMER121_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER130_ENABLED +#define NRFX_TIMER130_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER131_ENABLED +#define NRFX_TIMER131_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER132_ENABLED +#define NRFX_TIMER132_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER133_ENABLED +#define NRFX_TIMER133_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER134_ENABLED +#define NRFX_TIMER134_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER135_ENABLED +#define NRFX_TIMER135_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER136_ENABLED +#define NRFX_TIMER136_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER137_ENABLED +#define NRFX_TIMER137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM130_ENABLED +#define NRFX_TWIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM131_ENABLED +#define NRFX_TWIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM132_ENABLED +#define NRFX_TWIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM133_ENABLED +#define NRFX_TWIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM134_ENABLED +#define NRFX_TWIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM135_ENABLED +#define NRFX_TWIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM136_ENABLED +#define NRFX_TWIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM137_ENABLED +#define NRFX_TWIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance + * would be initialized only once. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS130_ENABLED +#define NRFX_TWIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS131_ENABLED +#define NRFX_TWIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS132_ENABLED +#define NRFX_TWIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS133_ENABLED +#define NRFX_TWIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS134_ENABLED +#define NRFX_TWIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS135_ENABLED +#define NRFX_TWIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS136_ENABLED +#define NRFX_TWIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS137_ENABLED +#define NRFX_TWIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for + * configuring GPIO pins is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for + * configuring PSEL registers is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking + * of TX transfers. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_UARTE120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE120_ENABLED +#define NRFX_UARTE120_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE130_ENABLED +#define NRFX_UARTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE131_ENABLED +#define NRFX_UARTE131_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE132_ENABLED +#define NRFX_UARTE132_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE133_ENABLED +#define NRFX_UARTE133_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE134_ENABLED +#define NRFX_UARTE134_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE135_ENABLED +#define NRFX_UARTE135_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE136_ENABLED +#define NRFX_UARTE136_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE137_ENABLED +#define NRFX_UARTE137_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_WDT010_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT010_ENABLED +#define NRFX_WDT010_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT011_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT011_ENABLED +#define NRFX_WDT011_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT131_ENABLED +#define NRFX_WDT131_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT132_ENABLED +#define NRFX_WDT132_ENABLED 0 +#endif + +#endif /* NRFX_CONFIG_NRF54H20_ENGA_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h new file mode 100644 index 00000000000..369fe18a81f --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_ppr.h @@ -0,0 +1,1855 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_PPR_H__ +#define NRFX_CONFIG_NRF54H20_ENGA_PPR_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 3 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 +#endif + +/** + * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e +#endif + +/** + * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 +#endif + +/** + * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 +#endif + +/** + * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 +#endif + +/** + * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 +#endif + +/** + * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df +#endif + +/** + * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf +#endif + +/** + * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0. Maximum: 15. + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_GPIOTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE130_ENABLED +#define NRFX_GPIOTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 2 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000000c0 +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED +#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL +#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_ENABLED +#define NRFX_I2S_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_CONFIG_LOG_ENABLED +#define NRFX_I2S_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_I2S_CONFIG_LOG_LEVEL +#define NRFX_I2S_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S130_ENABLED +#define NRFX_I2S130_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S131_ENABLED +#define NRFX_I2S131_ENABLED 0 +#endif + +/** + * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for + * workarounds in the driver. + * + * Integer value. Minimum: 0. Maximum: 5. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_6_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_6_ENABLED +#define NRFX_PRS_BOX_6_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_7_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_7_ENABLED +#define NRFX_PRS_BOX_7_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_8_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_8_ENABLED +#define NRFX_PRS_BOX_8_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_9_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_9_ENABLED +#define NRFX_PRS_BOX_9_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PWM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM120_ENABLED +#define NRFX_PWM120_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM130_ENABLED +#define NRFX_PWM130_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM131_ENABLED +#define NRFX_PWM131_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM132_ENABLED +#define NRFX_PWM132_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM133_ENABLED +#define NRFX_PWM133_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_QDEC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC130_ENABLED +#define NRFX_QDEC130_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC131_ENABLED +#define NRFX_QDEC131_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_RTC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC130_ENABLED +#define NRFX_RTC130_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC131_ENABLED +#define NRFX_RTC131_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM120_ENABLED +#define NRFX_SPIM120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM121_ENABLED +#define NRFX_SPIM121_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM130_ENABLED +#define NRFX_SPIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM131_ENABLED +#define NRFX_SPIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM132_ENABLED +#define NRFX_SPIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM133_ENABLED +#define NRFX_SPIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM134_ENABLED +#define NRFX_SPIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM135_ENABLED +#define NRFX_SPIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM136_ENABLED +#define NRFX_SPIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM137_ENABLED +#define NRFX_SPIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIS120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS120_ENABLED +#define NRFX_SPIS120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS130_ENABLED +#define NRFX_SPIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS131_ENABLED +#define NRFX_SPIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS132_ENABLED +#define NRFX_SPIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS133_ENABLED +#define NRFX_SPIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS134_ENABLED +#define NRFX_SPIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS135_ENABLED +#define NRFX_SPIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS136_ENABLED +#define NRFX_SPIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS137_ENABLED +#define NRFX_SPIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED +#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL +#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER120_ENABLED +#define NRFX_TIMER120_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER121_ENABLED +#define NRFX_TIMER121_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER130_ENABLED +#define NRFX_TIMER130_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER131_ENABLED +#define NRFX_TIMER131_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER132_ENABLED +#define NRFX_TIMER132_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER133_ENABLED +#define NRFX_TIMER133_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER134_ENABLED +#define NRFX_TIMER134_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER135_ENABLED +#define NRFX_TIMER135_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER136_ENABLED +#define NRFX_TIMER136_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER137_ENABLED +#define NRFX_TIMER137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM130_ENABLED +#define NRFX_TWIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM131_ENABLED +#define NRFX_TWIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM132_ENABLED +#define NRFX_TWIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM133_ENABLED +#define NRFX_TWIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM134_ENABLED +#define NRFX_TWIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM135_ENABLED +#define NRFX_TWIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM136_ENABLED +#define NRFX_TWIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM137_ENABLED +#define NRFX_TWIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance + * would be initialized only once. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS130_ENABLED +#define NRFX_TWIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS131_ENABLED +#define NRFX_TWIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS132_ENABLED +#define NRFX_TWIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS133_ENABLED +#define NRFX_TWIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS134_ENABLED +#define NRFX_TWIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS135_ENABLED +#define NRFX_TWIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS136_ENABLED +#define NRFX_TWIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS137_ENABLED +#define NRFX_TWIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for + * configuring GPIO pins is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for + * configuring PSEL registers is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking of TX + * transfers. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_UARTE120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE120_ENABLED +#define NRFX_UARTE120_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE130_ENABLED +#define NRFX_UARTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE131_ENABLED +#define NRFX_UARTE131_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE132_ENABLED +#define NRFX_UARTE132_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE133_ENABLED +#define NRFX_UARTE133_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE134_ENABLED +#define NRFX_UARTE134_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE135_ENABLED +#define NRFX_UARTE135_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE136_ENABLED +#define NRFX_UARTE136_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE137_ENABLED +#define NRFX_UARTE137_ENABLED 0 +#endif + +/** + * @brief NRFX_VEVIF_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_VEVIF_ENABLED +#define NRFX_VEVIF_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 3. + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_WDT131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT131_ENABLED +#define NRFX_WDT131_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT132_ENABLED +#define NRFX_WDT132_ENABLED 0 +#endif + +#endif /* NRFX_CONFIG_NRF54H20_ENGA_PPR_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h new file mode 100644 index 00000000000..7b9a1c4b733 --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54h20_enga_radiocore.h @@ -0,0 +1,2016 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54H20_ENGA_RADIOCORE_H__ +#define NRFX_CONFIG_NRF54H20_ENGA_RADIOCORE_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + +/** + * @brief NRFX_DEFAULT_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_DEFAULT_IRQ_PRIORITY +#define NRFX_DEFAULT_IRQ_PRIORITY 7 +#endif + +/** + * @brief NRFX_BELLBOARD_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD_ENABLED +#define NRFX_BELLBOARD_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_BELLBOARD_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_BELLBOARD0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD0_ENABLED +#define NRFX_BELLBOARD0_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD1_ENABLED +#define NRFX_BELLBOARD1_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD2_ENABLED +#define NRFX_BELLBOARD2_ENABLED 0 +#endif + +/** + * @brief NRFX_BELLBOARD3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_BELLBOARD3_ENABLED +#define NRFX_BELLBOARD3_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI020_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI030_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000f0 +#endif + +/** + * @brief NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000001e +#endif + +/** + * @brief NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000020 +#endif + +/** + * @brief NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000040 +#endif + +/** + * @brief NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000081 +#endif + +/** + * @brief NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI020_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI030_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000f +#endif + +/** + * @brief NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI131_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000ff +#endif + +/** + * @brief NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI132_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI133_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000e1 +#endif + +/** + * @brief NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI134_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000df +#endif + +/** + * @brief NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI135_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000bf +#endif + +/** + * @brief NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_DPPI136_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000007e +#endif + +/** + * @brief NRFX_EGU_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_EGU020_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_EGU020_ENABLED +#define NRFX_EGU020_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0. Maximum: 15. + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 1 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_GPIOTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GPIOTE130_ENABLED +#define NRFX_GPIOTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 4 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x00000f00 +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_GRTC_CONFIG_LOG_ENABLED +#define NRFX_GRTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GRTC_CONFIG_LOG_LEVEL +#define NRFX_GRTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_ENABLED +#define NRFX_I2S_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S_CONFIG_LOG_ENABLED +#define NRFX_I2S_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_I2S_CONFIG_LOG_LEVEL +#define NRFX_I2S_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_I2S130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S130_ENABLED +#define NRFX_I2S130_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_I2S131_ENABLED +#define NRFX_I2S131_ENABLED 0 +#endif + +/** + * @brief NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000030 +#endif + +/** + * @brief NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_PUB_CONFIG_ALLOWED_CHANNELS_MASK 0x0000000c +#endif + +/** + * @brief NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x000000c0 +#endif + +/** + * @brief NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT120_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0 +#endif + +/** + * @brief NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK + */ +#ifndef NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK +#define NRFX_IPCT130_SUB_CONFIG_ALLOWED_CHANNELS_MASK 0x00000003 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_MVDMA_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_MVDMA_ENABLED +#define NRFX_MVDMA_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID - Timer instance used for workarounds in the driver. + * + * Integer value. Minimum: 0. Maximum: 5. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_6_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_6_ENABLED +#define NRFX_PRS_BOX_6_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_7_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_7_ENABLED +#define NRFX_PRS_BOX_7_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_8_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_8_ENABLED +#define NRFX_PRS_BOX_8_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_9_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PRS_BOX_9_ENABLED +#define NRFX_PRS_BOX_9_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PWM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM120_ENABLED +#define NRFX_PWM120_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM130_ENABLED +#define NRFX_PWM130_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM131_ENABLED +#define NRFX_PWM131_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM132_ENABLED +#define NRFX_PWM132_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_PWM133_ENABLED +#define NRFX_PWM133_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_QDEC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC130_ENABLED +#define NRFX_QDEC130_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_QDEC131_ENABLED +#define NRFX_QDEC131_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_RTC130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC130_ENABLED +#define NRFX_RTC130_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_RTC131_ENABLED +#define NRFX_RTC131_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIM120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM120_ENABLED +#define NRFX_SPIM120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM121_ENABLED +#define NRFX_SPIM121_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM130_ENABLED +#define NRFX_SPIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM131_ENABLED +#define NRFX_SPIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM132_ENABLED +#define NRFX_SPIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM133_ENABLED +#define NRFX_SPIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM134_ENABLED +#define NRFX_SPIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM135_ENABLED +#define NRFX_SPIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM136_ENABLED +#define NRFX_SPIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIM137_ENABLED +#define NRFX_SPIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_SPIS120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS120_ENABLED +#define NRFX_SPIS120_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS130_ENABLED +#define NRFX_SPIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS131_ENABLED +#define NRFX_SPIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS132_ENABLED +#define NRFX_SPIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS133_ENABLED +#define NRFX_SPIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS134_ENABLED +#define NRFX_SPIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS135_ENABLED +#define NRFX_SPIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS136_ENABLED +#define NRFX_SPIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SPIS137_ENABLED +#define NRFX_SPIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_SYSTICK_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_SYSTICK_ENABLED +#define NRFX_SYSTICK_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TEMP_CONFIG_LOG_ENABLED +#define NRFX_TEMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TEMP_CONFIG_LOG_LEVEL +#define NRFX_TEMP_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TIMER020_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER020_ENABLED +#define NRFX_TIMER020_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER021_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER021_ENABLED +#define NRFX_TIMER021_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER022_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER022_ENABLED +#define NRFX_TIMER022_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER120_ENABLED +#define NRFX_TIMER120_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER121_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER121_ENABLED +#define NRFX_TIMER121_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER130_ENABLED +#define NRFX_TIMER130_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER131_ENABLED +#define NRFX_TIMER131_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER132_ENABLED +#define NRFX_TIMER132_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER133_ENABLED +#define NRFX_TIMER133_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER134_ENABLED +#define NRFX_TIMER134_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER135_ENABLED +#define NRFX_TIMER135_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER136_ENABLED +#define NRFX_TIMER136_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TIMER137_ENABLED +#define NRFX_TIMER137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIM130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM130_ENABLED +#define NRFX_TWIM130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM131_ENABLED +#define NRFX_TWIM131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM132_ENABLED +#define NRFX_TWIM132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM133_ENABLED +#define NRFX_TWIM133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM134_ENABLED +#define NRFX_TWIM134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM135_ENABLED +#define NRFX_TWIM135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM136_ENABLED +#define NRFX_TWIM136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIM137_ENABLED +#define NRFX_TWIM137_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance + * would be initialized only once. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_TWIS130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS130_ENABLED +#define NRFX_TWIS130_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS131_ENABLED +#define NRFX_TWIS131_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS132_ENABLED +#define NRFX_TWIS132_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS133_ENABLED +#define NRFX_TWIS133_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS134_ENABLED +#define NRFX_TWIS134_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS135_ENABLED +#define NRFX_TWIS135_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS136_ENABLED +#define NRFX_TWIS136_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_TWIS137_ENABLED +#define NRFX_TWIS137_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG - If enabled, support for + * configuring GPIO pins is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_GPIO_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG - If enabled, support for + * configuring PSEL registers is removed from the driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG +#define NRFX_UARTE_CONFIG_SKIP_PSEL_CONFIG 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_TX_LINK - If enabled, driver supports linking + * of TX transfers. + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_TX_LINK +#define NRFX_UARTE_CONFIG_TX_LINK 1 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_RX_CACHE_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_RX_CACHE_ENABLED +#define NRFX_UARTE_CONFIG_RX_CACHE_ENABLED 1 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_UARTE120_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE120_ENABLED +#define NRFX_UARTE120_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE130_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE130_ENABLED +#define NRFX_UARTE130_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE131_ENABLED +#define NRFX_UARTE131_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE132_ENABLED +#define NRFX_UARTE132_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE133_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE133_ENABLED +#define NRFX_UARTE133_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE134_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE134_ENABLED +#define NRFX_UARTE134_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE135_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE135_ENABLED +#define NRFX_UARTE135_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE136_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE136_ENABLED +#define NRFX_UARTE136_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE137_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_UARTE137_ENABLED +#define NRFX_UARTE137_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0. Maximum: 7. + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_WDT010_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT010_ENABLED +#define NRFX_WDT010_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT011_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT011_ENABLED +#define NRFX_WDT011_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT131_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT131_ENABLED +#define NRFX_WDT131_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT132_ENABLED + * + * Boolean. Accepted values: 0 and 1. + */ +#ifndef NRFX_WDT132_ENABLED +#define NRFX_WDT132_ENABLED 0 +#endif + +#endif /* NRFX_CONFIG_NRF54H20_ENGA_RADIOCORE_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h new file mode 100644 index 00000000000..a694a07955d --- /dev/null +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf54l15_enga_application.h @@ -0,0 +1,1522 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef NRFX_CONFIG_NRF54L15_APPLICATION_H__ +#define NRFX_CONFIG_NRF54L15_APPLICATION_H__ + +#ifndef NRFX_CONFIG_H__ +#error "This file should not be included directly. Include nrfx_config.h instead." +#endif + +/** + * @brief NRFX_CLOCK_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_CLOCK_ENABLED +#define NRFX_CLOCK_ENABLED 0 +#endif + +/** + * @brief NRFX_CLOCK_CONFIG_LF_SRC + * + * Integer value. + * Supported values: + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 + */ +#ifndef NRFX_CLOCK_CONFIG_LF_SRC +#define NRFX_CLOCK_CONFIG_LF_SRC 0 +#endif + +/** + * @brief NRFX_CLOCK_CONFIG_LF_CAL_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_CLOCK_CONFIG_LF_CAL_ENABLED +#define NRFX_CLOCK_CONFIG_LF_CAL_ENABLED 0 +#endif + +/** + * @brief NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED +#define NRFX_CLOCK_CONFIG_LFXO_TWO_STAGE_ENABLED 0 +#endif + +/** + * @brief NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_CLOCK_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED +#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_CLOCK_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL +#define NRFX_CLOCK_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_COMP_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_COMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_DPPI_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_DPPI_ENABLED +#define NRFX_DPPI_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_ENABLED +#define NRFX_DPPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_DPPI_CONFIG_LOG_LEVEL + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_DPPI_CONFIG_LOG_LEVEL +#define NRFX_DPPI_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_EGU_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU10_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_EGU10_ENABLED +#define NRFX_EGU10_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_EGU20_ENABLED +#define NRFX_EGU20_ENABLED 0 +#endif + +/** + * @brief NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_EGU_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_GPIOTE_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS + * + * Integer value. Minimum: 0 Maximum: 15 + */ +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS +#define NRFX_GPIOTE_CONFIG_NUM_OF_EVT_HANDLERS 0 +#endif + +/** + * @brief NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_GPIOTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_GRTC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_GRTC_ENABLED +#define NRFX_GRTC_ENABLED 0 +#endif + +/** + * @brief NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS + * + * Integer value. + */ +#ifndef NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS +#define NRFX_GRTC_CONFIG_NUM_OF_CC_CHANNELS 11 +#endif + +/** + * @brief GRTC CC channels ownership mask. + */ +#ifndef NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK +#define NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK 0x000007ff +#endif + +/** + * @brief NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_GRTC_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_I2S_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_I2S_ENABLED +#define NRFX_I2S_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_I2S_CONFIG_LOG_ENABLED +#define NRFX_I2S_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_I2S_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_I2S_CONFIG_LOG_LEVEL +#define NRFX_I2S_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_LPCOMP_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_LPCOMP_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_NFCT_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID +#define NRFX_NFCT_CONFIG_TIMER_INSTANCE_ID 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_NFCT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_PDM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PDM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_POWER_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_POWER_ENABLED +#define NRFX_POWER_ENABLED 0 +#endif + +/** + * @brief NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_2_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_3_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_4_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_5_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_5_ENABLED +#define NRFX_PRS_BOX_5_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_PWM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM20_ENABLED +#define NRFX_PWM20_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM21_ENABLED +#define NRFX_PWM21_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM22_ENABLED +#define NRFX_PWM22_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PWM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_QDEC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_QDEC20_ENABLED +#define NRFX_QDEC20_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_QDEC21_ENABLED +#define NRFX_QDEC21_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_QDEC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_RTC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC10_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_RTC10_ENABLED +#define NRFX_RTC10_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_RTC30_ENABLED +#define NRFX_RTC30_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_RTC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_SAADC_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SAADC_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_SPI_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI_ENABLED +#define NRFX_SPI_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI00_ENABLED +#define NRFX_SPI00_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI20_ENABLED +#define NRFX_SPI20_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI21_ENABLED +#define NRFX_SPI21_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI22_ENABLED +#define NRFX_SPI22_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI30_ENABLED +#define NRFX_SPI30_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_SPI_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPI_CONFIG_LOG_ENABLED +#define NRFX_SPI_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPI_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPI_CONFIG_LOG_LEVEL +#define NRFX_SPI_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_SPIM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM00_ENABLED +#define NRFX_SPIM00_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM20_ENABLED +#define NRFX_SPIM20_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM21_ENABLED +#define NRFX_SPIM21_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM22_ENABLED +#define NRFX_SPIM22_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM30_ENABLED +#define NRFX_SPIM30_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_EXTENDED_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM_EXTENDED_ENABLED +#define NRFX_SPIM_EXTENDED_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_SPIS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS00_ENABLED +#define NRFX_SPIS00_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS20_ENABLED +#define NRFX_SPIS20_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS21_ENABLED +#define NRFX_SPIS21_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS22_ENABLED +#define NRFX_SPIS22_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS30_ENABLED +#define NRFX_SPIS30_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_SPIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_SYSTICK_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_SYSTICK_ENABLED +#define NRFX_SYSTICK_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TEMP_ENABLED +#define NRFX_TEMP_ENABLED 0 +#endif + +/** + * @brief NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TEMP_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_TIMER_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER10_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER10_ENABLED +#define NRFX_TIMER10_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER20_ENABLED +#define NRFX_TIMER20_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER21_ENABLED +#define NRFX_TIMER21_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER22_ENABLED +#define NRFX_TIMER22_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER23_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER23_ENABLED +#define NRFX_TIMER23_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER24_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER24_ENABLED +#define NRFX_TIMER24_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TIMER_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_TWIM_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM20_ENABLED +#define NRFX_TWIM20_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM21_ENABLED +#define NRFX_TWIM21_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM22_ENABLED +#define NRFX_TWIM22_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM30_ENABLED +#define NRFX_TWIM30_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIM_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_TWIS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS00_ENABLED +#define NRFX_TWIS00_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS20_ENABLED +#define NRFX_TWIS20_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS21_ENABLED +#define NRFX_TWIS21_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS22_ENABLED +#define NRFX_TWIS22_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS30_ENABLED +#define NRFX_TWIS30_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +/** + * @brief NRFX_TWIS_NO_SYNC_MODE + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +/** + * @brief NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_TWIS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_UARTE_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE00_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE00_ENABLED +#define NRFX_UARTE00_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE20_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE20_ENABLED +#define NRFX_UARTE20_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE21_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE21_ENABLED +#define NRFX_UARTE21_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE22_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE22_ENABLED +#define NRFX_UARTE22_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE30_ENABLED +#define NRFX_UARTE30_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_UARTE_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 0 +#endif + +/** + * @brief NRFX_WDT_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT30_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT30_ENABLED +#define NRFX_WDT30_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT31_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT31_ENABLED +#define NRFX_WDT31_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_NO_IRQ + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +/** + * @brief NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY + * + * Integer value. Minimum: 0 Maximum: 7 + */ +#ifndef NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_WDT_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 0 +#endif + +#endif /* NRFX_CONFIG_NRF54L15_APPLICATION_H__ */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h index 873be583a35..c6029a18628 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h @@ -67,25 +67,21 @@ * between secure and non-secure mapping. */ #if defined(NRF_TRUSTZONE_NONSECURE) +#define NRF_GPIOTE NRF_GPIOTE1 #define NRF_GPIOTE1 NRF_GPIOTE1_NS #else #define NRF_CC_HOST_RGF NRF_CC_HOST_RGF_S #define NRF_CRYPTOCELL NRF_CRYPTOCELL_S #define NRF_CTRL_AP_PERI NRF_CTRL_AP_PERI_S #define NRF_FICR NRF_FICR_S +#define NRF_GPIOTE NRF_GPIOTE0 #define NRF_GPIOTE0 NRF_GPIOTE0_S +#define NRF_GPIOTE1 NRF_GPIOTE1_NS #define NRF_SPU NRF_SPU_S #define NRF_TAD NRF_TAD_S #define NRF_UICR NRF_UICR_S #endif -/* Fixups for the GPIOTE driver. */ -#if defined(NRF_TRUSTZONE_NONSECURE) -#define NRF_GPIOTE NRF_GPIOTE1 -#else -#define NRF_GPIOTE NRF_GPIOTE0 -#endif - /** * @brief NRFX_DEFAULT_IRQ_PRIORITY * diff --git a/modules/hal_nordic/nrfx/nrfx_glue.h b/modules/hal_nordic/nrfx/nrfx_glue.h index 2257ea879a3..0edda440112 100644 --- a/modules/hal_nordic/nrfx/nrfx_glue.h +++ b/modules/hal_nordic/nrfx/nrfx_glue.h @@ -7,6 +7,13 @@ #ifndef NRFX_GLUE_H__ #define NRFX_GLUE_H__ +#if defined(CONFIG_CPU_CORTEX_M) +/* Workaround for missing __ICACHE_PRESENT and __DCACHE_PRESENT symbols in MDK + * SoC definitions. To be removed when this is fixed. + */ +#include +#endif + #include #include #include @@ -35,6 +42,11 @@ extern "C" { #define NRFX_ASSERT(expression) __ASSERT_NO_MSG(expression) #endif +#if defined(CONFIG_RISCV) +/* included here due to dependency on NRFX_ASSERT definition */ +#include +#endif + /** * @brief Macro for placing a compile time assertion. * @@ -84,14 +96,22 @@ extern "C" { * * @param irq_number IRQ number. */ -#define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_PENDING_SET(irq_number) nrf_vpr_clic_int_pending_set(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_PENDING_SET(irq_number) NVIC_SetPendingIRQ(irq_number) +#endif /** * @brief Macro for clearing the pending status of a specific IRQ. * * @param irq_number IRQ number. */ -#define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_PENDING_CLEAR(irq_number) nrf_vpr_clic_int_pending_clear(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_PENDING_CLEAR(irq_number) NVIC_ClearPendingIRQ(irq_number) +#endif /** * @brief Macro for checking the pending status of a specific IRQ. @@ -99,7 +119,11 @@ extern "C" { * @retval true If the IRQ is pending. * @retval false Otherwise. */ -#define NRFX_IRQ_IS_PENDING(irq_number) (NVIC_GetPendingIRQ(irq_number) == 1) +#if defined(CONFIG_RISCV) +#define NRFX_IRQ_IS_PENDING(irq_number) nrf_vpr_clic_int_pending_check(NRF_VPRCLIC, irq_number) +#else +#define NRFX_IRQ_IS_PENDING(irq_number) (NVIC_GetPendingIRQ(irq_number) == 1) +#endif /** @brief Macro for entering into a critical section. */ #define NRFX_CRITICAL_SECTION_ENTER() { unsigned int irq_lock_key = irq_lock(); diff --git a/modules/mbedtls/CMakeLists.txt b/modules/mbedtls/CMakeLists.txt index f061605c027..a6277f654b5 100644 --- a/modules/mbedtls/CMakeLists.txt +++ b/modules/mbedtls/CMakeLists.txt @@ -16,9 +16,17 @@ zephyr_interface_library_named(mbedTLS) MBEDTLS_CONFIG_FILE="${CONFIG_MBEDTLS_CFG_FILE}" ) + if (CONFIG_BUILD_WITH_TFM) + target_include_directories(mbedTLS INTERFACE + $/api_ns/interface/include + ) + endif() + # Add regular includes target_include_directories(mbedTLS INTERFACE ${ZEPHYR_CURRENT_MODULE_DIR}/include + ${ZEPHYR_CURRENT_MODULE_DIR}/include/library + ${ZEPHYR_CURRENT_MODULE_DIR}/library configs include ) @@ -28,30 +36,24 @@ zephyr_interface_library_named(mbedTLS) # Base mbed TLS files list(APPEND mbedtls_base_src + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aes.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aesni.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/aria.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1parse.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/asn1write.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/base64.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_core.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod_raw.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/nist_kw.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/oid.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/padlock.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform_util.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/version.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/constant_time.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aes.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aesni.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/aria.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum_mod.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/bignum.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/camellia.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ccm.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/chacha20.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/chachapoly.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher_wrap.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/cipher.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/cmac.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/constant_time.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ctr_drbg.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/debug.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/des.c @@ -59,22 +61,27 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdh.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecdsa.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecjpake.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp_curves_new.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp_curves.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/ecp.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy_poll.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/entropy.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/error.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/gcm.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/hash_info.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/hkdf.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/hmac_drbg.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/lmots.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/lms.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/md5.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/md.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/md5.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/memory_buffer_alloc.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_reader.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/mps_trace.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/nist_kw.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/oid.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/padlock.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform_util.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/platform.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/poly1305.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_util.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/ripemd160.c @@ -86,6 +93,7 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/threading.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/timing.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/version_features.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/version.c zephyr_init.c ) @@ -107,11 +115,11 @@ zephyr_interface_library_named(mbedTLS) zephyr_library_named(mbedTLSCrypto) - if (CONFIG_MBEDTLS_PSA_CRYPTO_C) + if (CONFIG_MBEDTLS_PSA_CRYPTO_C AND NOT CONFIG_BUILD_WITH_TFM) list(APPEND crypto_source ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_aead.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_cipher.c - ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_driver_wrappers.c + ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_driver_wrappers_no_static.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_ecp.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_hash.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_mac.c @@ -119,11 +127,6 @@ zephyr_interface_library_named(mbedTLS) ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_se.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_storage.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_its_file.c - ) - endif() - - if (NOT CONFIG_BUILD_WITH_TFM) - list(APPEND crypto_source ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_client.c ${ZEPHYR_CURRENT_MODULE_DIR}/library/psa_crypto_slot_management.c diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 67277fb24c4..2a05ee28d36 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -5,6 +5,7 @@ config ZEPHYR_MBEDTLS_MODULE bool + config MBEDTLS_PROMPTLESS bool help @@ -13,7 +14,6 @@ config MBEDTLS_PROMPTLESS mbed TLS menu prompt and instead handle the selection of MBEDTLS from dependent sub-configurations and thus prevent stuck symbol behavior. - menuconfig MBEDTLS bool "mbed TLS Support" if !MBEDTLS_PROMPTLESS help @@ -27,6 +27,7 @@ choice MBEDTLS_IMPLEMENTATION config MBEDTLS_BUILTIN bool "Use Zephyr in-tree mbedTLS version" + depends on ! DISABLE_MBEDTLS_BUILTIN help Link with mbedTLS sources included with Zephyr distribution. Included mbedTLS version is well integrated with and supported @@ -40,6 +41,11 @@ config MBEDTLS_LIBRARY endchoice +# subsystems cannot deselect MBEDTLS_BUILTIN, but they can select +# DISABLE_MBEDTLS_BUILTIN. +config DISABLE_MBEDTLS_BUILTIN + bool + config CUSTOM_MBEDTLS_CFG_FILE bool "Custom mbed TLS configuration file" help @@ -233,3 +239,6 @@ config APP_LINK_WITH_MBEDTLS issues for 'app'. endif # MBEDTLS + +# Add PSA configurations +rsource "Kconfig.psa" diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa new file mode 100644 index 00000000000..b4d72801300 --- /dev/null +++ b/modules/mbedtls/Kconfig.psa @@ -0,0 +1,848 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# +menu "PSA RNG support" + +config PSA_WANT_GENERATE_RANDOM + bool + prompt "PSA RNG support" + help + Provide random number generator (RNG) support. + +config PSA_WANT_ALG_CTR_DRBG + bool + prompt "PSA RNG using CTR-DRBG as PRNG" + help + Provide random number generator (RNG) using CTR-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). + +config PSA_WANT_ALG_HMAC_DRBG + bool + prompt "PSA RNG using HMAC-DRBG as PRNG" + help + Provide random number generator (RNG) using HMAC-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). + +endmenu # RNG support + +menu "PSA key type support" + +config PSA_HAS_KEY_SUPPORT + bool + default y + depends on PSA_WANT_KEY_TYPE_DERIVE || \ + PSA_WANT_KEY_TYPE_HMAC || \ + PSA_WANT_KEY_TYPE_RAW_DATA || \ + PSA_WANT_KEY_TYPE_PASSWORD || \ + PSA_WANT_KEY_TYPE_PASSWORD_HASH || \ + PSA_WANT_KEY_TYPE_PEPPER || \ + PSA_WANT_KEY_TYPE_AES || \ + PSA_WANT_KEY_TYPE_ARIA || \ + PSA_WANT_KEY_TYPE_DES || \ + PSA_WANT_KEY_TYPE_CAMELLIA || \ + PSA_WANT_KEY_TYPE_SM4 || \ + PSA_WANT_KEY_TYPE_ARC4 || \ + PSA_WANT_KEY_TYPE_CHACHA20 || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + +config PSA_WANT_KEY_TYPE_DERIVE + bool "PSA derive key type support" + help + This key type is for high-entropy secrets only. + For low-entropy secrets, password key type should be used instead. + +config PSA_WANT_KEY_TYPE_RAW_DATA + bool "PSA raw data key type support" + help + A "key" of this type cannot be used for any cryptographic operation. + Applications can use this type to store arbitrary data in the keystore. + +config PSA_WANT_KEY_TYPE_HMAC + bool "PSA HMAC key type support" + help + HMAC key. + +config PSA_WANT_KEY_TYPE_PASSWORD + bool "PSA password key type support" + help + A low-entropy secret for password hashing or key derivation. + +config PSA_WANT_KEY_TYPE_PASSWORD_HASH + bool "PSA password hash key type support" + help + A secret value that can be used to verify a password hash. + +config PSA_WANT_KEY_TYPE_PEPPER + bool "PSA pepper key type support" + help + A secret value that can be used when computing a password hash. + +config PSA_WANT_KEY_TYPE_AES + bool "PSA AES key type support" + help + Key for cipher, AEAD or MAC algorithm based on the AES block cipher. + +config PSA_WANT_KEY_TYPE_ARIA + bool "PSA ARIA key type support" + +config PSA_WANT_KEY_TYPE_DES + bool "PSA DES key type support (weak)" + help + Warning: Single DES and 2-key 3DES are weak and strongly deprecated + and are only recommended for decrypting legacy data. + 3-key 3DES is weak and deprecated and is only recommended for use in + legacy protocols. + +config PSA_WANT_KEY_TYPE_CAMELLIA + bool "PSA CAMELLIA key type support" + +config PSA_WANT_KEY_TYPE_SM4 + bool "PSA SM4 key type support" + +config PSA_WANT_KEY_TYPE_ARC4 + bool "PSA ARC4 key type support (weak)" + help + Warning: The ARC4 cipher is weak and deprecated and is only + recommended for use in legacy protocols. + +config PSA_WANT_KEY_TYPE_CHACHA20 + bool "PSA ChaCha20 key type support" + default y + depends on PSA_WANT_ALG_CHACHA20_POLY1305 || \ + PSA_WANT_ALG_STREAM_CIPHER + help + Key for the ChaCha20 stream cipher or the ChaCha20-Poly1305 AEAD algorithm. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + bool "PSA ECC key pair support" + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + bool "PSA ECC public key support" + help + Elliptic curve public key. + + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT + bool "PSA ECC import key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: import for both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT + bool "PSA ECC export key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: export for both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE + bool "PSA ECC generate key pair support" + default y if PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + help + Elliptic curve key pair: generate for both the private and public key. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE + bool + default y + depends on PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + bool "PSA RSA key pair type support" + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + bool "PSA RSA public key support" + help + RSA public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT + bool "PSA RSA key pair import key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: import key for both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT + bool "PSA RSA key pair export key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: export key for both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE + bool "PSA RSA key pair generate key" + default y if PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + help + RSA key pair: key generation for both the private and public key. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_GENERATE + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR + bool "PSA DH key pair type support" + select PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + help + Finite-field Diffie-Hellman key pair: both the private key and public key. + +config PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + bool "PSA DH public key support" + help + Finite-field Diffie-Hellman public key. + +config PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_IMPORT + bool "SPAKE2P key pair import support" + default y if PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR + select PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY + help + SPAKE2P key pair: import key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_EXPORT + bool "SPAKE2P key pair export support" + default y if PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR + select PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY + help + SPAKE2P key pair: export key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_DERIVE + bool "SPAKE2P key pair derive support" + default y if PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR + select PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY + help + SPAKE2P key pair: derive key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR_DERIVE + +config PSA_WANT_KEY_TYPE_SPAKE2P_KEY_PAIR + bool "SPAKE2P key pair support" + select PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY + help + SPAKE2P key pair: both the private and public key. + +config PSA_WANT_KEY_TYPE_SPAKE2P_PUBLIC_KEY + bool "SPAKE2P public key support" + help + SPAKE2P public key. + +config PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_IMPORT + bool "SRP key pair import support" + default y if PSA_WANT_KEY_TYPE_SRP_KEY_PAIR + select PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY + help + SRP key pair: import key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_EXPORT + bool "SRP key pair export support" + default y if PSA_WANT_KEY_TYPE_SRP_KEY_PAIR + select PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY + help + SRP key pair: export key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_DERIVE + bool "SRP key pair derive support" + default y if PSA_WANT_KEY_TYPE_SRP_KEY_PAIR + select PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY + help + SRP key pair: derive key for both the private and public key. + +config PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_BASIC + bool + default y + depends on PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_IMPORT || \ + PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_EXPORT || \ + PSA_WANT_KEY_TYPE_SRP_KEY_PAIR_DERIVE + +config PSA_WANT_KEY_TYPE_SRP_PUBLIC_KEY + bool "SRP public key support" + help + SRP public key. + +config PSA_WANT_KEY_TYPE_SRP_KEY_PAIR + bool "SRP public key support" + help + SRP public key. + +endmenu # PSA Key type support + +menu "PSA AEAD support" + +config PSA_HAS_AEAD_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CCM || \ + PSA_WANT_ALG_GCM || \ + PSA_WANT_ALG_CHACHA20_POLY1305 + help + Prompt-less configuration that states that AEAD is supported. + +config PSA_WANT_ALG_CCM + bool + prompt "PSA CCM support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_GCM + bool + prompt "PSA GCM support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CHACHA20_POLY1305 + bool + prompt "PSA ChaCha20-Poly1305 support" if !PSA_PROMPTLESS + +endmenu # PSA AEAD support + + +menu "PSA MAC support" + +config PSA_HAS_MAC_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CBC_MAC || \ + PSA_WANT_ALG_CMAC || \ + PSA_WANT_ALG_HMAC + help + Prompt-less configuration that states that MAC is supported. + +config PSA_WANT_ALG_CBC_MAC + bool + prompt "PSA CBC-MAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CMAC + bool + prompt "PSA CMAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_HMAC + bool + prompt "PSA HMAC support" if !PSA_PROMPTLESS + +endmenu # PSA MAC support + + +menu "PSA Hash support" + +config PSA_HAS_HASH_SUPPORT + bool + default y + depends on PSA_WANT_ALG_SHA_1 || \ + PSA_WANT_ALG_SHA_224 || \ + PSA_WANT_ALG_SHA_256 || \ + PSA_WANT_ALG_SHA_384 || \ + PSA_WANT_ALG_SHA_512 || \ + PSA_WANT_ALG_SHA_512_224 || \ + PSA_WANT_ALG_SHA_512_256 || \ + PSA_WANT_ALG_SHA3_224 || \ + PSA_WANT_ALG_SHA3_256 || \ + PSA_WANT_ALG_SHA3_384 || \ + PSA_WANT_ALG_SHA3_512 || \ + PSA_WANT_ALG_SM3 || \ + PSA_WANT_ALG_SHAKE256_512 || \ + PSA_WANT_ALG_RIPEMD160 || \ + PSA_WANT_ALG_MD2 || \ + PSA_WANT_ALG_MD4 || \ + PSA_WANT_ALG_MD5 + help + Prompt-less configuration that states that hash is supported. + +config PSA_WANT_ALG_SHA_1 + bool + prompt "PSA SHA-1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The SHA-1 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_SHA_224 + bool + prompt "PSA SHA-224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_256 + bool + prompt "PSA SHA-256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_384 + bool + prompt "PSA SHA-384 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512 + bool + prompt "PSA SHA-512 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512_224 + bool + prompt "PSA SHA-512/224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA_512_256 + bool + prompt "PSA SHA-512/256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_224 + bool + prompt "PSA SHA3-224 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_256 + bool + prompt "PSA SHA3-256 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_384 + bool + prompt "PSA SHA3-384 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHA3_512 + bool + prompt "PSA SHA3-512 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SM3 + bool + prompt "PSA SM3 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SHAKE256_512 + bool + prompt "PSA SHAKE256 512 bits support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RIPEMD160 + bool + prompt "PSA RIPEMD-160 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_MD2 + bool + prompt "PSA MD2 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD2 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_MD4 + bool + prompt "PSA MD4 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD4 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +config PSA_WANT_ALG_MD5 + bool + prompt "PSA MD5 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD5 hash is weak and deprecated and is only recommended + for use in legacy protocols. + +endmenu # PSA Hash support + +menu "PSA Cipher support" + +config PSA_HAS_CIPHER_SUPPORT + bool + default y + depends on PSA_WANT_ALG_ECB_NO_PADDING || \ + PSA_WANT_ALG_CBC_NO_PADDING || \ + PSA_WANT_ALG_CBC_PKCS7 || \ + PSA_WANT_ALG_CCM_STAR_NO_TAG || \ + PSA_WANT_ALG_CFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_OFB || \ + PSA_WANT_ALG_XTS || \ + PSA_WANT_ALG_STREAM_CIPHER + help + Prompt-less configuration that states that cipher is supported. + +config PSA_WANT_ALG_ECB_NO_PADDING + bool + prompt "PSA ECB block cipher mode support (with no padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CBC_NO_PADDING + bool + prompt "PSA CBC block cipher mode support (with no padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CBC_PKCS7 + bool + prompt "PSA CBC block cipher mode support (with PKCS#7 padding)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CFB + bool + prompt "PSA stream cipher using CFB block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CTR + bool + prompt "PSA stream cipher using CTR block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_OFB + bool + prompt "PSA stream cipher using OFB block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_XTS + bool + prompt "PSA XTS block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CCM_STAR_NO_TAG + bool + prompt "PSA CCM* with no tag support" if !PSA_PROMPTLESS + help + Unauthenticated version of CCM. Uses the cipher API instead of the AEAD API. + +config PSA_WANT_ALG_STREAM_CIPHER + bool + prompt "PSA stream cipher support" if !PSA_PROMPTLESS + +endmenu # PSA Cipher Support + +menu "PSA Key agreement support" + +config PSA_HAS_KEY_AGREEMENT + bool + default y + depends on PSA_WANT_ALG_ECDH + depends on PSA_WANT_ALG_FFDH + help + Promt-less configuration that states that key agreement is supported. + +config PSA_WANT_ALG_ECDH + bool + prompt "PSA ECDH support" if !PSA_PROMPTLESS + + +config PSA_WANT_ALG_FFDH + bool + prompt "PSA FFDH support" if !PSA_PROMPTLESS + +endmenu # PSA Key agreement support + +menu "PSA Key derivation support" + +config PSA_HAS_KEY_DERIVATION + bool + default y + depends on PSA_WANT_ALG_HKDF || \ + PSA_WANT_ALG_HKDF_EXPAND || \ + PSA_WANT_ALG_HKDF_EXTRACT || \ + PSA_WANT_ALG_PBKDF2_HMAC || \ + PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 || \ + PSA_WANT_ALG_TLS12_PRF || \ + PSA_WANT_ALG_TLS12_PSK_TO_MS || \ + PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + help + Prompt-less configuration that states that key derivation is supported. + +config PSA_WANT_ALG_HKDF + bool + prompt "PSA HKDF support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_HKDF_EXTRACT + bool + prompt "PSA HKDF extract support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_HKDF_EXPAND + bool + prompt "PSA HKDF expand support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_PBKDF2_HMAC + bool + prompt "PSA PBKDF2 HMAC support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 + bool + prompt "PSA PBKDF2-AES-CMAC-PRF-128 support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_CMAC + +config PSA_WANT_ALG_TLS12_PRF + bool + prompt "PSA PRF support (TLS1.2)" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_TLS12_PSK_TO_MS + bool + prompt "PSA TLS 1.2 PSK to MS support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + bool + prompt "PSA TLS 1.2 EC J-PAKE to PMS support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_SHA_256 + +endmenu # PSA Key derivation support + + +menu "PSA Asymmetric support" + +config PSA_HAS_ASYM_ENCRYPT_SUPPORT + bool + default y + depends on PSA_WANT_ALG_RSA_OAEP || \ + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + help + Prompt-less configuration that states that asymmetric encryption + is supported. + + +config PSA_HAS_ASYM_SIGN_SUPPORT + bool + default y + depends on PSA_WANT_ALG_DETERMINISTIC_ECDSA || \ + PSA_WANT_ALG_ECDSA || \ + PSA_WANT_ALG_ECDSA_ANY || \ + PSA_WANT_ALG_PURE_EDDSA || \ + PSA_WANT_ALG_ED25519PH || \ + PSA_WANT_ALG_ED448PH || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW || \ + PSA_WANT_ALG_RSA_PSS || \ + PSA_WANT_ALG_RSA_PSS_ANY_SALT + help + Prompt-less configuration that states that asymmetric signing + is supported. + +config PSA_WANT_ALG_ECDSA + bool + prompt "PSA ECDSA support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ECDSA_ANY + bool + prompt "PSA ECDSA support, without hashing" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_DETERMINISTIC_ECDSA + bool + prompt "PSA ECDSA support (deterministic mode)" if !PSA_PROMPTLESS + +menu "Elliptic Curve type support" + +config PSA_WANT_ECC_BRAINPOOL_P_R1_160 + bool + prompt "PSA ECC BrainpoolP160r1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 160-bit curve brainpoolP160r1 is weak and deprecated and + is only recommended for use in legacy protocols. + +config PSA_WANT_ECC_BRAINPOOL_P_R1_192 + bool + prompt "PSA ECC BrainpoolP192r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_224 + bool + prompt "PSA ECC BrainpoolP224r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_256 + bool + prompt "PSA ECC BrainpoolP256r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_320 + bool + prompt "PSA ECC BrainpoolP320r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_384 + bool + prompt "PSA ECC BrainpoolP384r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_BRAINPOOL_P_R1_512 + bool + prompt "PSA ECC BrainpoolP512r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_MONTGOMERY_255 + bool + prompt "PSA ECC Curve25519 (X25519) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_MONTGOMERY_448 + bool + prompt "PSA ECC Curve448 (X448) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_TWISTED_EDWARDS_255 + bool + prompt "PSA ECC Edwards25519 (Ed25519) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_TWISTED_EDWARDS_448 + bool + prompt "PSA ECC Edwards448 (Ed448) support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_192 + bool + prompt "PSA ECC secp192k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_224 + bool + prompt "PSA ECC secp224k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_K1_256 + bool + prompt "PSA ECC secp256k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_192 + bool + prompt "PSA ECC secp192r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_224 + bool + prompt "PSA ECC secp224r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_256 + bool + prompt "PSA ECC secp256r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_384 + bool + prompt "PSA ECC secp384r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_521 + bool + prompt "PSA ECC secp521r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R2_160 + bool + prompt "PSA ECC secp160r2 support (weak)" if !PSA_PROMPTLESS + help + Warning: his family of curves is weak and deprecated. + +config PSA_WANT_ECC_SECT_K1_163 + bool + prompt "PSA ECC sect163k1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163k1 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_SECT_K1_233 + bool + prompt "PSA ECC sect233k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_239 + bool + prompt "PSA ECC sect239k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_283 + bool + prompt "PSA ECC sect283k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_409 + bool + prompt "PSA ECC sect409k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_K1_571 + bool + prompt "PSA ECC sect571k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_163 + bool + prompt "PSA ECC sect163r1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163r1 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_SECT_R1_233 + bool + prompt "PSA ECC sect233r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_283 + bool + prompt "PSA ECC sect283r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_409 + bool + prompt "PSA ECC sect409r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R1_571 + bool + prompt "PSA ECC sect571r1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECT_R2_163 + bool + prompt "PSA ECC sect163r2 support (weak)" if !PSA_PROMPTLESS + help + Warning: The 163-bit curve sect163r2 is weak and deprecated and is + only recommended for use in legacy protocols. + +config PSA_WANT_ECC_FRP_V1_256 + bool + prompt "PSA ECC FRP256v1 support" if !PSA_PROMPTLESS + +endmenu # Elliptic Curve type support + +config PSA_WANT_ALG_RSA_OAEP + bool + prompt "PSA RSA OAEP asymmetric encryption support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + bool + prompt "PSA RSA PKCS#1 v1.5 asymmetric encryption support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN + bool + prompt "PSA RSA PKCS#1 v1.5 message signature support, with hashing" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN_RAW + bool + prompt "PSA RSA raw PKCS#1 v1.5 message signature support, without hashing)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PSS + bool + prompt "PSA RSA PSS message signature support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PSS_ANY_SALT + bool + prompt "PSA RSA PSS message signature support, any salt length" if !PSA_PROMPTLESS + +endmenu # PSA Asymmetric support + +config PSA_WANT_ALG_JPAKE + bool + prompt "PSA EC J-PAKE support" if !PSA_PROMPTLESS + select EXPERIMENTAL if !NET_L2_OPENTHREAD + +config PSA_WANT_ALG_SPAKE2P_HMAC + bool + prompt "PSA SPAKE2+ HMAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SPAKE2P_CMAC + bool + prompt "PSA SPAKE2+ CMAC support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SPAKE2P_MATTER + bool + prompt "PSA SPAKE2+ MATTER support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_SRP_6 + bool + prompt "PSA SRP-6 support" if !PSA_PROMPTLESS + select EXPERIMENTAL + +config PSA_WANT_ALG_SRP_PASSWORD_HASH + bool + prompt "PSA SRP password hash support" if !PSA_PROMPTLESS + select EXPERIMENTAL + + +config PSA_WANT_ALG_PURE_EDDSA + bool + prompt "PSA PURE_EDDSA support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED25519PH + bool + prompt "PSA ED25519PH support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED448PH + bool + prompt "PSA ED448PH support" if !PSA_PROMPTLESS diff --git a/modules/mbedtls/Kconfig.tls-generic b/modules/mbedtls/Kconfig.tls-generic index 3c0e17c0fe3..d629c1b1d2a 100644 --- a/modules/mbedtls/Kconfig.tls-generic +++ b/modules/mbedtls/Kconfig.tls-generic @@ -9,6 +9,8 @@ menu "TLS configuration" menu "Supported TLS version" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_TLS_VERSION_1_0 bool "Support for TLS 1.0" select MBEDTLS_CIPHER @@ -33,6 +35,8 @@ config MBEDTLS_DTLS bool "Support for DTLS" depends on MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 +endif + config MBEDTLS_SSL_EXPORT_KEYS bool "Support for exporting SSL key block and master secret" depends on MBEDTLS_TLS_VERSION_1_0 || MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 @@ -47,6 +51,8 @@ menu "Ciphersuite configuration" comment "Supported key exchange modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_ALL_ENABLED bool "All available ciphersuite modes" select MBEDTLS_KEY_EXCHANGE_PSK_ENABLED @@ -81,6 +87,8 @@ config MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +endif + config MBEDTLS_PSK_MAX_LEN int "Max size of TLS pre-shared keys" default 32 @@ -88,6 +96,8 @@ config MBEDTLS_PSK_MAX_LEN help Max size of TLS pre-shared keys, in bytes. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_RSA_ENABLED bool "RSA-only based ciphersuite modes" default y if !NET_L2_OPENTHREAD @@ -202,6 +212,7 @@ config MBEDTLS_ECP_NIST_OPTIM bool "NSIT curves optimization" endif +endif # !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) comment "Supported hash" @@ -226,6 +237,8 @@ config MBEDTLS_HASH_SHA512_ENABLED comment "Supported cipher modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CIPHER_ALL_ENABLED bool "All available ciphers" select MBEDTLS_CIPHER_AES_ENABLED @@ -299,8 +312,12 @@ config MBEDTLS_CHACHAPOLY_AEAD_ENABLED bool "ChaCha20-Poly1305 AEAD algorithm" depends on MBEDTLS_CIPHER_CHACHA20_ENABLED || MBEDTLS_MAC_POLY1305_ENABLED +endif + comment "Supported message authentication methods" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MAC_ALL_ENABLED bool "All available MAC methods" select MBEDTLS_MAC_MD4_ENABLED @@ -349,10 +366,14 @@ config MBEDTLS_MAC_CMAC_ENABLED bool "CMAC (Cipher-based Message Authentication Code) mode for block ciphers." depends on MBEDTLS_CIPHER_AES_ENABLED || MBEDTLS_CIPHER_DES_ENABLED +endif + endmenu comment "Random number generators" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CTR_DRBG_ENABLED bool "CTR_DRBG AES-256-based random generator" depends on MBEDTLS_CIPHER_AES_ENABLED @@ -362,14 +383,20 @@ config MBEDTLS_HMAC_DRBG_ENABLED bool "HMAC_DRBG random generator" select MBEDTLS_MD +endif + comment "Other configurations" config MBEDTLS_CIPHER bool "generic cipher layer." +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MD bool "generic message digest layer." +endif + config MBEDTLS_GENPRIME_ENABLED bool "prime-number generation code." @@ -387,11 +414,15 @@ config MBEDTLS_HAVE_ASM of asymmetric cryptography, however this might have an impact on the code size. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_ENTROPY_ENABLED bool "MbedTLS generic entropy pool" depends on MBEDTLS_MAC_SHA256_ENABLED || MBEDTLS_MAC_SHA384_ENABLED || MBEDTLS_MAC_SHA512_ENABLED default y if MBEDTLS_ZEPHYR_ENTROPY +endif + config MBEDTLS_OPENTHREAD_OPTIMIZATIONS_ENABLED bool "MbedTLS optimizations for OpenThread" depends on NET_L2_OPENTHREAD diff --git a/modules/mbedtls/configs/config-mini-tls1_1.h b/modules/mbedtls/configs/config-mini-tls1_1.h index 2bce8647caf..da8bf795c1d 100644 --- a/modules/mbedtls/configs/config-mini-tls1_1.h +++ b/modules/mbedtls/configs/config-mini-tls1_1.h @@ -59,6 +59,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_CIPHER_MODE_CBC diff --git a/modules/mbedtls/configs/config-no-entropy.h b/modules/mbedtls/configs/config-no-entropy.h index b5295bf1fb7..b3406a394b4 100644 --- a/modules/mbedtls/configs/config-no-entropy.h +++ b/modules/mbedtls/configs/config-no-entropy.h @@ -62,6 +62,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_CIPHER_MODE_CBC diff --git a/modules/mbedtls/configs/config-suite-b.h b/modules/mbedtls/configs/config-suite-b.h index 6f2cc963bd1..7468f763358 100644 --- a/modules/mbedtls/configs/config-suite-b.h +++ b/modules/mbedtls/configs/config-suite-b.h @@ -66,6 +66,7 @@ /* System support */ #define MBEDTLS_HAVE_ASM #define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT /* mbed TLS feature support */ #define MBEDTLS_ECP_DP_SECP256R1_ENABLED diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index 7cf85731c85..2d1b53c54fd 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -37,6 +37,7 @@ #if defined(CONFIG_MBEDTLS_HAVE_TIME_DATE) #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE +#define MBEDTLS_PLATFORM_MS_TIME_ALT #endif #if defined(CONFIG_MBEDTLS_TEST) diff --git a/modules/mbedtls/zephyr_init.c b/modules/mbedtls/zephyr_init.c index d882b0aedb8..49c9ffc8aff 100644 --- a/modules/mbedtls/zephyr_init.c +++ b/modules/mbedtls/zephyr_init.c @@ -15,6 +15,8 @@ #include #include #include +#include + #include @@ -45,7 +47,7 @@ static void init_heap(void) #define init_heap(...) #endif /* CONFIG_MBEDTLS_ENABLE_HEAP && MBEDTLS_MEMORY_BUFFER_ALLOC_C */ -#if defined(CONFIG_MBEDTLS_ZEPHYR_ENTROPY) +#if defined(CONFIG_MBEDTLS_ZEPHYR_ENTROPY) && !defined(CONFIG_NRF_CC3XX_PLATFORM) static const struct device *const entropy_dev = DEVICE_DT_GET_OR_NULL(DT_CHOSEN(zephyr_entropy)); @@ -107,3 +109,9 @@ int mbedtls_init(void) { return _mbedtls_init(); } + +/* TLS 1.3 ticket lifetime needs a timing interface */ +mbedtls_ms_time_t mbedtls_ms_time(void) +{ + return (mbedtls_ms_time_t)k_uptime_get(); +} diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 2b2b593f82f..5b64d3be2f5 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -3,10 +3,19 @@ if(CONFIG_OPENTHREAD_SOURCES) set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +macro(kconfig_to_ot_option kconfig_option ot_config description) + if(${kconfig_option}) + set(${ot_config} ON CACHE BOOL "${description}" FORCE) + else() + set(${ot_config} OFF CACHE BOOL "${description}" FORCE) + endif() +endmacro() + # OpenThread options set(OT_BUILD_EXECUTABLES OFF CACHE BOOL "Disable OpenThread samples") set(OT_BUILTIN_MBEDTLS_MANAGEMENT OFF CACHE BOOL "Use Zephyr's mbedTLS heap") set(OT_PLATFORM "zephyr" CACHE STRING "Zephyr as a target platform") +set(OT_PLATFORM_POWER_CALIBRATION OFF CACHE BOOL "Use Zephyr's power calibration handled by Radio Driver") set(OT_THREAD_VERSION ${CONFIG_OPENTHREAD_THREAD_VERSION} CACHE STRING "User selected Thread stack version") set(OT_CLI_TRANSPORT "CONSOLE" CACHE STRING "Set CLI to use console interpreter") @@ -28,476 +37,96 @@ elseif(CONFIG_OPENTHREAD_MTD) set(OT_MTD ON CACHE BOOL "Enable MTD" FORCE) endif() -if(CONFIG_OPENTHREAD_ANYCAST_LOCATOR) - set(OT_ANYCAST_LOCATOR ON CACHE BOOL "Enable anycast locator" FORCE) -else() - set(OT_ANYCAST_LOCATOR OFF CACHE BOOL "Enable anycast locator" FORCE) -endif() - -if(CONFIG_ASSERT) - set(OT_ASSERT ON CACHE BOOL "Enable assert function OT_ASSERT()" FORCE) -else() - set(OT_ASSERT OFF CACHE BOOL "Enable assert function OT_ASSERT()" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER) - set(OT_BACKBONE_ROUTER ON CACHE BOOL "Enable backbone router functionality" FORCE) -else() - set(OT_BACKBONE_ROUTER OFF CACHE BOOL "Enable backbone router functionality" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING) - set(OT_BACKBONE_ROUTER_DUA_NDPROXYING ON CACHE BOOL "Enable BBR DUA ND Proxy support" FORCE) -else() - set(OT_BACKBONE_ROUTER_DUA_NDPROXYING OFF CACHE BOOL "Enable BBR DUA ND Proxy support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING) - set(OT_BACKBONE_ROUTER_MULTICAST_ROUTING ON CACHE BOOL "Enable BBR MR support" FORCE) -else() - set(OT_BACKBONE_ROUTER_MULTICAST_ROUTING OFF CACHE BOOL "Enable BBR MR support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_AGENT) - set(OT_BORDER_AGENT ON CACHE BOOL "Enable Border Agent" FORCE) -else() - set(OT_BORDER_AGENT OFF CACHE BOOL "Enable Border Agent" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTER) - set(OT_BORDER_ROUTER ON CACHE BOOL "Enable Border Router" FORCE) -else() - set(OT_BORDER_ROUTER OFF CACHE BOOL "Enable Border Router" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING) - set(OT_BORDER_ROUTING ON CACHE BOOL "Enable Border routing" FORCE) -else() - set(OT_BORDER_ROUTING OFF CACHE BOOL "Enable Border routing" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING_COUNTERS) - set(OT_BORDER_ROUTING_COUNTERS ON CACHE BOOL "Enable Border routing counters" FORCE) -else() - set(OT_BORDER_ROUTING_COUNTERS OFF CACHE BOOL "Enable Border routing counters" FORCE) -endif() - -if(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD) - set(OT_BORDER_ROUTING_DHCP6_PD ON CACHE BOOL "DHCPv6-PD support in border routing" FORCE) -else() - set(OT_BORDER_ROUTING_DHCP6_PD OFF CACHE BOOL "DHCPv6-PD support in border routing" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CHANNEL_MANAGER) - set(OT_CHANNEL_MANAGER ON CACHE BOOL "Enable channel manager support" FORCE) -else() - set(OT_CHANNEL_MANAGER OFF CACHE BOOL "Enable channel manager support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CHANNEL_MONITOR) - set(OT_CHANNEL_MONITOR ON CACHE BOOL "Enable channel monitor support" FORCE) -else() - set(OT_CHANNEL_MONITOR OFF CACHE BOOL "Enable channel monitor support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP) - set(OT_COAP ON CACHE BOOL "Enable CoAP API" FORCE) -else() - set(OT_COAP OFF CACHE BOOL "Enable CoAP API" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP_BLOCK) - set(OT_COAP_BLOCK ON CACHE BOOL "Enable CoAP Block-wise option support" FORCE) -else() - set(OT_COAP_BLOCK OFF CACHE BOOL "Enable CoAP Block-wise option support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAP_OBSERVE) - set(OT_COAP_OBSERVE ON CACHE BOOL "Enable CoAP Observe option support" FORCE) -else() - set(OT_COAP_OBSERVE OFF CACHE BOOL "Enable CoAP Observe option support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COAPS) - set(OT_COAPS ON CACHE BOOL "Enable secure CoAP API support" FORCE) -else() - set(OT_COAPS OFF CACHE BOOL "Enable secure CoAP API support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COMMISSIONER) - set(OT_COMMISSIONER ON CACHE BOOL "Enable Commissioner" FORCE) -else() - set(OT_COMMISSIONER OFF CACHE BOOL "Enable Commissioner" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_AUTO_SYNC) - set(OT_CSL_AUTO_SYNC ON CACHE BOOL "Enable csl autosync" FORCE) -else() - set(OT_CSL_AUTO_SYNC OFF CACHE BOOL "Enable csl autosync" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_DEBUG) - set(OT_CSL_DEBUG ON CACHE BOOL "Enable CSL debug" FORCE) -else() - set(OT_CSL_DEBUG OFF CACHE BOOL "Enable CSL debug" FORCE) -endif() - -if(CONFIG_OPENTHREAD_CSL_RECEIVER) - set(OT_CSL_RECEIVER ON CACHE BOOL "Enable CSL receiver feature for Thread 1.2" FORCE) -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() - 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() - set(OT_DHCP6_CLIENT OFF CACHE BOOL "Enable DHCPv6 Client" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DHCP6_SERVER) - set(OT_DHCP6_SERVER ON CACHE BOOL "Enable DHCPv6 Server" FORCE) -else() - set(OT_DHCP6_SERVER OFF CACHE BOOL "Enable DHCPv6 Server" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DIAG) - set(OT_DIAGNOSTIC ON CACHE BOOL "Enable Diagnostics support" FORCE) -else() - set(OT_DIAGNOSTIC OFF CACHE BOOL "Enable Diagnostics support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_CLIENT) - set(OT_DNS_CLIENT ON CACHE BOOL "Enable DNS client support" FORCE) -else() - set(OT_DNS_CLIENT OFF CACHE BOOL "Enable DNS client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_CLIENT_OVER_TCP) - set(OT_DNS_CLIENT_OVER_TCP ON CACHE BOOL "Enable dns query over tcp" FORCE) -else() - set(OT_DNS_CLIENT_OVER_TCP OFF CACHE BOOL "Enable dns query over tcp" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_DSO) - set(OT_DNS_DSO ON CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) -else() - set(OT_DNS_DSO OFF CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY) - set(OT_DNS_UPSTREAM_QUERY ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) -else() - set(OT_DNS_UPSTREAM_QUERY OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DNSSD_SERVER) - set(OT_DNSSD_SERVER ON CACHE BOOL "Enable DNS-SD server support" FORCE) -else() - set(OT_DNSSD_SERVER OFF CACHE BOOL "Enable DNS-SD server support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_DUA) - set(OT_DUA ON CACHE BOOL "Enable Domain Unicast Address feature for Thread 1.2" FORCE) -else() - set(OT_DUA OFF CACHE BOOL "Enable Domain Unicast Address feature for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_ECDSA) - set(OT_ECDSA ON CACHE BOOL "Enable ECDSA support" FORCE) -else() - set(OT_ECDSA OFF CACHE BOOL "Enable ECDSA support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_ENABLE_SERVICE) - set(OT_SERVICE ON CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) -else() - set(OT_SERVICE OFF CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) -endif() - -if(CONFIG_OPENTHREAD_EXTERNAL_HEAP) - set(OT_EXTERNAL_HEAP ON CACHE BOOL "Enable external heap support" FORCE) -else() - set(OT_EXTERNAL_HEAP OFF CACHE BOOL "Enable external heap support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_FIREWALL) - set(OT_FIREWALL ON CACHE BOOL "Enable firewall" FORCE) -else() - set(OT_FIREWALL OFF CACHE BOOL "Enable firewall" FORCE) -endif() - -if(CONFIG_OPENTHREAD_FULL_LOGS) - set(OT_FULL_LOGS ON CACHE BOOL "Enable full logs" FORCE) -else() - set(OT_FULL_LOGS OFF CACHE BOOL "Enable full logs" FORCE) -endif() - -if(CONFIG_OPENTHREAD_HISTORY_TRACKER) - set(OT_HISTORY_TRACKER ON CACHE BOOL "Enable history tracker support." FORCE) -else() - set(OT_HISTORY_TRACKER OFF CACHE BOOL "Enable history tracker support." FORCE) -endif() - -if(CONFIG_OPENTHREAD_IP6_FRAGM) - set(OT_IP6_FRAGM ON CACHE BOOL "Enable IPv6 fragmentation support" FORCE) -else() - set(OT_IP6_FRAGM OFF CACHE BOOL "Enable IPv6 fragmentation support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_JAM_DETECTION) - set(OT_JAM_DETECTION ON CACHE BOOL "Enable Jam Detection" FORCE) -else() - set(OT_JAM_DETECTION OFF CACHE BOOL "Enable Jam Detection" FORCE) -endif() +kconfig_to_ot_option(CONFIG_OPENTHREAD_ANYCAST_LOCATOR OT_ANYCAST_LOCATOR "Enable anycast locator") +kconfig_to_ot_option(CONFIG_ASSERT OT_ASSERT "Enable assert function OT_ASSERT()") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER OT_BACKBONE_ROUTER "Enable backbone router functionality") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING OT_BACKBONE_ROUTER_DUA_NDPROXYING "Enable BBR DUA ND Proxy support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING OT_BACKBONE_ROUTER_MULTICAST_ROUTING "Enable BBR MR support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BLE_TCAT OT_BLE_TCAT "Enable BLE TCAT support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_AGENT OT_BORDER_AGENT "Enable Border Agent") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTER OT_BORDER_ROUTER "Enable Border Router") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING OT_BORDER_ROUTING "Enable Border routing") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_COUNTERS OT_BORDER_ROUTING_COUNTERS "Enable Border routing counters") +kconfig_to_ot_option(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD OT_BORDER_ROUTING_DHCP6_PD "DHCPv6-PD support in border routing") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MANAGER OT_CHANNEL_MANAGER "Enable channel manager support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CHANNEL_MONITOR OT_CHANNEL_MONITOR "Enable channel monitor support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP OT_COAP "Enable CoAP API") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP_BLOCK OT_COAP_BLOCK "Enable CoAP Block-wise option support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAP_OBSERVE OT_COAP_OBSERVE "Enable CoAP Observe option support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COAPS OT_COAPS "Enable secure CoAP API support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_COMMISSIONER OT_COMMISSIONER "Enable Commissioner") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_AUTO_SYNC OT_CSL_AUTO_SYNC "Enable csl autosync") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_DEBUG OT_CSL_DEBUG "Enable CSL debug") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_RECEIVER OT_CSL_RECEIVER "Enable CSL receiver feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_CSL_RECEIVER_LOCAL_TIME_SYNC OT_CSL_RECEIVER_LOCAL_TIME_SYNC "Use local time for CSL sync") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DATASET_UPDATER OT_DATASET_UPDATER "Enable Dataset updater") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DEVICE_PROP_LEADER_WEIGHT OT_DEVICE_PROP_LEADER_WEIGHT "Enable device props for leader weight") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DHCP6_CLIENT OT_DHCP6_CLIENT "Enable DHCPv6 Client") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DHCP6_SERVER OT_DHCP6_SERVER "Enable DHCPv6 Server") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DIAG OT_DIAGNOSTIC "Enable Diagnostics support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_CLIENT OT_DNS_CLIENT "Enable DNS client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_CLIENT_OVER_TCP OT_DNS_CLIENT_OVER_TCP "Enable dns query over tcp") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_DSO OT_DNS_DSO "Enable DNS Stateful Operations (DSO) support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY OT_DNS_UPSTREAM_QUERY "Enable forwarding DNS queries to upstream") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DNSSD_SERVER OT_DNSSD_SERVER "Enable DNS-SD server support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_DUA OT_DUA "Enable Domain Unicast Address feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_ECDSA OT_ECDSA "Enable ECDSA support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_ENABLE_SERVICE OT_SERVICE "Enable Service entries in Thread Network Data") +kconfig_to_ot_option(CONFIG_OPENTHREAD_EXTERNAL_HEAP OT_EXTERNAL_HEAP "Enable external heap support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_FIREWALL OT_FIREWALL "Enable firewall") +kconfig_to_ot_option(CONFIG_OPENTHREAD_FULL_LOGS OT_FULL_LOGS "Enable full logs") +kconfig_to_ot_option(CONFIG_OPENTHREAD_HISTORY_TRACKER OT_HISTORY_TRACKER "Enable history tracker support.") +kconfig_to_ot_option(CONFIG_OPENTHREAD_IP6_FRAGM OT_IP6_FRAGM "Enable IPv6 fragmentation support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_JAM_DETECTION OT_JAM_DETECTION "Enable Jam Detection") +kconfig_to_ot_option(CONFIG_OPENTHREAD_JOINER OT_JOINER "Enable Joiner") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LEGACY OT_LEGACY "Enable legacy network support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR OT_LINK_METRICS_INITIATOR "Enable Link Metrics initiator for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_MANAGER OT_LINK_METRICS_MANAGER "Enable Link Metrics manager for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT OT_LINK_METRICS_SUBJECT "Enable Link Metrics subject for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC OT_LOG_LEVEL_DYNAMIC "Enable dynamic log level control") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MAC_FILTER OT_MAC_FILTER "Enable MAC filter support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MESH_DIAG OT_MESH_DIAG "Enable Mesh Diagnostics") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MESSAGE_USE_HEAP OT_MESSAGE_USE_HEAP "Enable heap allocator for message buffers") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MLE_LONG_ROUTES OT_MLE_LONG_ROUTES "Enable MLE long routes support (Experimental)") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MLR OT_MLR "Enable Multicast Listener Registration feature for Thread 1.2") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MULTIPAN_RCP OT_MULTIPAN_RCP "Enable Multi-PAN RCP") +kconfig_to_ot_option(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE OT_MULTIPLE_INSTANCE "Enable multiple instances") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NAT64_BORDER_ROUTING OT_NAT64_BORDER_ROUTING "Enable border routing NAT64 support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NAT64_TRANSLATOR OT_NAT64_TRANSLATOR "Enable NAT64 translator") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT OT_NEIGHBOR_DISCOVERY_AGENT "Enable neighbor discovery agent support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NETDIAG_CLIENT OT_NETDIAG_CLIENT "Enable TMF network diagnostics on clients") +kconfig_to_ot_option(CONFIG_OPENTHREAD_NETDATA_PUBLISHER OT_NETDATA_PUBLISHER "Enable Thread Network Data publisher") +kconfig_to_ot_option(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT OT_OPERATIONAL_DATASET_AUTO_INIT "Enable operational dataset auto init") +kconfig_to_ot_option(CONFIG_OPENTHREAD_OTNS OT_OTNS "Enable OTNS support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PING_SENDER OT_PING_SENDER "Enable ping sender support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE OT_PLATFORM_BOOTLOADER_MODE "Enable platform bootloader mode support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_KEY_REF OT_PLATFORM_KEY_REF "Enable platform key reference support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_NETIF OT_PLATFORM_NETIF "Enable platform netif support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_PLATFORM_UDP OT_PLATFORM_UDP "Enable platform UDP support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE OT_15_4 "Enable 802.15.4 radio") +kconfig_to_ot_option(CONFIG_OPENTHREAD_RAW OT_LINK_RAW "Enable Link Raw") +kconfig_to_ot_option(CONFIG_OPENTHREAD_REFERENCE_DEVICE OT_REFERENCE_DEVICE "Enable Thread Certification Reference Device") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SETTINGS_RAM OT_SETTINGS_RAM "Enable volatile-only storage of settings") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SLAAC OT_SLAAC "Enable SLAAC") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SNTP_CLIENT OT_SNTP_CLIENT "Enable SNTP Client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_CLIENT OT_SRP_CLIENT "Enable SRP Client support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_SRP_SERVER OT_SRP_SERVER "Enable SRP Server support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TCP_ENABLE OT_TCP "Enable TCP support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TIME_SYNC OT_TIME_SYNC "Enable the time synchronization service feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TREL OT_TREL "Enable TREL radio link for Thread over Infrastructure feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TX_BEACON_PAYLOAD OT_TX_BEACON_PAYLOAD "Enable tx beacon payload support") +kconfig_to_ot_option(CONFIG_OPENTHREAD_TX_QUEUE_STATISTICS OT_TX_QUEUE_STATS "Enable tx queue statistics") +kconfig_to_ot_option(CONFIG_OPENTHREAD_UDP_FORWARD OT_UDP_FORWARD "Enable UDP forward feature") +kconfig_to_ot_option(CONFIG_OPENTHREAD_UPTIME OT_UPTIME "Enable support for tracking OpenThread instance's uptime") -if(CONFIG_OPENTHREAD_JOINER) - set(OT_JOINER ON CACHE BOOL "Enable Joiner" FORCE) -else() - set(OT_JOINER OFF CACHE BOOL "Enable Joiner" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LEGACY) - set(OT_LEGACY ON CACHE BOOL "Enable legacy network support" FORCE) -else() - set(OT_LEGACY OFF CACHE BOOL "Enable legacy network support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR) - set(OT_LINK_METRICS_INITIATOR ON CACHE BOOL "Enable Link Metrics initiator for Thread 1.2" FORCE) -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() - set(OT_LINK_METRICS_SUBJECT OFF CACHE BOOL "Enable Link Metrics subject for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_LOG_LEVEL_DYNAMIC) - set(OT_LOG_LEVEL_DYNAMIC ON CACHE BOOL "Enable dynamic log level control" FORCE) -else() - set(OT_LOG_LEVEL_DYNAMIC OFF CACHE BOOL "Enable dynamic log level control" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MAC_FILTER) - set(OT_MAC_FILTER ON CACHE BOOL "Enable MAC filter support" FORCE) -else() - set(OT_MAC_FILTER OFF CACHE BOOL "Enable MAC filter support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MESH_DIAG) - set(OT_MESH_DIAG ON CACHE BOOL "Enable Mesh Diagnostics" FORCE) -else() - set(OT_MESH_DIAG OFF CACHE BOOL "Enable Mesh Diagnostics" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MESSAGE_USE_HEAP) - set(OT_MESSAGE_USE_HEAP ON CACHE BOOL "Enable heap allocator for message buffers" FORCE) -else() - set(OT_MESSAGE_USE_HEAP OFF CACHE BOOL "Enable heap allocator for message buffers" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MLE_LONG_ROUTES) - set(OT_MLE_LONG_ROUTES ON CACHE BOOL "Enable MLE long routes support (Experimental)" FORCE) -else() - set(OT_MLE_LONG_ROUTES OFF CACHE BOOL "Enable MLE long routes support (Experimental)" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MLR) - set(OT_MLR ON CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) -else() - set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) -endif() - -if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) - set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) -else() - set(OT_MULTIPLE_INSTANCE OFF CACHE BOOL "Enable multiple instances" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NAT64_BORDER_ROUTING) - set(OT_NAT64_BORDER_ROUTING ON CACHE BOOL "Enable border routing NAT64 support" FORCE) -else() - set(OT_NAT64_BORDER_ROUTING OFF CACHE BOOL "Enable border routing NAT64 support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NAT64_TRANSLATOR) - set(OT_NAT64_TRANSLATOR ON CACHE BOOL "Enable NAT64 translator" FORCE) -else() - set(OT_NAT64_TRANSLATOR OFF CACHE BOOL "Enable NAT64 translator" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT) - set(OT_NEIGHBOR_DISCOVERY_AGENT ON CACHE BOOL "Enable neighbor discovery agent support" FORCE) -else() - set(OT_NEIGHBOR_DISCOVERY_AGENT OFF CACHE BOOL "Enable neighbor discovery agent support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NETDIAG_CLIENT) - set(OT_NETDIAG_CLIENT ON CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -else() - set(OT_NETDIAG_CLIENT OFF CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -endif() - -if(CONFIG_OPENTHREAD_NETDATA_PUBLISHER) - set(OT_NETDATA_PUBLISHER ON CACHE BOOL "Enable Thread Network Data publisher" FORCE) -else() - set(OT_NETDATA_PUBLISHER OFF CACHE BOOL "Enable Thread Network Data publisher" FORCE) -endif() - -if(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT) - set(OT_OPERATIONAL_DATASET_AUTO_INIT ON CACHE BOOL "Enable operational dataset auto init" FORCE) -else() - set(OT_OPERATIONAL_DATASET_AUTO_INIT OFF CACHE BOOL "Enable operational dataset auto init" FORCE) -endif() - -if(CONFIG_OPENTHREAD_OTNS) - set(OT_OTNS ON CACHE BOOL "Enable OTNS support" FORCE) -else() - set(OT_OTNS OFF CACHE BOOL "Enable OTNS support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PING_SENDER) - set(OT_PING_SENDER ON CACHE BOOL "Enable ping sender support" FORCE) -else() - set(OT_PING_SENDER OFF CACHE BOOL "Enable ping sender support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PLATFORM_NETIF) - set(OT_PLATFORM_NETIF ON CACHE BOOL "Enable platform netif support" FORCE) -else() - set(OT_PLATFORM_NETIF OFF CACHE BOOL "Enable platform netif support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_PLATFORM_UDP) - set(OT_PLATFORM_UDP ON CACHE BOOL "Enable platform UDP support" FORCE) -else() - set(OT_PLATFORM_UDP OFF CACHE BOOL "Enable platform UDP support" FORCE) +if(CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE) + set(OT_NCP_VENDOR_HOOK_SOURCE ${CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE} CACHE STRING "NCP vendor hook source file name" FORCE) endif() if(CONFIG_OPENTHREAD_POWER_SUPPLY) set(OT_POWER_SUPPLY ${CONFIG_OPENTHREAD_POWER_SUPPLY} CACHE STRING "Power supply configuration" FORCE) endif() -if(CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE) - set(OT_15_4 ON CACHE BOOL "Enable 802.15.4 radio" FORCE) -else() - set(OT_15_4 OFF CACHE BOOL "Enable 802.15.4 radio" FORCE) -endif() - -if(CONFIG_OPENTHREAD_RAW) - set(OT_LINK_RAW ON CACHE BOOL "Enable Link Raw" FORCE) -else() - set(OT_LINK_RAW OFF CACHE BOOL "Enable Link Raw" FORCE) -endif() - -if(CONFIG_OPENTHREAD_REFERENCE_DEVICE) - set(OT_REFERENCE_DEVICE ON CACHE BOOL "Enable Thread Certification Reference Device" FORCE) -else() - set(OT_REFERENCE_DEVICE OFF CACHE BOOL "Enable Thread Certification Reference Device" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SETTINGS_RAM) - set(OT_SETTINGS_RAM ON CACHE BOOL "Enable volatile-only storage of settings" FORCE) -else() - set(OT_SETTINGS_RAM OFF CACHE BOOL "Enable volatile-only storage of settings" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SLAAC) - set(OT_SLAAC ON CACHE BOOL "Enable SLAAC" FORCE) -else() - set(OT_SLAAC OFF CACHE BOOL "Enable SLAAC" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SNTP_CLIENT) - set(OT_SNTP_CLIENT ON CACHE BOOL "Enable SNTP Client support" FORCE) -else() - set(OT_SNTP_CLIENT OFF CACHE BOOL "Enable SNTP Client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SRP_CLIENT) - set(OT_SRP_CLIENT ON CACHE BOOL "Enable SRP Client support" FORCE) -else() - set(OT_SRP_CLIENT OFF CACHE BOOL "Enable SRP Client support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_SRP_SERVER) - set(OT_SRP_SERVER ON CACHE BOOL "Enable SRP Server support" FORCE) -else() - set(OT_SRP_SERVER OFF CACHE BOOL "Enable SRP Server support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TCP_ENABLE) - set(OT_TCP ON CACHE BOOL "Enable TCP support" FORCE) -else() - set(OT_TCP OFF CACHE BOOL "Enable TCP support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TIME_SYNC) - set(OT_TIME_SYNC ON CACHE BOOL "Enable the time synchronization service feature" FORCE) -else() - set(OT_TIME_SYNC OFF CACHE BOOL "Enable the time synchronization service feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TREL) - set(OT_TREL ON CACHE BOOL "Enable TREL radio link for Thread over Infrastructure feature" FORCE) -else() - set(OT_TREL OFF CACHE BOOL "Enable TREL radio link for Thread over Infrastructure feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TX_BEACON_PAYLOAD) - set(OT_TX_BEACON_PAYLOAD ON CACHE BOOL "Enable tx beacon payload support" FORCE) -else() - set(OT_TX_BEACON_PAYLOAD OFF CACHE BOOL "Enable tx beacon payload support" FORCE) -endif() - -if(CONFIG_OPENTHREAD_TX_QUEUE_STATISTICS) - set(OT_TX_QUEUE_STATS ON CACHE BOOL "Enable tx queue statistics" FORCE) -else() - set(OT_TX_QUEUE_STATS OFF CACHE BOOL "Enable tx queue statistics" FORCE) -endif() - -if(CONFIG_OPENTHREAD_UDP_FORWARD) - set(OT_UDP_FORWARD ON CACHE BOOL "Enable UDP forward feature" FORCE) -else() - set(OT_UDP_FORWARD OFF CACHE BOOL "Enable UDP forward feature" FORCE) -endif() - -if(CONFIG_OPENTHREAD_UPTIME) - set(OT_UPTIME ON CACHE BOOL "Enable support for tracking OpenThread instance's uptime" FORCE) -else() - set(OT_UPTIME OFF CACHE BOOL "Enable support for tracking OpenThread instance's uptime" FORCE) -endif() - -if(CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE) - set(OT_NCP_VENDOR_HOOK_SOURCE ${CONFIG_OPENTHREAD_COPROCESSOR_VENDOR_HOOK_SOURCE} CACHE STRING "NCP vendor hook source file name" FORCE) -endif() - set(BUILD_TESTING OFF CACHE BOOL "Disable openthread cmake testing targets" FORCE) # Zephyr logging options diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index a75c9e8fd48..ba3990a348d 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -17,7 +17,7 @@ config OPENTHREAD_THREAD_VERSION_1_3 bool "Version 1.3" config OPENTHREAD_THREAD_VERSION_1_3_1 bool "Version 1.3.1" -endchoice +endchoice # OPENTHREAD_STACK_VERSION config OPENTHREAD_THREAD_VERSION string @@ -39,6 +39,10 @@ config OPENTHREAD_BACKBONE_ROUTER_DUA_NDPROXYING config OPENTHREAD_BACKBONE_ROUTER_MULTICAST_ROUTING bool "BBR MR support" +config OPENTHREAD_BLE_TCAT + bool "BLE TCAT support" + select EXPERIMENTAL + config OPENTHREAD_BORDER_AGENT bool "Border Agent support" @@ -214,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" @@ -242,6 +249,31 @@ config OPENTHREAD_OTNS config OPENTHREAD_PING_SENDER bool "Ping sender support" +config OPENTHREAD_PLATFORM_KEY_REF + bool "Platform cryptographic key reference support" + help + Enable usage of cryptographic key references instead of literal keys. + This requires a crypto backend library that supports key references. + +choice OPENTHREAD_PLATFORM_BOOTLOADER_MODE_CHOICE + prompt "Platform bootloader mode configuration" + optional + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION + bool "Bootloader mode support with boot mode retention API" + depends on RETENTION_BOOT_MODE && REBOOT + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO + bool "Bootloader mode support with GPIO pin trigger" + select OPENTHREAD_PLATFORM_BOOTLOADER_MODE +endchoice # OPENTHREAD_PLATFORM_BOOTLOADER_MODE + +config OPENTHREAD_PLATFORM_BOOTLOADER_MODE + bool + help + Platform bootloader mode support + config OPENTHREAD_PLATFORM_NETIF bool "Platform netif support" @@ -263,7 +295,7 @@ config OPENTHREAD_POWER_SUPPLY_EXTERNAL_STABLE config OPENTHREAD_POWER_SUPPLY_EXTERNAL_UNSTABLE bool "OT_POWER_SUPPLY_EXTERNAL_UNSTABLE" -endchoice +endchoice # OPENTHREAD_POWER_SUPPLY_CHOICE config OPENTHREAD_POWER_SUPPLY string diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index 891365b4672..542992e7fa1 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -181,3 +181,16 @@ config OPENTHREAD_DEFAULT_TX_POWER default 0 help Set the default TX output power [dBm] in radio driver for OpenThread purpose. + +config OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE + int "Openthread default TCAT stack size" + default 5120 if OPENTHREAD_CRYPTO_PSA + default 4200 + help + Openthread default TCAT stack size. + +config OPENTHREAD_BLE_TCAT_RING_BUF_SIZE + int "Openthread BLE ringbuffer size" + default 512 + help + Openthread BLE TCAT ringbuffer size. diff --git a/modules/openthread/platform/CMakeLists.txt b/modules/openthread/platform/CMakeLists.txt index d363bcda7df..542aa5186ea 100644 --- a/modules/openthread/platform/CMakeLists.txt +++ b/modules/openthread/platform/CMakeLists.txt @@ -10,6 +10,7 @@ zephyr_library_sources( spi.c ) +zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_BLE_TCAT ble.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_DIAG diag.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_COPROCESSOR uart.c) zephyr_library_sources_ifdef(CONFIG_OPENTHREAD_CRYPTO_PSA crypto_psa.c) diff --git a/modules/openthread/platform/ble.c b/modules/openthread/platform/ble.c new file mode 100644 index 00000000000..7b41556b617 --- /dev/null +++ b/modules/openthread/platform/ble.c @@ -0,0 +1,458 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* Zephyr OpenThread integration Library */ +#include + +/* OpenThread BLE driver API */ +#include + +/* Zephyr Logging */ + +#define LOG_MODULE_NAME net_openthread_tcat +#define LOG_LEVEL CONFIG_OPENTHREAD_LOG_LEVEL + +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + +/* BLE connection constants as defined in thread specification. */ +#define TOBLE_SERVICE_UUID 0xfffb +#define RX_CHARACTERISTIC_UUID \ + BT_UUID_128_ENCODE(0x6bd10d8b, 0x85a7, 0x4e5a, 0xba2d, 0xc83558a5f220) +#define TX_CHARACTERISTIC_UUID \ + BT_UUID_128_ENCODE(0x7fddf61f, 0x280a, 0x4773, 0xb448, 0xba1b8fe0dd69) + +#define BT_UUID_TCAT_SERVICE BT_UUID_DECLARE_16(TOBLE_SERVICE_UUID) +#define BT_UUID_TCAT_SERVICE_RX BT_UUID_DECLARE_128(RX_CHARACTERISTIC_UUID) +#define BT_UUID_TCAT_SERVICE_TX BT_UUID_DECLARE_128(TX_CHARACTERISTIC_UUID) + +#define PLAT_BLE_THREAD_DEALY 500 +#define PLAT_BLE_MSG_DATA_MAX CONFIG_BT_L2CAP_TX_MTU /* must match the maximum MTU size used */ + +#define PLAT_BLE_MSG_CONNECT (PLAT_BLE_MSG_DATA_MAX + 1U) +#define PLAT_BLE_MSG_DISCONNECT (PLAT_BLE_MSG_CONNECT + 1U) + +/* Zephyr Kernel Objects */ + +static void ot_plat_ble_thread(void *, void *, void *); +static uint8_t ot_plat_ble_msg_buf[PLAT_BLE_MSG_DATA_MAX]; + +static K_SEM_DEFINE(ot_plat_ble_init_semaphore, 0, 1); +static K_SEM_DEFINE(ot_plat_ble_event_semaphore, 0, K_SEM_MAX_LIMIT); +RING_BUF_DECLARE(ot_plat_ble_ring_buf, CONFIG_OPENTHREAD_BLE_TCAT_RING_BUF_SIZE); +static K_THREAD_DEFINE(ot_plat_ble_tid, CONFIG_OPENTHREAD_BLE_TCAT_THREAD_STACK_SIZE, + ot_plat_ble_thread, NULL, NULL, NULL, 5, 0, PLAT_BLE_THREAD_DEALY); + +/* OpenThread Objects */ + +static otInstance *ble_openthread_instance; + +/* BLE service Objects */ + +/* forward declaration for callback functions */ +static ssize_t on_receive(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags); +static void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value); + +/* Service Declaration and Registration */ +BT_GATT_SERVICE_DEFINE(my_service, BT_GATT_PRIMARY_SERVICE(BT_UUID_TCAT_SERVICE), + BT_GATT_CHARACTERISTIC(BT_UUID_TCAT_SERVICE_RX, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_WRITE_WITHOUT_RESP, + BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, NULL, + on_receive, NULL), + BT_GATT_CHARACTERISTIC(BT_UUID_TCAT_SERVICE_TX, BT_GATT_CHRC_NOTIFY, + BT_GATT_PERM_READ, NULL, NULL, NULL), + BT_GATT_CCC(on_cccd_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),); + +/* Zephyr BLE Objects */ + +/* forward declaration for callback functions */ +static void connected(struct bt_conn *conn, uint8_t err); +static void disconnected(struct bt_conn *conn, uint8_t reason); +static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); +static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout); + +static struct bt_conn *ot_plat_ble_connection; + +static struct bt_conn_cb conn_callbacks = {.connected = connected, + .disconnected = disconnected, + .le_param_req = le_param_req, + .le_param_updated = le_param_updated}; + +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +}; + +static const struct bt_data sd[] = { + BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(TOBLE_SERVICE_UUID)), +}; + +/* Zephyr BLE Message Queue and Thread */ + +static bool ot_plat_ble_queue_msg(const uint8_t *aData, uint16_t aLen, int8_t aRssi) +{ + otError error = OT_ERROR_NONE; + uint16_t len = 0; + + if (aLen <= PLAT_BLE_MSG_DATA_MAX && aData == NULL) { + return OT_ERROR_INVALID_ARGS; + } + + k_sched_lock(); + + len = sizeof(aLen) + sizeof(aRssi) + ((aLen <= PLAT_BLE_MSG_DATA_MAX) ? aLen : 0); + + if (ring_buf_space_get(&ot_plat_ble_ring_buf) >= len) { + ring_buf_put(&ot_plat_ble_ring_buf, (uint8_t *)&aLen, sizeof(aLen)); + ring_buf_put(&ot_plat_ble_ring_buf, &aRssi, sizeof(aRssi)); + if (aLen <= PLAT_BLE_MSG_DATA_MAX) { + ring_buf_put(&ot_plat_ble_ring_buf, aData, aLen); + } + k_sem_give(&ot_plat_ble_event_semaphore); + } else { + error = OT_ERROR_NO_BUFS; + } + + k_sched_unlock(); + + return error; +} + +static void ot_plat_ble_thread(void *unused1, void *unused2, void *unused3) +{ + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + ARG_UNUSED(unused3); + + uint16_t len; + int8_t rssi; + otBleRadioPacket my_packet; + + LOG_INF("%s started", __func__); + + while (1) { + k_sem_take(&ot_plat_ble_event_semaphore, K_FOREVER); + ring_buf_get(&ot_plat_ble_ring_buf, (uint8_t *)&len, sizeof(len)); + ring_buf_get(&ot_plat_ble_ring_buf, &rssi, sizeof(rssi)); + if (len <= PLAT_BLE_MSG_DATA_MAX) { + ring_buf_get(&ot_plat_ble_ring_buf, ot_plat_ble_msg_buf, len); + } + + openthread_api_mutex_lock(openthread_get_default_context()); + + if (len <= PLAT_BLE_MSG_DATA_MAX) { + /* The packet parameter in otPlatBleGattServerOnWriteRequest is not const. + * Re-write all members. + */ + my_packet.mValue = ot_plat_ble_msg_buf; + my_packet.mPower = rssi; + my_packet.mLength = len; + otPlatBleGattServerOnWriteRequest(ble_openthread_instance, 0, &my_packet); + } else if (len == PLAT_BLE_MSG_CONNECT) { + otPlatBleGapOnConnected(ble_openthread_instance, 0); + } else if (len == PLAT_BLE_MSG_DISCONNECT) { + otPlatBleGapOnDisconnected(ble_openthread_instance, 0); + } + openthread_api_mutex_unlock(openthread_get_default_context()); + } +} + +/* Zephyr BLE service callbacks */ + +/* This function is called whenever the RX Characteristic has been written to by a Client */ +static ssize_t on_receive(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags) +{ + LOG_DBG("Received data, handle %" PRIu16 ", len %" PRIu16, attr->handle, len); + + otError error = ot_plat_ble_queue_msg(buf, len, 0); + + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + + return len; +} + +/* This function is called whenever a Notification has been sent by the TX Characteristic */ +static void on_sent(struct bt_conn *conn, void *user_data) +{ + ARG_UNUSED(conn); + ARG_UNUSED(user_data); + + LOG_DBG("Data sent"); +} + +/* This function is called whenever the CCCD register has been changed by the client */ +void on_cccd_changed(const struct bt_gatt_attr *attr, uint16_t value) +{ + uint16_t mtu; + otError error = OT_ERROR_NONE; + + ARG_UNUSED(attr); + + switch (value) { + case BT_GATT_CCC_NOTIFY: + + error = ot_plat_ble_queue_msg(NULL, PLAT_BLE_MSG_CONNECT, 0); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("CCCD update (mtu=%" PRIu16 ")!", mtu); + + break; + + default: + break; + } +} + +otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, + const otBleRadioPacket *aPacket) +{ + ARG_UNUSED(aInstance); + + /* TO DO change to indications. */ + const struct bt_gatt_attr *attr = &my_service.attrs[3]; + + struct bt_gatt_notify_params params = {.uuid = BT_UUID_TCAT_SERVICE_TX, + .attr = attr, + .data = aPacket->mValue, + .len = aPacket->mLength, + .func = on_sent}; + + LOG_DBG("Send data, handle %d, len %d", attr->handle, aPacket->mLength); + + /* Only one connection supported */ + if (aHandle != 0) { + return OT_ERROR_INVALID_ARGS; + } + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_INVALID_STATE; + } + + /* Check whether notifications are enabled or not */ + if (bt_gatt_is_subscribed(ot_plat_ble_connection, attr, BT_GATT_CCC_NOTIFY)) { + if (bt_gatt_notify_cb(ot_plat_ble_connection, ¶ms)) { + LOG_WRN("Error, unable to send notification"); + return OT_ERROR_INVALID_ARGS; + } + } else { + LOG_WRN("Warning, notification not enabled on the selected attribute"); + return OT_ERROR_INVALID_STATE; + } + + return OT_ERROR_NONE; +} + +otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu) +{ + ARG_UNUSED(aInstance); + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_FAILED; + } + + if (aMtu != NULL) { + *aMtu = bt_gatt_get_mtu(ot_plat_ble_connection); + } + + return OT_ERROR_NONE; +} + +otError otPlatBleGapDisconnect(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + + if (ot_plat_ble_connection == NULL) { + return OT_ERROR_INVALID_STATE; + } + + if (bt_conn_disconnect(ot_plat_ble_connection, BT_HCI_ERR_REMOTE_USER_TERM_CONN)) { + return OT_ERROR_INVALID_STATE; + } + + return OT_ERROR_NONE; +} + +/* Zephyr BLE callbacks */ + +static void connected(struct bt_conn *conn, uint8_t err) +{ + struct bt_conn_info info; + char addr[BT_ADDR_LE_STR_LEN]; + uint16_t mtu; + otError error = OT_ERROR_NONE; + + ot_plat_ble_connection = bt_conn_ref(conn); + + if (err) { + LOG_WRN("Connection failed (err %u)", err); + return; + } else if (bt_conn_get_info(conn, &info)) { + LOG_WRN("Could not parse connection info"); + } else { + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("Connection established (mtu=%" PRIu16 ")!", mtu); + } +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + otError error = OT_ERROR_NONE; + + LOG_INF("Disconnected (reason %" PRIu8 ")", reason); + + if (ot_plat_ble_connection) { + bt_conn_unref(ot_plat_ble_connection); + ot_plat_ble_connection = NULL; + + error = ot_plat_ble_queue_msg(NULL, PLAT_BLE_MSG_DISCONNECT, 0); + if (error != OT_ERROR_NONE) { + LOG_WRN("Error queuing message: %s", otThreadErrorToString(error)); + } + } +} + +static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param) +{ + return true; +} + +static void le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, + uint16_t timeout) +{ + struct bt_conn_info info; + char addr[BT_ADDR_LE_STR_LEN]; + uint16_t mtu; + otError error = OT_ERROR_NONE; + + if (bt_conn_get_info(conn, &info)) { + LOG_INF("Could not parse connection info"); + } else { + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + error = otPlatBleGattMtuGet(ble_openthread_instance, &mtu); + + if (error != OT_ERROR_NONE) { + LOG_WRN("Error retrieving mtu: %s", otThreadErrorToString(error)); + } + + LOG_INF("Connection parameters updated (mtu=%" PRIu16 ")!", mtu); + } +} + +static void bt_ready(int err) +{ + if (err) { + LOG_WRN("BLE init failed with error code %d", err); + return; + } + + bt_conn_cb_register(&conn_callbacks); + k_sem_give(&ot_plat_ble_init_semaphore); /* BLE stack up an running */ +} + +otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval) +{ + ARG_UNUSED(aInstance); + ARG_UNUSED(aInterval); + + /* TO DO advertisement format change */ + int err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); + + if (err != 0 && err != -EALREADY) { + LOG_WRN("Advertising failed to start (err %d)", err); + return OT_ERROR_INVALID_STATE; + } + + LOG_INF("Advertising successfully started"); + + return OT_ERROR_NONE; +} + +otError otPlatBleGapAdvStop(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + + int err = bt_le_adv_stop(); + + if (err != 0 && err != -EALREADY) { + LOG_WRN("Advertisement failed to stop (err %d)", err); + return OT_ERROR_FAILED; + } + return OT_ERROR_NONE; +} + +/* Zephyr BLE initialization */ + +otError otPlatBleEnable(otInstance *aInstance) +{ + int err; + + ble_openthread_instance = aInstance; + err = bt_enable(bt_ready); + + if (err != 0 && err != -EALREADY) { + LOG_WRN("BLE enable failed with error code %d", err); + return OT_ERROR_FAILED; + } else if (err == -EALREADY) { + err = k_sem_take(&ot_plat_ble_init_semaphore, K_MSEC(500)); + return OT_ERROR_NONE; + } + + err = k_sem_take(&ot_plat_ble_init_semaphore, K_MSEC(500)); + + if (!err) { + LOG_INF("Bluetooth initialized"); + } else { + LOG_INF("BLE initialization did not complete in time"); + return OT_ERROR_FAILED; + } + + return OT_ERROR_NONE; +} + +otError otPlatBleDisable(otInstance *aInstance) +{ + ARG_UNUSED(aInstance); + /* This function intentionally does nothing since disabling advertisement disables BLE + * stack. + */ + return OT_ERROR_NONE; +} diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index e5b234ce030..c818c5695a3 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -16,6 +16,7 @@ #if defined(CONFIG_OPENTHREAD_ECDSA) #include +#include #endif static otError psaToOtError(psa_status_t aStatus) @@ -41,6 +42,8 @@ static psa_key_type_t toPsaKeyType(otCryptoKeyType aType) return PSA_KEY_TYPE_AES; case OT_CRYPTO_KEY_TYPE_HMAC: return PSA_KEY_TYPE_HMAC; + case OT_CRYPTO_KEY_TYPE_ECDSA: + return PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1); default: return PSA_KEY_TYPE_NONE; } @@ -53,12 +56,14 @@ static psa_algorithm_t toPsaAlgorithm(otCryptoKeyAlgorithm aAlgorithm) return PSA_ALG_ECB_NO_PADDING; case OT_CRYPTO_KEY_ALG_HMAC_SHA_256: return PSA_ALG_HMAC(PSA_ALG_SHA_256); + case OT_CRYPTO_KEY_ALG_ECDSA: + return PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256); default: /* * There is currently no constant like PSA_ALG_NONE, but 0 is used * to indicate an unknown algorithm. */ - return (psa_algorithm_t) 0; + return (psa_algorithm_t)0; } } @@ -82,16 +87,19 @@ static psa_key_usage_t toPsaKeyUsage(int aUsage) usage |= PSA_KEY_USAGE_SIGN_HASH; } + if (aUsage & OT_CRYPTO_KEY_USAGE_VERIFY_HASH) { + usage |= PSA_KEY_USAGE_VERIFY_HASH; + } + return usage; } static bool checkKeyUsage(int aUsage) { /* Check if only supported flags have been passed */ - int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT | - OT_CRYPTO_KEY_USAGE_ENCRYPT | - OT_CRYPTO_KEY_USAGE_DECRYPT | - OT_CRYPTO_KEY_USAGE_SIGN_HASH; + int supported_flags = OT_CRYPTO_KEY_USAGE_EXPORT | OT_CRYPTO_KEY_USAGE_ENCRYPT | + OT_CRYPTO_KEY_USAGE_DECRYPT | OT_CRYPTO_KEY_USAGE_SIGN_HASH | + OT_CRYPTO_KEY_USAGE_VERIFY_HASH; return (aUsage & ~supported_flags) == 0; } @@ -102,31 +110,6 @@ static bool checkContext(otCryptoContext *aContext, size_t aMinSize) return aContext != NULL && aContext->mContext != NULL && aContext->mContextSize >= aMinSize; } -static void ensureKeyIsLoaded(otCryptoKeyRef aKeyRef) -{ - /* - * The workaround below will no longer be need after updating TF-M version used in Zephyr - * to 1.5.0 (see upstream commit 42e77b561fcfe19819ff1e63cb7c0b672ee8ba41). - * In the recent versions of TF-M the concept of key handles and psa_open_key()/ - * psa_close_key() APIs have been being deprecated, but the version currently used in Zephyr - * is in the middle of that transition. Consequently, psa_destroy_key() and lots of other - * functions will fail when a key ID that they take as a parameter is not loaded from the - * persistent storage. That may occur when a given persistent key is created via - * psa_generate_key() or psa_import_key(), and then the device reboots. - * - * Use psa_open_key() when the key has not been loaded yet to work around the issue. - */ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status = psa_get_key_attributes(aKeyRef, &attributes); - psa_key_id_t key_handle; - - if (status == PSA_ERROR_INVALID_HANDLE) { - psa_open_key(aKeyRef, &key_handle); - } - - psa_reset_key_attributes(&attributes); -} - void otPlatCryptoInit(void) { psa_crypto_init(); @@ -137,26 +120,57 @@ 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"); + __ASSERT_EVAL((void)settings_subsys_init(), int err = settings_subsys_init(), !err, + "Failed to initialize settings"); #endif } -otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, - otCryptoKeyType aKeyType, - otCryptoKeyAlgorithm aKeyAlgorithm, - int aKeyUsage, - otCryptoKeyStorage aKeyPersistence, - const uint8_t *aKey, +otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, otCryptoKeyType aKeyType, + otCryptoKeyAlgorithm aKeyAlgorithm, int aKeyUsage, + otCryptoKeyStorage aKeyPersistence, const uint8_t *aKey, size_t aKeyLen) { +#if defined(CONFIG_OPENTHREAD_ECDSA) + int version; + size_t len; + unsigned char *p = (unsigned char *)aKey; + unsigned char *end; +#endif + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; + psa_status_t status = 0; if (aKeyRef == NULL || aKey == NULL || !checkKeyUsage(aKeyUsage)) { return OT_ERROR_INVALID_ARGS; } +#if defined(CONFIG_OPENTHREAD_ECDSA) + /* Check if key is ECDSA pair and extract private key from it since PSA expects it. */ + if (aKeyType == OT_CRYPTO_KEY_TYPE_ECDSA) { + + end = p + aKeyLen; + status = mbedtls_asn1_get_tag(&p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); + if (status != 0) { + return OT_ERROR_FAILED; + } + + end = p + len; + status = mbedtls_asn1_get_int(&p, end, &version); + if (status != 0) { + return OT_ERROR_FAILED; + } + + status = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING); + if (status != 0 || len != 32) { + return OT_ERROR_FAILED; + } + + aKey = p; + aKeyLen = len; + } +#endif + psa_set_key_type(&attributes, toPsaKeyType(aKeyType)); psa_set_key_algorithm(&attributes, toPsaAlgorithm(aKeyAlgorithm)); psa_set_key_usage_flags(&attributes, toPsaKeyUsage(aKeyUsage)); @@ -177,24 +191,18 @@ otError otPlatCryptoImportKey(otCryptoKeyRef *aKeyRef, return psaToOtError(status); } -otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, - uint8_t *aBuffer, - size_t aBufferLen, +otError otPlatCryptoExportKey(otCryptoKeyRef aKeyRef, uint8_t *aBuffer, size_t aBufferLen, size_t *aKeyLen) { if (aBuffer == NULL) { return OT_ERROR_INVALID_ARGS; } - ensureKeyIsLoaded(aKeyRef); - return psaToOtError(psa_export_key(aKeyRef, aBuffer, aBufferLen, aKeyLen)); } otError otPlatCryptoDestroyKey(otCryptoKeyRef aKeyRef) { - ensureKeyIsLoaded(aKeyRef); - return psaToOtError(psa_destroy_key(aKeyRef)); } @@ -203,7 +211,6 @@ bool otPlatCryptoHasKey(otCryptoKeyRef aKeyRef) psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_status_t status; - ensureKeyIsLoaded(aKeyRef); status = psa_get_key_attributes(aKeyRef, &attributes); psa_reset_key_attributes(&attributes); @@ -246,15 +253,13 @@ otError otPlatCryptoHmacSha256Start(otCryptoContext *aContext, const otCryptoKey return OT_ERROR_INVALID_ARGS; } - ensureKeyIsLoaded(aKey->mKeyRef); operation = aContext->mContext; status = psa_mac_sign_setup(operation, aKey->mKeyRef, PSA_ALG_HMAC(PSA_ALG_SHA_256)); return psaToOtError(status); } -otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, - const void *aBuf, +otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, const void *aBuf, uint16_t aBufLength) { psa_mac_operation_t *operation; @@ -265,7 +270,7 @@ otError otPlatCryptoHmacSha256Update(otCryptoContext *aContext, operation = aContext->mContext; - return psaToOtError(psa_mac_update(operation, (const uint8_t *) aBuf, aBufLength)); + return psaToOtError(psa_mac_update(operation, (const uint8_t *)aBuf, aBufLength)); } otError otPlatCryptoHmacSha256Finish(otCryptoContext *aContext, uint8_t *aBuf, size_t aBufLength) @@ -291,7 +296,7 @@ otError otPlatCryptoAesInit(otCryptoContext *aContext) } key_ref = aContext->mContext; - *key_ref = (psa_key_id_t) 0; /* In TF-M 1.5.0 this can be replaced with PSA_KEY_ID_NULL */ + *key_ref = (psa_key_id_t)0; /* In TF-M 1.5.0 this can be replaced with PSA_KEY_ID_NULL */ return OT_ERROR_NONE; } @@ -314,7 +319,6 @@ otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, { const size_t block_size = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); psa_status_t status = PSA_SUCCESS; - psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; psa_key_id_t *key_ref; size_t cipher_length; @@ -322,37 +326,10 @@ otError otPlatCryptoAesEncrypt(otCryptoContext *aContext, const uint8_t *aInput, return OT_ERROR_INVALID_ARGS; } - /* - * The code below can be simplified after updating TF-M version used in Zephyr to 1.5.0 - * (see upstream commit: 045ec4abfc73152a0116684ba9127d0a97cc8d34), using - * psa_cipher_encrypt() function which will replace the setup-update-finish sequence below. - */ key_ref = aContext->mContext; - ensureKeyIsLoaded(*key_ref); - status = psa_cipher_encrypt_setup(&operation, *key_ref, PSA_ALG_ECB_NO_PADDING); - - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_cipher_update(&operation, - aInput, - block_size, - aOutput, - block_size, - &cipher_length); - - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_cipher_finish(&operation, - aOutput + cipher_length, - block_size - cipher_length, - &cipher_length); + status = psa_cipher_encrypt(*key_ref, PSA_ALG_ECB_NO_PADDING, aInput, block_size, aOutput, + block_size, &cipher_length); -out: - psa_cipher_abort(&operation); return psaToOtError(status); } @@ -411,7 +388,7 @@ otError otPlatCryptoSha256Update(otCryptoContext *aContext, const void *aBuf, ui operation = aContext->mContext; - return psaToOtError(psa_hash_update(operation, (const uint8_t *) aBuf, aBufLength)); + return psaToOtError(psa_hash_update(operation, (const uint8_t *)aBuf, aBufLength)); } otError otPlatCryptoSha256Finish(otCryptoContext *aContext, uint8_t *aHash, uint16_t aHashSize) @@ -475,38 +452,6 @@ otError otPlatCryptoEcdsaGenerateKey(otPlatCryptoEcdsaKeyPair *aKeyPair) return psaToOtError(status); } -otError otPlatCryptoEcdsaGetPublicKey(const otPlatCryptoEcdsaKeyPair *aKeyPair, - otPlatCryptoEcdsaPublicKey *aPublicKey) -{ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_key_id_t key_id = 0; - psa_status_t status; - size_t exported_length; - uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE]; - - psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_bits(&attributes, 256); - - status = psa_import_key(&attributes, aKeyPair->mDerBytes, aKeyPair->mDerLength, &key_id); - if (status != PSA_SUCCESS) { - goto out; - } - - status = psa_export_public_key(key_id, buffer, sizeof(buffer), &exported_length); - if (status != PSA_SUCCESS) { - goto out; - } - __ASSERT_NO_MSG(exported_length == sizeof(buffer)); - memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE); - -out: - psa_reset_key_attributes(&attributes); - psa_destroy_key(key_id); - - return psaToOtError(status); -} - otError otPlatCryptoEcdsaSign(const otPlatCryptoEcdsaKeyPair *aKeyPair, const otPlatCryptoSha256Hash *aHash, otPlatCryptoEcdsaSignature *aSignature) diff --git a/modules/openthread/platform/misc.c b/modules/openthread/platform/misc.c index 7f57dddb9e3..5f9043dfa27 100644 --- a/modules/openthread/platform/misc.c +++ b/modules/openthread/platform/misc.c @@ -9,6 +9,24 @@ #include #include +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + +#include + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + +BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(openthread_config), + "`openthread,config` compatible node not found"); +BUILD_ASSERT(DT_NODE_HAS_PROP(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), bootloader_gpios), + "`bootloader-gpios` property missing from `openthread,config` compatible node"); + +#include + +static const struct gpio_dt_spec bootloader_gpio = + GPIO_DT_SPEC_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(openthread_config), + bootloader_gpios); +#endif + #include "platform-zephyr.h" void otPlatReset(otInstance *aInstance) @@ -19,6 +37,54 @@ void otPlatReset(otInstance *aInstance) sys_reboot(SYS_REBOOT_WARM); } +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) +otError otPlatResetToBootloader(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + +#if defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_RETENTION) + if (bootmode_set(BOOT_MODE_TYPE_BOOTLOADER)) { + return OT_ERROR_NOT_CAPABLE; + } + sys_reboot(SYS_REBOOT_WARM); + +#elif defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO) + /* + * To enable resetting to bootloader by triggering gpio pin, + * select `CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE_GPIO=y`, + * and in Devicetree create `openthread` node in `/options/` path with + * `compatible = "openthread,config"` property and `bootloader-gpios` property, + * which should represent GPIO pin's configuration, + * containing controller phandle, pin number and pin flags. e.g: + * + * options { + * openthread { + * compatible = "openthread,config"; + * bootloader-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + * }; + * }; + * + * Note: in below implementation, chosen GPIO pin is configured as output + * and initialized to active state (logical value ‘1’). + * Configuring pin flags in `bootloader-gpios` allows to choose + * if pin should be active in high or in low state. + */ + + if (!gpio_is_ready_dt(&bootloader_gpio)) { + return OT_ERROR_NOT_CAPABLE; + } + gpio_pin_configure_dt(&bootloader_gpio, GPIO_OUTPUT_ACTIVE); + +#endif + + /* + * Return OT_ERROR_NOT_CAPABLE if resetting has been unsuccessful (invalid configuration or + * triggering reset had no effect) + */ + return OT_ERROR_NOT_CAPABLE; +} +#endif /* defined(CONFIG_OPENTHREAD_PLATFORM_BOOTLOADER_MODE) */ + otPlatResetReason otPlatGetResetReason(otInstance *aInstance) { ARG_UNUSED(aInstance); @@ -33,5 +99,10 @@ void otPlatWakeHost(void) void otPlatAssertFail(const char *aFilename, int aLineNumber) { - __ASSERT(false, "OpenThread ASSERT @ %s:%d", aFilename, aLineNumber); + /* + * The code below is used instead of __ASSERT(false) to print the actual assert + * location instead of __FILE__:__LINE__, which would point to this function. + */ + __ASSERT_PRINT("OpenThread ASSERT @ %s:%d\n", aFilename, aLineNumber); + __ASSERT_POST_ACTION(); } diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 881585e5578..71a087ca0b5 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -396,16 +396,6 @@ #define OPENTHREAD_CONFIG_CRYPTO_LIB OPENTHREAD_CONFIG_CRYPTO_LIB_PSA #endif -/** - * @def OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE - * - * Set to 1 if you want to enable key reference usage support. - * - */ -#ifdef CONFIG_OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE -#define OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE 1 -#endif - /** * @def OPENTHREAD_CONFIG_PLATFORM_MAC_KEYS_EXPORTABLE_ENABLE * @@ -448,17 +438,6 @@ #define OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE 0 #endif -/** - * @def OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE - * - * In Zephyr, power calibration is handled by Radio Driver, so it can't be handled on OT level. - * - */ -#ifndef OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE -#define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE 0 -#endif - - /** * @def OPENTHREAD_CONFIG_RADIO_STATS * diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 98eab182aad..d405539bcc0 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -380,13 +380,8 @@ void transmit_message(struct k_work *tx_job) channel = sTransmitFrame.mChannel; - radio_api->set_channel(radio_dev, sTransmitFrame.mChannel); - -#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER) - net_pkt_set_ieee802154_txpwr(tx_pkt, get_transmit_power_for_channel(channel)); -#else + radio_api->set_channel(radio_dev, channel); radio_api->set_txpower(radio_dev, get_transmit_power_for_channel(channel)); -#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */ net_pkt_set_ieee802154_frame_secured(tx_pkt, sTransmitFrame.mInfo.mTxInfo.mIsSecurityProcessed); @@ -1188,20 +1183,14 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe struct ieee802154_key keys[] = { { .key_id_mode = key_id_mode, - .key_index = aKeyId == 1 ? 0x80 : aKeyId - 1, - .key_value = (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { .key_id_mode = key_id_mode, - .key_index = aKeyId, - .key_value = (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { .key_id_mode = key_id_mode, - .key_index = aKeyId == 0x80 ? 1 : aKeyId + 1, - .key_value = (uint8_t *)aNextKey->mKeyMaterial.mKey.m8, .frame_counter_per_key = false, }, { @@ -1215,9 +1204,24 @@ void otPlatRadioSetMacKey(otInstance *aInstance, uint8_t aKeyIdMode, uint8_t aKe }, }; - /* aKeyId in range: (1, 0x80) means valid keys - * aKeyId == 0 is used only to clear keys for stack reset in RCP - */ + if (key_id_mode == 1) { + /* aKeyId in range: (1, 0x80) means valid keys */ + uint8_t prev_key_id = aKeyId == 1 ? 0x80 : aKeyId - 1; + uint8_t next_key_id = aKeyId == 0x80 ? 1 : aKeyId + 1; + + keys[0].key_id = &prev_key_id; + keys[0].key_value = (uint8_t *)aPrevKey->mKeyMaterial.mKey.m8; + + keys[1].key_id = &aKeyId; + keys[1].key_value = (uint8_t *)aCurrKey->mKeyMaterial.mKey.m8; + + keys[2].key_id = &next_key_id; + keys[2].key_value = (uint8_t *)aNextKey->mKeyMaterial.mKey.m8; + } else { + /* aKeyId == 0 is used only to clear keys for stack reset in RCP */ + __ASSERT_NO_MSG((key_id_mode == 0) && (aKeyId == 0)); + } + struct ieee802154_config config = { .mac_keys = aKeyId == 0 ? clear_keys : keys, }; @@ -1251,10 +1255,7 @@ 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, - }; + struct ieee802154_config config = { 0 }; int result; ARG_UNUSED(aInstance); @@ -1267,6 +1268,8 @@ otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShort if (result) { return OT_ERROR_FAILED; } + config.ack_ie.short_addr = aShortAddr; + config.ack_ie.ext_addr = aExtAddr != NULL ? aExtAddr->m8 : NULL; /* Configure the CSL IE. */ if (aCslPeriod > 0) { @@ -1291,6 +1294,22 @@ otError otPlatRadioEnableCsl(otInstance *aInstance, uint32_t aCslPeriod, otShort return result ? OT_ERROR_FAILED : OT_ERROR_NONE; } +otError otPlatRadioResetCsl(otInstance *aInstance) +{ + struct ieee802154_config config = { 0 }; + int result; + + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_CSL_PERIOD, &config); + if (result) { + return OT_ERROR_FAILED; + } + + config.ack_ie.purge_ie = true; + result = radio_api->configure(radio_dev, IEEE802154_CONFIG_ENH_ACK_HEADER_IE, &config); + + return result ? OT_ERROR_FAILED : OT_ERROR_NONE; +} + void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTime) { ARG_UNUSED(aInstance); @@ -1344,7 +1363,7 @@ uint8_t otPlatRadioGetCslUncertainty(otInstance *aInstance) * | IE_VENDOR_THREAD_ACK_PROBING_ID | LINK_METRIC_TOKEN | LINK_METRIC_TOKEN| * |---------------------------------|-------------------|------------------| */ -static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header) +static void set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, uint8_t *ie_header) { /* Vendor-specific IE identifier */ const uint8_t ie_vendor_id = 0x00; @@ -1358,7 +1377,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui const uint8_t ie_vendor_thread_margin_token = 0x02; /* Thread Vendor-specific ACK Probing IE LQI value placeholder */ const uint8_t ie_vendor_thread_lqi_token = 0x03; - const uint8_t ie_header_size = 2; const uint8_t oui_size = 3; const uint8_t sub_type = 1; const uint8_t id_offset = 7; @@ -1376,7 +1394,8 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui __ASSERT(ie_header, "Invalid argument"); if (link_metrics_data_len == 0) { - return 0; + ie_header[0] = 0; + return; } /* Set Element ID */ @@ -1411,8 +1430,6 @@ static uint8_t set_vendor_ie_header_lm(bool lqi, bool link_margin, bool rssi, ui if (rssi) { ie_header[link_metrics_idx++] = ie_vendor_thread_rssi_token; } - - return ie_header_size + content_len; } otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics aLinkMetrics, @@ -1424,13 +1441,12 @@ otError otPlatRadioConfigureEnhAckProbing(otInstance *aInstance, otLinkMetrics a .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); - header_ie_len = set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, - aLinkMetrics.mRssi, header_ie_buf); + set_vendor_ie_header_lm(aLinkMetrics.mLqi, aLinkMetrics.mLinkMargin, + aLinkMetrics.mRssi, 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); diff --git a/modules/trusted-firmware-m/CMakeLists.txt b/modules/trusted-firmware-m/CMakeLists.txt index 177a47e28d6..2bba4a45c6d 100644 --- a/modules/trusted-firmware-m/CMakeLists.txt +++ b/modules/trusted-firmware-m/CMakeLists.txt @@ -40,9 +40,11 @@ if (CONFIG_BUILD_WITH_TFM) endif() if (CONFIG_TFM_REGRESSION_S) list(APPEND TFM_CMAKE_ARGS -DTEST_S=ON) + list(APPEND TFM_CMAKE_ARGS -DTFM_S_REG_TEST:BOOL=ON) endif() if (CONFIG_TFM_REGRESSION_NS) list(APPEND TFM_CMAKE_ARGS -DTEST_NS=ON) + list(APPEND TFM_CMAKE_ARGS -DTFM_NS_REG_TEST:BOOL=ON) endif() if (CONFIG_TFM_BL2) list(APPEND TFM_CMAKE_ARGS -DBL2=TRUE) @@ -51,11 +53,6 @@ if (CONFIG_BUILD_WITH_TFM) else() list(APPEND TFM_CMAKE_ARGS -DBL2=FALSE) endif() - if (CONFIG_TFM_BUILD_NS) - list(APPEND TFM_CMAKE_ARGS -DNS=TRUE) - else() - list(APPEND TFM_CMAKE_ARGS -DNS=FALSE) - endif() if (CONFIG_TFM_ISOLATION_LEVEL) list(APPEND TFM_CMAKE_ARGS -DTFM_ISOLATION_LEVEL=${CONFIG_TFM_ISOLATION_LEVEL}) endif() @@ -68,20 +65,6 @@ if (CONFIG_BUILD_WITH_TFM) if (CONFIG_TFM_PROFILE) list(APPEND TFM_CMAKE_ARGS -DTFM_PROFILE=${CONFIG_TFM_PROFILE}) endif() - if (CONFIG_TFM_PSA_TEST_CRYPTO) - set(TFM_PSA_TEST_SUITE CRYPTO) - elseif (CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE) - set(TFM_PSA_TEST_SUITE PROTECTED_STORAGE) - elseif (CONFIG_TFM_PSA_TEST_INTERNAL_TRUSTED_STORAGE) - set(TFM_PSA_TEST_SUITE INTERNAL_TRUSTED_STORAGE) - elseif (CONFIG_TFM_PSA_TEST_STORAGE) - set(TFM_PSA_TEST_SUITE STORAGE) - elseif (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION) - set(TFM_PSA_TEST_SUITE INITIAL_ATTESTATION) - endif() - if (DEFINED TFM_PSA_TEST_SUITE) - list(APPEND TFM_CMAKE_ARGS -DTEST_PSA_API=${TFM_PSA_TEST_SUITE}) - endif() if (CONFIG_TFM_CMAKE_BUILD_TYPE_RELEASE) set(TFM_CMAKE_BUILD_TYPE "Release") elseif (CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL) @@ -95,6 +78,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() @@ -163,34 +152,17 @@ if (CONFIG_BUILD_WITH_TFM) foreach(module ${TFM_CRYPTO_MODULES}) if (CONFIG_TFM_${module}_ENABLED) # list(APPEND TFM_ENABLED_CRYPTO_MODULES_ARG ${module}) - set(val "FALSE") - else() - set(val "TRUE") + list(APPEND TFM_CMAKE_ARGS -D${module}_ENABLED=True) endif() - list(APPEND TFM_CMAKE_ARGS -D${module}_DISABLED=${val}) endforeach() set(TFM_BINARY_DIR ${CMAKE_BINARY_DIR}/tfm) - set(TFM_TEST_REPO_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/../tf-m-tests) set(PSA_ARCH_TESTS_PATH ${ZEPHYR_CURRENT_MODULE_DIR}/../psa-arch-tests) - set(VENEERS_FILE ${TFM_BINARY_DIR}/secure_fw/s_veneers.o) - set(TFM_API_NS_PATH ${TFM_BINARY_DIR}/tf-m-tests/app/libtfm_api_ns.a) - set(PLATFORM_NS_FILE ${TFM_BINARY_DIR}/platform/ns/libplatform_ns.a) - set(TFM_GENERATED_INCLUDES ${TFM_BINARY_DIR}/generated/interface/include) - set(TFM_INTERFACE_SOURCE_DIR ${TFM_BINARY_DIR}/install/interface/src) - - if (TFM_PSA_TEST_SUITE) - set(PSA_TEST_VAL_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/val/val_nspe.a) - set(PSA_TEST_PAL_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/platform/pal_nspe.a) - set(COMBINE_DIR_STORAGE storage) - set(COMBINE_DIR_PROTECTED_STORAGE storage) - set(COMBINE_DIR_INTERNAL_TRUSTED_STORAGE storage) - set(COMBINE_DIR_CRYPTO crypto) - set(COMBINE_DIR_INITIAL_ATTESTATION initial_attestation) - set(PSA_TEST_COMBINE_FILE ${TFM_BINARY_DIR}/tf-m-tests/app/psa_api_tests/dev_apis/${COMBINE_DIR_${TFM_PSA_TEST_SUITE}}/test_combine.a) - endif() + set(TFM_INTERFACE_SOURCE_DIR ${TFM_BINARY_DIR}/api_ns/interface/src) + set(TFM_INTERFACE_INCLUDE_DIR ${TFM_BINARY_DIR}/api_ns/interface/include) + set(TFM_INTERFACE_LIB_DIR ${TFM_BINARY_DIR}/api_ns/interface/lib) if(CONFIG_TFM_BL2) set(BL2_ELF_FILE ${TFM_BINARY_DIR}/bin/bl2.elf) @@ -201,38 +173,33 @@ if (CONFIG_BUILD_WITH_TFM) set(TFM_S_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s.bin) set(TFM_S_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_s.hex) set(TFM_NS_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.bin) - set(TFM_NS_HEX_FILE ${TFM_BINARY_DIR}/bin/tfm_ns.hex) + set(TFM_NS_HEX_FILE ${CMAKE_BINARY_DIR}/tfm_ns/bin/tfm_ns.hex) set(TFM_S_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_signed.bin) set(TFM_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_ns_signed.bin) set(TFM_S_NS_SIGNED_BIN_FILE ${TFM_BINARY_DIR}/bin/tfm_s_ns_signed.bin) set(BUILD_BYPRODUCTS - ${VENEERS_FILE} - ${TFM_API_NS_PATH} - ${TFM_GENERATED_INCLUDES}/psa_manifest/sid.h ${PSA_TEST_VAL_FILE} ${PSA_TEST_PAL_FILE} ${PSA_TEST_COMBINE_FILE} - ${PLATFORM_NS_FILE} ${BL2_ELF_FILE} ${BL2_BIN_FILE} ${BL2_HEX_FILE} ${TFM_S_ELF_FILE} ${TFM_S_BIN_FILE} ${TFM_S_HEX_FILE} - ${TFM_NS_BIN_FILE} - ${TFM_NS_HEX_FILE} ${TFM_S_SIGNED_BIN_FILE} - ${TFM_NS_SIGNED_BIN_FILE} ${TFM_S_NS_SIGNED_BIN_FILE} + ${TFM_INTERFACE_LIB_DIR}/s_veneers.o + ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c - ${TFM_INTERFACE_SOURCE_DIR}/tfm_psa_ns_api.c + ${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c # Specific to nordic_nrf platform ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c @@ -257,33 +224,7 @@ if (CONFIG_BUILD_WITH_TFM) message(FATAL_ERROR "Unsupported ZEPHYR_TOOLCHAIN_VARIANT: ${ZEPHYR_TOOLCHAIN_VARIANT}") endif() - if (CONFIG_TFM_PARTITION_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") - # TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, - # or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has - # been manually downloaded by the user before starting the build. - message(FATAL_ERROR "CONFIG_TFM_PARTITION_INITIAL_ATTESTATION is not available " - "with TF-M 1.7.0 due to licensing issues with a dependent library. This " - "restriction will be removed once licensing issues have been resolved." - ) - endif() - - if (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") - # TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, - # or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has - # been manually downloaded by the user before starting the build. - message(FATAL_ERROR "CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION is not available " - "with TF-M 1.7.0 due to licensing issues with a dependent library. This " - "restriction will be removed once licensing issues have been resolved." - ) - endif() - - if (CONFIG_TFM_QCBOR_PATH STREQUAL "DOWNLOAD") - # Change CMake cache type to string to avoid QCBOR_PATH=/absolute/path/DOWNLOAD being set. - set(QCBOR_PATH_TYPE ":STRING") - endif() - # Always set QCBOR_PATH, this will make sure that we don't automatically download this - # dependency in the TF-M build system and it will fail when set to an invalid value. - list(APPEND TFM_CMAKE_ARGS -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH}) + string(REPLACE "toolchain" "toolchain_ns" TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_FILE}) if(CONFIG_BOARD_LPCXPRESSO55S69_CPU0) # Supply path to NXP HAL sources used for TF-M build @@ -300,13 +241,6 @@ if (CONFIG_BUILD_WITH_TFM) list(APPEND TFM_CMAKE_ARGS -DMCUBOOT_DATA_SHARING=ON) endif() - if(TFM_PSA_TEST_SUITE) - list(APPEND TFM_CMAKE_ARGS - -DPSA_TOOLCHAIN_FILE=${CMAKE_CURRENT_LIST_DIR}/psa/GNUARM.cmake - -DTOOLCHAIN=INHERIT - ) - endif() - if(CONFIG_FPU AND CONFIG_FP_HARDABI) list(APPEND TFM_CMAKE_ARGS -DCONFIG_TFM_ENABLE_FP=ON) # Note: This is not a cmake option in TF-M. @@ -334,7 +268,6 @@ if (CONFIG_BUILD_WITH_TFM) ${TFM_CMAKE_ARGS} $> -DMBEDCRYPTO_PATH=$>,$,${ZEPHYR_MBEDTLS_MODULE_DIR}> - -DTFM_TEST_REPO_PATH=${TFM_TEST_REPO_PATH} -DPSA_ARCH_TESTS_PATH=${PSA_ARCH_TESTS_PATH} ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR} WORKING_DIRECTORY ${TFM_BINARY_DIR} @@ -373,6 +306,11 @@ if (CONFIG_BUILD_WITH_TFM) # This is the root of all TFM build artifacts. set_target_properties(tfm PROPERTIES TFM_BINARY_DIR ${TFM_BINARY_DIR}) + # Set TFM toolchain properties on 'tfm' + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_NS_FILE ${TFM_TOOLCHAIN_NS_FILE}) + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PREFIX ${TFM_TOOLCHAIN_PREFIX}) + set_target_properties(tfm PROPERTIES TFM_TOOLCHAIN_PATH ${TFM_TOOLCHAIN_PATH}) + # Set BL2 (MCUboot) executable file paths as target properties on 'tfm' # These files are produced by the TFM build system. if(CONFIG_TFM_BL2) @@ -409,48 +347,27 @@ if (CONFIG_BUILD_WITH_TFM) if (CONFIG_TFM_PARTITION_PLATFORM AND NOT CONFIG_TFM_PARTITION_PLATFORM_CUSTOM_REBOOT) zephyr_library_sources(src/reboot.c) endif() - zephyr_library_sources_ifndef(CONFIG_TFM_PSA_TEST_NONE src/zephyr_tfm_psa_test.c) - if (TFM_PSA_TEST_SUITE) - zephyr_library_link_libraries( - ${PSA_TEST_VAL_FILE} - ${PSA_TEST_PAL_FILE} - ${PSA_TEST_COMBINE_FILE} - ) - endif() - - if(NOT CONFIG_TFM_BUILD_NS) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PROTECTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_CRYPTO ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INITIAL_ATTESTATION ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_FIRMWARE_UPDATE ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_platform_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PROTECTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_ps_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE ${TFM_INTERFACE_SOURCE_DIR}/tfm_its_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_CRYPTO ${TFM_INTERFACE_SOURCE_DIR}/tfm_crypto_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_INITIAL_ATTESTATION ${TFM_INTERFACE_SOURCE_DIR}/tfm_attest_api.c) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_FIRMWARE_UPDATE ${TFM_INTERFACE_SOURCE_DIR}/tfm_fwu_api.c) - zephyr_library_sources(${TFM_INTERFACE_SOURCE_DIR}/tfm_psa_ns_api.c) - - if(CONFIG_SOC_FAMILY_NRF) - zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c) - endif() + zephyr_library_sources(${TFM_INTERFACE_SOURCE_DIR}/tfm_tz_psa_ns_api.c) - else() - zephyr_library_link_libraries( - ${PLATFORM_NS_FILE} - ${TFM_API_NS_PATH} - ) + if(CONFIG_SOC_FAMILY_NRF) + zephyr_library_sources_ifdef(CONFIG_TFM_PARTITION_PLATFORM ${TFM_INTERFACE_SOURCE_DIR}/tfm_ioctl_core_ns_api.c) endif() - zephyr_include_directories( - ${TFM_GENERATED_INCLUDES} - ) - target_include_directories(tfm_api PRIVATE - ${TFM_BINARY_DIR}/install/interface/include - ${TFM_BINARY_DIR}/install/interface/include/crypto_keys + ${TFM_INTERFACE_INCLUDE_DIR} + ${TFM_INTERFACE_INCLUDE_DIR}/crypto_keys ) zephyr_library_link_libraries( - ${VENEERS_FILE} + ${TFM_INTERFACE_LIB_DIR}/s_veneers.o ) # To ensure that generated include files are created before they are used. @@ -579,4 +496,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..f8285da53d6 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -177,6 +177,25 @@ 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" + select TFM_INITIAL_ATTESTATION_KEY + 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_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 @@ -207,19 +226,8 @@ config TFM_BL2 TFM is designed to run with MCUboot in a certain configuration. This config adds MCUboot to the build - built via TFM's build system. -config TFM_BUILD_NS - bool "Build the TF-M Non-Secure application and libraries" - help - Instruct the TF-M build system to build the TF-M Non-Secure - application and libraries. - - This option is intended for testing purposes only, since this is the - easiest way to build the TF-M regression tests application and test - support libraries in the zephyr build system. - config TFM_USE_NS_APP bool "Use the TF-M Non-Secure application" - depends on TFM_BUILD_NS help The TF-M build system can produce multiple executable files. The main one is the TF-M secure firmware. Optionally the TF-M diff --git a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules index 1d70a2c44d2..02d3580c22f 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules +++ b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules @@ -10,6 +10,7 @@ if TFM_PARTITION_CRYPTO config TFM_CRYPTO_RNG_MODULE_ENABLED bool "Random number generator crypto module" default y + depends on PSA_WANT_GENERATE_RANDOM && NRF_SECURITY help Enables the random number generator module within the crypto partition. Unset this option if 'psa_generate_random' is not used. @@ -17,6 +18,7 @@ config TFM_CRYPTO_RNG_MODULE_ENABLED config TFM_CRYPTO_KEY_MODULE_ENABLED bool "KEY crypto module" default y + depends on PSA_HAS_KEY_SUPPORT && NRF_SECURITY help Enables the KEY crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key_management.c' @@ -25,6 +27,7 @@ config TFM_CRYPTO_KEY_MODULE_ENABLED config TFM_CRYPTO_AEAD_MODULE_ENABLED bool "AEAD crypto module" default y + depends on PSA_HAS_AEAD_SUPPORT && NRF_SECURITY help Enables the AEAD crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_aead.c' @@ -33,6 +36,7 @@ config TFM_CRYPTO_AEAD_MODULE_ENABLED config TFM_CRYPTO_MAC_MODULE_ENABLED bool "MAC crypto module" default y + depends on PSA_HAS_MAC_SUPPORT && NRF_SECURITY help Enables the MAC crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_mac.c' @@ -41,6 +45,7 @@ config TFM_CRYPTO_MAC_MODULE_ENABLED config TFM_CRYPTO_HASH_MODULE_ENABLED bool "HASH crypto module" default y + depends on PSA_HAS_HASH_SUPPORT && NRF_SECURITY help Enables the HASH crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_hash.c' @@ -49,6 +54,7 @@ config TFM_CRYPTO_HASH_MODULE_ENABLED config TFM_CRYPTO_CIPHER_MODULE_ENABLED bool "CIPHER crypto module" default y + depends on PSA_HAS_CIPHER_SUPPORT && NRF_SECURITY help Enables the CIPHER crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_cipher.c' @@ -57,6 +63,7 @@ config TFM_CRYPTO_CIPHER_MODULE_ENABLED config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED bool "ASYM ENCRYPT crypto module" default y + depends on PSA_HAS_ASYM_ENCRYPT_SUPPORT && NRF_SECURITY help Enables the ASYM ENCRYPT crypto module within the crypto partition. Unset this option if the encrypt functionality provided by 'crypto_asymmetric.c' @@ -65,6 +72,7 @@ config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED bool "ASYM SIGN crypto module" default y + depends on PSA_HAS_ASYM_SIGN_SUPPORT && NRF_SECURITY help Enables the ASYM SIGN crypto module within the crypto partition. Unset this option if the sign functionality provided by 'crypto_asymmetric.c' @@ -73,10 +81,12 @@ config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED config TFM_CRYPTO_KEY_DERIVATION_MODULE_ENABLED bool "KEY DERIVATION crypto module" default y + depends on (PSA_HAS_KEY_DERIVATION || PSA_HAS_KEY_AGREEMENT) && NRF_SECURITY help Enables the KEY_DERIVATION crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key_derivation.c' is not used. + Note that key agreement is under key derivation in the current implementation. endif # TFM_PARTITION_CRYPTO 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' diff --git a/modules/trusted-firmware-m/interface/interface.c b/modules/trusted-firmware-m/interface/interface.c index ad0ed1abdfe..d949a9dc027 100644 --- a/modules/trusted-firmware-m/interface/interface.c +++ b/modules/trusted-firmware-m/interface/interface.c @@ -35,7 +35,7 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn, if (!is_pre_kernel) { /* TF-M request protected by NS lock */ if (k_mutex_lock(&tfm_mutex, K_FOREVER) != 0) { - return (int32_t)TFM_ERROR_GENERIC; + return (int32_t)PSA_ERROR_GENERIC_ERROR; } #if !defined(CONFIG_ARM_NONSECURE_PREEMPTIBLE_SECURE_CALLS) @@ -79,7 +79,7 @@ uint32_t tfm_ns_interface_init(void) * The static K_MUTEX_DEFINE handles mutex initialization, * so this function may be implemented as no-op. */ - return TFM_SUCCESS; + return PSA_SUCCESS; } @@ -90,7 +90,7 @@ uint32_t tfm_ns_interface_init(void) static int ns_interface_init(void) { - __ASSERT(tfm_ns_interface_init() == TFM_SUCCESS, + __ASSERT(tfm_ns_interface_init() == PSA_SUCCESS, "TF-M NS interface init failed"); return 0; diff --git a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt index 41dca2f15a9..d75b34a8109 100644 --- a/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/CMakeLists.txt @@ -36,14 +36,6 @@ target_include_directories(platform_s ${board_includes} ) -target_include_directories(platform_ns - PUBLIC - include - include/util - ${partition_includes} - ${board_includes} -) - if(BL2) target_include_directories(platform_bl2 PUBLIC @@ -54,14 +46,18 @@ if(BL2) ) 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 ) + +if (TFM_PARTITION_PLATFORM) +install(FILES include/tfm_ioctl_api.h + include/device_cfg.h + include/RTE_Device.h + include/tfm_ioctl_api.h + DESTINATION ${INSTALL_INTERFACE_INC_DIR}) +endif() + +install(FILES ns/CMakeLists.txt + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) 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 index c6c36ee927f..3fade10525a 100644 --- a/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h +++ b/modules/trusted-firmware-m/nordic_nrf/include/tfm_ioctl_api.h @@ -9,7 +9,6 @@ #include #include -#include #include /* Include core IOCTL services */ diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt index 279ea385996..b74620fe2d5 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/CMakeLists.txt @@ -5,8 +5,19 @@ # 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) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf5340dk_nrf5340_cpuapp/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR} +) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake index b3e5d74181c..ae50a4846dd 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf5340 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf5340/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake new file mode 100644 index 00000000000..f19d7f43c67 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/cpuarch.cmake @@ -0,0 +1,9 @@ +# +# 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/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake new file mode 100644 index 00000000000..077e88bd37b --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf5340_cpuapp/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf5340/cpuarch.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 index a84c6fd9fd5..64fff7cdb86 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/CMakeLists.txt @@ -5,8 +5,21 @@ # 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) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf9120/cpuarch.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf9120) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf9161dk_nrf9161/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake index 3f58e7b89eb..e858eda3a27 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf91 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.cmake new file mode 100644 index 00000000000..9f0886c7a51 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/cpuarch.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/nrf9120/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake new file mode 100644 index 00000000000..c53d684d7e8 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9120/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf9120/cpuarch.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 index a84c6fd9fd5..aa2ef831031 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/CMakeLists.txt @@ -5,8 +5,21 @@ # 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) + +install(FILES ${CMAKE_CURRENT_LIST_DIR}/ns/cpuarch_ns.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR} + RENAME cpuarch.cmake) + +install(FILES ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/common/nrf9160/cpuarch.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}/common/nrf9160) + +install(FILES config.cmake + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) + +install(DIRECTORY ${Trusted\ Firmware\ M_SOURCE_DIR}/platform/ext/target/nordic_nrf/nrf9160dk_nrf9160/tests + + DESTINATION ${INSTALL_PLATFORM_NS_DIR}) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake index 3f58e7b89eb..e858eda3a27 100644 --- a/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/config.cmake @@ -4,5 +4,6 @@ # SPDX-License-Identifier: Apache-2.0 # -set(PLATFORM_PATH platform/ext/target/nordic_nrf/) +set(NRF_SOC_VARIANT nrf91 CACHE STRING "nRF SoC Variant") + include(${PLATFORM_PATH}/common/nrf91/config.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake new file mode 100644 index 00000000000..f728014d3f7 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/cpuarch.cmake @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_PATH platform/ext/target/nordic_nrf) + +include(${PLATFORM_PATH}/common/nrf9160/cpuarch.cmake) diff --git a/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake b/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake new file mode 100644 index 00000000000..902e7fe7ef4 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/nrf9160/ns/cpuarch_ns.cmake @@ -0,0 +1,10 @@ +# +# Copyright (c) 2023, Nordic Semiconductor ASA. +# +# SPDX-License-Identifier: Apache-2.0 +# + +set(PLATFORM_DIR ${CMAKE_CURRENT_LIST_DIR}) +set(PLATFORM_PATH ${CMAKE_CURRENT_LIST_DIR}) + +include(${CMAKE_CURRENT_LIST_DIR}/common/nrf9160/cpuarch.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/ns/CMakeLists.txt b/modules/trusted-firmware-m/nordic_nrf/ns/CMakeLists.txt new file mode 100644 index 00000000000..5bb8cb5bd94 --- /dev/null +++ b/modules/trusted-firmware-m/nordic_nrf/ns/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# 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(NRF_BOARD_SELECTED True) + +add_library(platform_ns STATIC) + +set(partition_includes + ${CMAKE_CURRENT_LIST_DIR}/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_include_directories(platform_ns + PUBLIC + ${partition_includes} + ${board_includes} +) + +# Get the value of HAL_NORDIC_PATH +include(${CMAKE_CURRENT_LIST_DIR}/common/core/config_nordic_nrf_spe.cmake) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common/${NRF_SOC_VARIANT} ${NRF_SOC_VARIANT}) + +target_include_directories(platform_ns + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) + +target_link_libraries(platform_ns + PUBLIC + platform_region_defs +) diff --git a/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c b/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c deleted file mode 100644 index d7d68f9db67..00000000000 --- a/modules/trusted-firmware-m/src/zephyr_tfm_psa_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/** - * \brief This symbol is the entry point provided by the PSA API compliance - * test libraries - */ -extern void val_entry(void); - - -void psa_test(void) -{ - val_entry(); -} diff --git a/modules/uoscore-uedhoc/CMakeLists.txt b/modules/uoscore-uedhoc/CMakeLists.txt index e23ad7da2e6..aaf842e392c 100644 --- a/modules/uoscore-uedhoc/CMakeLists.txt +++ b/modules/uoscore-uedhoc/CMakeLists.txt @@ -29,7 +29,7 @@ if (CONFIG_UOSCORE OR CONFIG_UEDHOC) if (CONFIG_BUILD_WITH_TFM) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/modules/zcbor/Kconfig b/modules/zcbor/Kconfig index 1b3fd15d5e3..655fb2ed2a8 100644 --- a/modules/zcbor/Kconfig +++ b/modules/zcbor/Kconfig @@ -33,4 +33,11 @@ config ZCBOR_ASSERT config ZCBOR_BIG_ENDIAN def_bool BIG_ENDIAN +config ZCBOR_MAX_STR_LEN + int "Default max length when calling zcbor_tstr_put_term()" + default 256 + help + This can be manually used if no other value is readily available, but + using this is discouraged. + endif # ZCBOR 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..2523aac8ea7 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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) 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/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..2523aac8ea7 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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) 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/central/src/main.c b/samples/bluetooth/central/src/main.c index 0c88f647539..e6305ea70b6 100644 --- a/samples/bluetooth/central/src/main.c +++ b/samples/bluetooth/central/src/main.c @@ -43,7 +43,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c index 385877ec280..fada73d9d94 100644 --- a/samples/bluetooth/central_gatt_write/src/central_gatt_write.c +++ b/samples/bluetooth/central_gatt_write/src/central_gatt_write.c @@ -35,7 +35,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, } /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/central_iso/README.rst b/samples/bluetooth/central_iso/README.rst index 4965ea96b3b..13e6f56d778 100644 --- a/samples/bluetooth/central_iso/README.rst +++ b/samples/bluetooth/central_iso/README.rst @@ -6,12 +6,12 @@ Bluetooth: Central ISO Overview ******** -Application demonstrating a connected isochronous channel functional as the -central role, by scanning for peripheral devices and establishing a connection -to the first one with a strong enough signal. -The application then attempts to setup a connected isochronous channel and -starts sending data. +This sample demonstrates how to use an isochronous channel as a central. +The sample scans for a peripheral, establishes a connection, and sets up a connected isochronous channel to it. +Once the isochronous channel is connected, isochronous data is transferred to the peer device every 10 milliseconds. +It is recommended to run this sample together with the :ref:`Bluetooth: Peripheral ISO ` sample. +To run the sample with an encrypted isochronous channel, enable :kconfig:option:`CONFIG_BT_SMP`. Requirements ************ @@ -19,11 +19,28 @@ Requirements * BlueZ running on the host, or * A board with Bluetooth Low Energy 5.2 support * A Bluetooth Controller and board that supports setting - CONFIG_BT_CTLR_CENTRAL_ISO=y + :kconfig:option:`CONFIG_BT_CTLR_CENTRAL_ISO`. Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/central_iso` in the Zephyr tree. -See :ref:`bluetooth samples section ` for details. +1. Start the application. + In the terminal window, check that it is scanning for other devices. + + Bluetooth initialized + Scanning successfully started + Device found: D3:3A:5D:F5:73:33 (random) (RSSI -78) + Device found: 70:7B:F4:2B:76:AD (random) (RSSI -68) + Device found: 65:CF:20:0D:CB:9D (random) (RSSI -82) + +2. Observe that the device connects. + + Connected: 65:CF:20:0D:CB:9D (random) + +3. Observe that the ISO channel is connected + + ISO Channel 0x200048f8 connected + +See :ref:`bluetooth samples section ` for more details. diff --git a/samples/bluetooth/central_iso/prj.conf b/samples/bluetooth/central_iso/prj.conf index ab5a202401f..81264161a5c 100644 --- a/samples/bluetooth/central_iso/prj.conf +++ b/samples/bluetooth/central_iso/prj.conf @@ -1,11 +1,3 @@ CONFIG_BT=y CONFIG_LOG=y CONFIG_BT_ISO_CENTRAL=y -CONFIG_BT_SMP=y - -CONFIG_BT_KEYS_OVERWRITE_OLDEST=y -CONFIG_BT_SETTINGS=y -CONFIG_FLASH=y -CONFIG_FLASH_MAP=y -CONFIG_NVS=y -CONFIG_SETTINGS=y diff --git a/samples/bluetooth/central_iso/src/main.c b/samples/bluetooth/central_iso/src/main.c index a0062fcfa73..20c848cb121 100644 --- a/samples/bluetooth/central_iso/src/main.c +++ b/samples/bluetooth/central_iso/src/main.c @@ -99,7 +99,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/central_multilink/src/central_multilink.c b/samples/bluetooth/central_multilink/src/central_multilink.c index ea9afbb977c..197021efe97 100644 --- a/samples/bluetooth/central_multilink/src/central_multilink.c +++ b/samples/bluetooth/central_multilink/src/central_multilink.c @@ -70,7 +70,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf new file mode 100644 index 00000000000..e6749ae6399 --- /dev/null +++ b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf b/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf new file mode 100644 index 00000000000..e6749ae6399 --- /dev/null +++ b/samples/bluetooth/hci_pwr_ctrl/sysbuild/hci_rpmsg.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/samples/bluetooth/mesh/CMakeLists.txt b/samples/bluetooth/mesh/CMakeLists.txt index 6ee28b12d48..74734eb84b4 100644 --- a/samples/bluetooth/mesh/CMakeLists.txt +++ b/samples/bluetooth/mesh/CMakeLists.txt @@ -16,6 +16,6 @@ endif() if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh/README.rst b/samples/bluetooth/mesh/README.rst index e6ee78ba3a7..58532a0600b 100644 --- a/samples/bluetooth/mesh/README.rst +++ b/samples/bluetooth/mesh/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Overview ******** -This sample demonstrates Bluetooth mesh functionality. It has several +This sample demonstrates Bluetooth Mesh functionality. It has several standard mesh models, and supports provisioning over both the Advertising and the GATT Provisioning Bearers (i.e. PB-ADV and PB-GATT). The application also needs a functioning serial console, since that's diff --git a/samples/bluetooth/mesh/boards/bbc_microbit.conf b/samples/bluetooth/mesh/boards/bbc_microbit.conf index 26fb05301c1..1655768864b 100644 --- a/samples/bluetooth/mesh/boards/bbc_microbit.conf +++ b/samples/bluetooth/mesh/boards/bbc_microbit.conf @@ -32,3 +32,4 @@ CONFIG_BT_MESH_SUBNET_COUNT=1 CONFIG_BT_MESH_APP_KEY_COUNT=1 CONFIG_BT_MESH_MODEL_GROUP_COUNT=1 CONFIG_BT_MESH_LABEL_COUNT=0 +CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n diff --git a/samples/bluetooth/mesh_demo/CMakeLists.txt b/samples/bluetooth/mesh_demo/CMakeLists.txt index 07736d6c12e..f5d347ab373 100644 --- a/samples/bluetooth/mesh_demo/CMakeLists.txt +++ b/samples/bluetooth/mesh_demo/CMakeLists.txt @@ -15,6 +15,6 @@ endif() if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh_demo/README.rst b/samples/bluetooth/mesh_demo/README.rst index 7fe7f0908ce..2edb690ab19 100644 --- a/samples/bluetooth/mesh_demo/README.rst +++ b/samples/bluetooth/mesh_demo/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Demo Overview ******** -This sample is a Bluetooth mesh application intended for demonstration +This sample is a Bluetooth Mesh application intended for demonstration purposes only. The application provisions and configures itself (i.e. no external provisioner needed) with hard-coded network and application key values. The local unicast address can be set using a NODE_ADDR build diff --git a/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf b/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf index 5eb087c4ced..64adc465794 100644 --- a/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf +++ b/samples/bluetooth/mesh_demo/boards/bbc_microbit.conf @@ -22,3 +22,4 @@ CONFIG_BT_MESH_BEACON_ENABLED=n CONFIG_BT_MESH_LABEL_COUNT=1 CONFIG_BT_MESH_SETTINGS_WORKQ=n +CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG=n diff --git a/samples/bluetooth/mesh_provisioner/CMakeLists.txt b/samples/bluetooth/mesh_provisioner/CMakeLists.txt index 7b22bd0fe14..aefe3628ba8 100644 --- a/samples/bluetooth/mesh_provisioner/CMakeLists.txt +++ b/samples/bluetooth/mesh_provisioner/CMakeLists.txt @@ -10,6 +10,6 @@ target_sources(app PRIVATE src/main.c) if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/bluetooth/mesh_provisioner/README.rst b/samples/bluetooth/mesh_provisioner/README.rst index 6da113afc1b..1b37a04a4a8 100644 --- a/samples/bluetooth/mesh_provisioner/README.rst +++ b/samples/bluetooth/mesh_provisioner/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh Provisioner Overview ******** -This sample demonstrates how to use the Bluetooth mesh APIs related to +This sample demonstrates how to use the Bluetooth Mesh APIs related to provisioning and using the Configuration Database (CDB). It is intended to be tested together with a device capable of being provisioned. For example, one could use the sample in diff --git a/samples/bluetooth/mesh_provisioner/prj.conf b/samples/bluetooth/mesh_provisioner/prj.conf index bfc6d5a1241..341dd49ed2e 100644 --- a/samples/bluetooth/mesh_provisioner/prj.conf +++ b/samples/bluetooth/mesh_provisioner/prj.conf @@ -33,7 +33,7 @@ CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_RELAY_RETRANSMIT_COUNT=3 CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=n +CONFIG_BT_MESH_PROVISIONEE=n CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_CDB_NODE_COUNT=16 CONFIG_BT_MESH_CDB_SUBNET_COUNT=3 diff --git a/samples/bluetooth/mtu_update/central/src/central_mtu_update.c b/samples/bluetooth/mtu_update/central/src/central_mtu_update.c index 046446882dc..9db4b507d3c 100644 --- a/samples/bluetooth/mtu_update/central/src/central_mtu_update.c +++ b/samples/bluetooth/mtu_update/central/src/central_mtu_update.c @@ -131,7 +131,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/peripheral_iso/README.rst b/samples/bluetooth/peripheral_iso/README.rst index 4d5d8c1b576..d877cf3a98f 100644 --- a/samples/bluetooth/peripheral_iso/README.rst +++ b/samples/bluetooth/peripheral_iso/README.rst @@ -6,9 +6,10 @@ Bluetooth: Peripheral ISO Overview ******** -Similar to the :ref:`Peripheral ` sample, except that this application enables -support for connected isochronous (ISO) channels. - +This sample demonstrates how to use isochronous channels as a peripheral. +The sample starts advertising, waits for a central to connect to it and set up an isochronous channel. +Once the isochronous channel is set up, received isochronous data is printed out. +It is recommended to run this sample together with the :ref:`Bluetooth: Central ISO ` sample. Requirements ************ @@ -23,4 +24,43 @@ Building and Running This sample can be found under :zephyr_file:`samples/bluetooth/peripheral_iso` in the Zephyr tree. -See :ref:`bluetooth samples section ` for details. +1. Start the application. + In the terminal window, check that it is advertising. + + Bluetooth initialized + Advertising successfully started + +2. Observe that the central device connects and sets up an isochronous channel. + + Connected E8:DC:8D:B3:47:69 (random) + Incoming request from 0x20002260 + ISO Channel 0x20000698 connected + +3. Observe that incoming data is printed. + + Incoming data channel 0x20000698 len 1 + 00 + Incoming data channel 0x20000698 len 2 + 0001 + Incoming data channel 0x20000698 len 3 + 000102 + Incoming data channel 0x20000698 len 4 + 00010203 + Incoming data channel 0x20000698 len 5 + 0001020304 + Incoming data channel 0x20000698 len 6 + 000102030405 + Incoming data channel 0x20000698 len 7 + 000102...040506 + Incoming data channel 0x20000698 len 8 + 000102...050607 + Incoming data channel 0x20000698 len 9 + 000102...060708 + Incoming data channel 0x20000698 len 10 + 000102...070809 + Incoming data channel 0x20000698 len 11 + 000102...08090a + Incoming data channel 0x20000698 len 12 + 000102...090a0b + +See :ref:`bluetooth samples section ` for more details. 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/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index 3953bee99f0..974d4f825f8 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -480,7 +480,7 @@ static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, printk("Device found: %s (RSSI %d)\n", addr_str, rssi); /* connect only to devices in close proximity */ - if (rssi < -70) { + if (rssi < -50) { return; } diff --git a/samples/bluetooth/unicast_audio_client/sysbuild.cmake b/samples/bluetooth/unicast_audio_client/sysbuild.cmake index c150913cc55..2523aac8ea7 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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) 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/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..2523aac8ea7 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) @@ -18,27 +18,7 @@ if(NOT("${SB_CONFIG_NET_CORE_BOARD}" STREQUAL "")) 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/boards/nrf/mesh/onoff-app/README.rst b/samples/boards/nrf/mesh/onoff-app/README.rst index e8cadccd53c..35e37d6a599 100644 --- a/samples/boards/nrf/mesh/onoff-app/README.rst +++ b/samples/boards/nrf/mesh/onoff-app/README.rst @@ -6,7 +6,7 @@ Bluetooth: Mesh OnOff Model Overview ******** -This is a simple application demonstrating a Bluetooth mesh multi-element node. +This is a simple application demonstrating a Bluetooth Mesh multi-element node. Each element has a mesh onoff client and server model which controls one of the 4 sets of buttons and LEDs . diff --git a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst index 05b8d896e77..f33bf1e7761 100644 --- a/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst +++ b/samples/boards/nrf/mesh/onoff_level_lighting_vnd_app/README.rst @@ -4,7 +4,7 @@ Bluetooth: Mesh Generic OnOff, Generic Level, Lighting & Vendor Models ###################################################################### Overview ******** -This is a application demonstrating a Bluetooth mesh node in +This is a application demonstrating a Bluetooth Mesh node in which Root element has following models - Generic OnOff Server 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}) 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/boards/nrf/nrfx/Kconfig b/samples/boards/nrf/nrfx/Kconfig index 0d54067202a..09076c9da49 100644 --- a/samples/boards/nrf/nrfx/Kconfig +++ b/samples/boards/nrf/nrfx/Kconfig @@ -7,4 +7,14 @@ config NRFX_DPPI config NRFX_PPI default HAS_HW_NRF_PPI +config NRFX_GPIOTE0 + default y if SOC_SERIES_NRF51X || \ + SOC_SERIES_NRF52X || \ + (SOC_SERIES_NRF53X && !TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91X && !TRUSTED_EXECUTION_NONSECURE) + +config NRFX_GPIOTE1 + default y if (SOC_SERIES_NRF53X && TRUSTED_EXECUTION_NONSECURE) || \ + (SOC_SERIES_NRF91X && TRUSTED_EXECUTION_NONSECURE) + source "Kconfig.zephyr" diff --git a/samples/boards/nrf/nrfx/prj.conf b/samples/boards/nrf/nrfx/prj.conf index 32cbfc3279c..d4f0c29699f 100644 --- a/samples/boards/nrf/nrfx/prj.conf +++ b/samples/boards/nrf/nrfx/prj.conf @@ -1,4 +1,3 @@ CONFIG_GPIO=n -CONFIG_NRFX_GPIOTE=y CONFIG_LOG=y CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100 diff --git a/samples/boards/nrf/nrfx/src/main.c b/samples/boards/nrf/nrfx/src/main.c index 615b800545e..0643b1c0911 100644 --- a/samples/boards/nrf/nrfx/src/main.c +++ b/samples/boards/nrf/nrfx/src/main.c @@ -21,6 +21,15 @@ LOG_MODULE_REGISTER(nrfx_sample, LOG_LEVEL_INF); #define INPUT_PIN DT_GPIO_PIN(DT_ALIAS(sw0), gpios) #define OUTPUT_PIN DT_GPIO_PIN(DT_ALIAS(led0), gpios) +#define GPIOTE_INST NRF_DT_GPIOTE_INST(DT_ALIAS(sw0), gpios) +#define GPIOTE_NODE DT_NODELABEL(_CONCAT(gpiote, GPIOTE_INST)) + +BUILD_ASSERT(NRF_DT_GPIOTE_INST(DT_ALIAS(led0), gpios) == GPIOTE_INST, + "Both sw0 and led0 GPIOs must use the same GPIOTE instance"); +BUILD_ASSERT(IS_ENABLED(_CONCAT(CONFIG_, _CONCAT(NRFX_GPIOTE, GPIOTE_INST))), + "NRFX_GPIOTE" STRINGIFY(GPIOTE_INST) " must be enabled in Kconfig"); + + static void button_handler(nrfx_gpiote_pin_t pin, nrfx_gpiote_trigger_t trigger, void *context) @@ -35,28 +44,28 @@ int main(void) nrfx_err_t err; uint8_t in_channel, out_channel; uint8_t ppi_channel; + const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(GPIOTE_INST); - /* Connect GPIOTE_0 IRQ to nrfx_gpiote_irq_handler */ - IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)), - DT_IRQ(DT_NODELABEL(gpiote), priority), - nrfx_isr, nrfx_gpiote_irq_handler, 0); + /* Connect GPIOTE instance IRQ to irq handler */ + IRQ_CONNECT(DT_IRQN(GPIOTE_NODE), DT_IRQ(GPIOTE_NODE, priority), nrfx_isr, + NRFX_CONCAT(nrfx_gpiote_, GPIOTE_INST, _irq_handler), 0); /* Initialize GPIOTE (the interrupt priority passed as the parameter * here is ignored, see nrfx_glue.h). */ - err = nrfx_gpiote_init(0); + err = nrfx_gpiote_init(&gpiote, 0); if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_gpiote_init error: 0x%08X", err); return 0; } - err = nrfx_gpiote_channel_alloc(&in_channel); + err = nrfx_gpiote_channel_alloc(&gpiote, &in_channel); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate in_channel, error: 0x%08X", err); return 0; } - err = nrfx_gpiote_channel_alloc(&out_channel); + err = nrfx_gpiote_channel_alloc(&gpiote, &out_channel); if (err != NRFX_SUCCESS) { LOG_ERR("Failed to allocate out_channel, error: 0x%08X", err); return 0; @@ -65,20 +74,22 @@ int main(void) /* Initialize input pin to generate event on high to low transition * (falling edge) and call button_handler() */ - static const nrfx_gpiote_input_config_t input_config = { - .pull = NRF_GPIO_PIN_PULLUP, - }; - const nrfx_gpiote_trigger_config_t trigger_config = { + static const nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLUP; + nrfx_gpiote_trigger_config_t trigger_config = { .trigger = NRFX_GPIOTE_TRIGGER_HITOLO, .p_in_channel = &in_channel, }; static const nrfx_gpiote_handler_config_t handler_config = { .handler = button_handler, }; - err = nrfx_gpiote_input_configure(INPUT_PIN, - &input_config, - &trigger_config, - &handler_config); + nrfx_gpiote_input_pin_config_t input_config = { + .p_pull_config = &pull_config, + .p_trigger_config = &trigger_config, + .p_handler_config = &handler_config + }; + + err = nrfx_gpiote_input_configure(&gpiote, INPUT_PIN, &input_config); + if (err != NRFX_SUCCESS) { LOG_ERR("nrfx_gpiote_input_configure error: 0x%08X", err); return 0; @@ -97,7 +108,7 @@ int main(void) .polarity = NRF_GPIOTE_POLARITY_TOGGLE, .init_val = 1, }; - err = nrfx_gpiote_output_configure(OUTPUT_PIN, + err = nrfx_gpiote_output_configure(&gpiote, OUTPUT_PIN, &output_config, &task_config); if (err != NRFX_SUCCESS) { @@ -105,8 +116,8 @@ int main(void) return 0; } - nrfx_gpiote_trigger_enable(INPUT_PIN, true); - nrfx_gpiote_out_task_enable(OUTPUT_PIN); + nrfx_gpiote_trigger_enable(&gpiote, INPUT_PIN, true); + nrfx_gpiote_out_task_enable(&gpiote, OUTPUT_PIN); LOG_INF("nrfx_gpiote initialized"); @@ -122,8 +133,8 @@ int main(void) * the button is pressed, the LED pin will be toggled. */ nrfx_gppi_channel_endpoints_setup(ppi_channel, - nrfx_gpiote_in_event_address_get(INPUT_PIN), - nrfx_gpiote_out_task_address_get(OUTPUT_PIN)); + nrfx_gpiote_in_event_address_get(&gpiote, INPUT_PIN), + nrfx_gpiote_out_task_address_get(&gpiote, OUTPUT_PIN)); /* Enable the channel. */ nrfx_gppi_channels_enable(BIT(ppi_channel)); diff --git a/samples/boards/reel_board/mesh_badge/README.rst b/samples/boards/reel_board/mesh_badge/README.rst index d5973ab8e9c..ccfc7e771ae 100644 --- a/samples/boards/reel_board/mesh_badge/README.rst +++ b/samples/boards/reel_board/mesh_badge/README.rst @@ -6,7 +6,7 @@ Mesh Badge Overview ******** -This sample app for the reel board showcases Bluetooth mesh +This sample app for the reel board showcases Bluetooth Mesh The app starts off as a regular Bluetooth GATT peripheral application. Install the "nRF Connect" app on your phone (available both for @@ -34,7 +34,7 @@ Steps to set up you're not happy with it you can try writing something else. #. When you're happy with the text, disconnect from the board (exit the app or go back to the device scan page) -#. Once disconnected the board switches over to Bluetooth mesh mode, and you +#. Once disconnected the board switches over to Bluetooth Mesh mode, and you can't connect to it anymore over GATT. If you configure multiple boards like this they can communicate with diff --git a/samples/drivers/counter/alarm/CMakeLists.txt b/samples/drivers/counter/alarm/CMakeLists.txt index eadc9e99e67..747c2b27ebd 100644 --- a/samples/drivers/counter/alarm/CMakeLists.txt +++ b/samples/drivers/counter/alarm/CMakeLists.txt @@ -9,6 +9,6 @@ target_sources(app PRIVATE ${app_sources}) if(CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index e65d44f0048..c69621c2496 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -1,5 +1,6 @@ # # Copyright (c) 2021 Carlo Caione +# Copyright 2023-2024 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -8,10 +9,16 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../remote/zephyr) + if(("${BOARD}" STREQUAL "nrf5340dk_nrf5340_cpuapp") OR ("${BOARD}" STREQUAL "nrf5340bsim_nrf5340_cpuapp") OR ("${BOARD}" STREQUAL "adp_xc7k_ae350") OR - ("${BOARD}" STREQUAL "mimxrt595_evk_cm33")) + ("${BOARD}" STREQUAL "mimxrt1170_evkb_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm7") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu0") OR + ("${BOARD}" STREQUAL "nrf54h20pdk_nrf54h20_cpuapp")) message(STATUS "${BOARD} compile as Main in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") @@ -21,4 +28,9 @@ project(mbox_ipc) enable_language(C ASM) +if(CONFIG_INCLUDE_REMOTE_DIR) + target_include_directories(zephyr_interface + INTERFACE ${REMOTE_ZEPHYR_DIR}/include/public) +endif() + target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/mbox/Kconfig b/samples/drivers/mbox/Kconfig new file mode 100644 index 00000000000..3af6e740bfc --- /dev/null +++ b/samples/drivers/mbox/Kconfig @@ -0,0 +1,37 @@ +# Copyright 2023 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config INCLUDE_REMOTE_DIR + bool "Include remote core header directory" + help + Include remote build header files. Can be used if primary image + needs to be aware of size or base address of secondary image + +config TX_ENABLED + bool "TX enabled" + default y + help + Enable TX + +config TX_CHANNEL_ID + int "Channel ID for TX" + default 1 + depends on TX_ENABLED + help + Channel ID for TX + +config RX_ENABLED + bool "RX enabled" + default y + help + Enable RX + +config RX_CHANNEL_ID + int "Channel ID for RX" + depends on RX_ENABLED + default 0 + help + Channel ID for RX diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index 46ffe3e12ae..aca48b8ead3 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -1,4 +1,5 @@ # Copyright 2023 Nordic Semiconductor ASA +# Copyright 2023-2024 NXP # # SPDX-License-Identifier: Apache-2.0 @@ -9,4 +10,8 @@ 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" + default "mimxrt1170_evkb_cm4" if $(BOARD) = "mimxrt1170_evkb_cm7" + default "mimxrt1170_evk_cm4" if $(BOARD) = "mimxrt1170_evk_cm7" + default "mimxrt1160_evk_cm4" if $(BOARD) = "mimxrt1160_evk_cm7" + default "lpcxpresso55s69_cpu1" if $(BOARD) = "lpcxpresso55s69_cpu0" + default "nrf54h20pdk_nrf54h20_cpuppr" if $(BOARD) = "nrf54h20pdk_nrf54h20_cpuapp" diff --git a/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.conf b/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.conf new file mode 100644 index 00000000000..5077d775881 --- /dev/null +++ b/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.conf @@ -0,0 +1,3 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_MBOX_NXP_MAILBOX=y +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.overlay b/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 00000000000..b5919c4fd72 --- /dev/null +++ b/samples/drivers/mbox/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mailbox0@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.conf b/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.overlay b/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.overlay new file mode 100644 index 00000000000..942f67ba6a9 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1160_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.conf b/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.overlay b/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.overlay new file mode 100644 index 00000000000..942f67ba6a9 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1170_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.conf b/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.conf new file mode 100644 index 00000000000..0dfb100ed70 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.overlay b/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.overlay new file mode 100644 index 00000000000..942f67ba6a9 --- /dev/null +++ b/samples/drivers/mbox/boards/mimxrt1170_evkb_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf b/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf deleted file mode 100644 index b01ff58e024..00000000000 --- a/samples/drivers/mbox/boards/mimxrt595_evk_cm33.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_MBOX_NXP_IMX_MU=y diff --git a/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.conf b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.conf new file mode 100644 index 00000000000..0b6bc73d6bc --- /dev/null +++ b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.conf @@ -0,0 +1 @@ +CONFIG_TX_ENABLED=n diff --git a/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.overlay b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.overlay new file mode 100644 index 00000000000..5f0cfe2261d --- /dev/null +++ b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +mbox: &cpuapp_bellboard { + status = "okay"; +}; diff --git a/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.conf b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.conf new file mode 100644 index 00000000000..d8d66e9812d --- /dev/null +++ b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.conf @@ -0,0 +1,2 @@ +CONFIG_RX_ENABLED=n +CONFIG_TX_CHANNEL_ID=4 diff --git a/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.overlay b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.overlay new file mode 100644 index 00000000000..ed631f04cc3 --- /dev/null +++ b/samples/drivers/mbox/boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +mbox: &cpuppr_vevif { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 3aee2d96482..cb024cb6112 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -1,5 +1,6 @@ # # Copyright (c) 2021 Carlo Caione +# Copyright 2023-2024 NXP # # SPDX-License-Identifier: Apache-2.0 # @@ -10,7 +11,12 @@ 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")) + ("${BOARD}" STREQUAL "mimxrt1170_evkb_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm4") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu1") OR + ("${BOARD}" STREQUAL "adp_xc7k_ae350") OR + ("${BOARD}" STREQUAL "nrf54h20pdk_nrf54h20_cpuppr")) message(STATUS "${BOARD} compile as remote in this sample") else() message(FATAL_ERROR "${BOARD} is not supported for this sample") diff --git a/samples/drivers/mbox/remote/Kconfig b/samples/drivers/mbox/remote/Kconfig new file mode 100644 index 00000000000..7edb8574359 --- /dev/null +++ b/samples/drivers/mbox/remote/Kconfig @@ -0,0 +1,30 @@ +# Copyright 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config TX_ENABLED + bool "TX enabled" + default y + help + Enable TX + +config TX_CHANNEL_ID + int "Channel ID for TX" + default 0 + depends on TX_ENABLED + help + Channel ID for TX + +config RX_ENABLED + bool "RX enabled" + default y + help + Enable RX + +config RX_CHANNEL_ID + int "Channel ID for RX" + depends on RX_ENABLED + default 1 + help + Channel ID for RX diff --git a/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.conf b/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.conf new file mode 100644 index 00000000000..b499f5da051 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.conf @@ -0,0 +1,10 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_MBOX_NXP_MAILBOX=y + +# For purpose of sample enable UART Console on CPU1 +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_CLOCK_CONTROL=y diff --git a/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.overlay b/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.overlay new file mode 100644 index 00000000000..36e6f0ff267 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/lpcxpresso55s69_cpu1.overlay @@ -0,0 +1,43 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + zephyr,console = &flexcomm0; + zephyr,shell-uart = &flexcomm0; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mbox@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +&flexcomm0 { + status = "okay"; +}; + +&dma0 { + status = "okay"; +}; + +&syscon { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.conf b/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.overlay b/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.overlay new file mode 100644 index 00000000000..cc05e9b96c1 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1160_evk_cm4.overlay @@ -0,0 +1,48 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.conf b/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.overlay new file mode 100644 index 00000000000..cc05e9b96c1 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1170_evk_cm4.overlay @@ -0,0 +1,48 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.conf b/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.overlay b/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.overlay new file mode 100644 index 00000000000..392141712a9 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/mimxrt1170_evkb_cm4.overlay @@ -0,0 +1,49 @@ +/* + * Copyright 2023 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart1; + zephyr,shell-uart = &lpuart1; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; + +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.conf b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.conf new file mode 100644 index 00000000000..4596bc3a757 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.conf @@ -0,0 +1 @@ +CONFIG_RX_ENABLED=n diff --git a/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.overlay b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.overlay new file mode 100644 index 00000000000..5f0cfe2261d --- /dev/null +++ b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +mbox: &cpuapp_bellboard { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.conf b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.conf new file mode 100644 index 00000000000..19e03b75c63 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.conf @@ -0,0 +1,2 @@ +CONFIG_TX_ENABLED=n +CONFIG_RX_CHANNEL_ID=4 diff --git a/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.overlay b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.overlay new file mode 100644 index 00000000000..ed631f04cc3 --- /dev/null +++ b/samples/drivers/mbox/remote/boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +mbox: &cpuppr_vevif { + status = "okay"; +}; diff --git a/samples/drivers/mbox/remote/src/main.c b/samples/drivers/mbox/remote/src/main.c index 89039e3b277..1ca832a697c 100644 --- a/samples/drivers/mbox/remote/src/main.c +++ b/samples/drivers/mbox/remote/src/main.c @@ -4,53 +4,64 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include #include +#include -#define TX_ID (0) -#define RX_ID (1) +#if !defined(CONFIG_RX_ENABLED) && !defined(CONFIG_TX_ENABLED) +#error "At least one of CONFIG_RX_ENABLED or CONFIG_TX_ENABLED must be set" +#endif +#ifdef CONFIG_RX_ENABLED static void callback(const struct device *dev, uint32_t channel, void *user_data, struct mbox_msg *data) { printk("Pong (on channel %d)\n", channel); } +#endif /* CONFIG_RX_ENABLED */ int main(void) { - struct mbox_channel tx_channel; - struct mbox_channel rx_channel; - const struct device *dev; + int ret; + const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); - printk("Hello from NET\n"); + printk("Hello from REMOTE\n"); - dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); +#ifdef CONFIG_RX_ENABLED + struct mbox_channel rx_channel; - mbox_init_channel(&tx_channel, dev, TX_ID); - mbox_init_channel(&rx_channel, dev, RX_ID); + mbox_init_channel(&rx_channel, dev, CONFIG_RX_CHANNEL_ID); - if (mbox_register_callback(&rx_channel, callback, NULL)) { - printk("mbox_register_callback() error\n"); + ret = mbox_register_callback(&rx_channel, callback, NULL); + if (ret < 0) { + printk("Could not register callback (%d)\n", ret); return 0; } - if (mbox_set_enabled(&rx_channel, 1)) { - printk("mbox_set_enable() error\n"); + ret = mbox_set_enabled(&rx_channel, true); + if (ret < 0) { + printk("Could not enable RX channel %d (%d)\n", rx_channel.id, ret); return 0; } +#endif /* CONFIG_RX_ENABLED */ - while (1) { +#ifdef CONFIG_TX_ENABLED + struct mbox_channel tx_channel; + + mbox_init_channel(&tx_channel, dev, CONFIG_TX_CHANNEL_ID); + while (1) { printk("Ping (on channel %d)\n", tx_channel.id); - if (mbox_send(&tx_channel, NULL) < 0) { - printk("mbox_send() error\n"); + ret = mbox_send(&tx_channel, NULL); + if (ret < 0) { + printk("Could not send (%d)\n", ret); return 0; } k_sleep(K_MSEC(3000)); } +#endif /* CONFIG_TX_ENABLED */ + return 0; } diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index f7aa8953ea1..b386b9d2b4b 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -8,10 +8,62 @@ tests: platform_allow: - nrf5340dk_nrf5340_cpuapp - adp_xc7k_ae350 - - mimxrt595_evk_cm33 + - mimxrt1170_evkb_cm7 + - mimxrt1170_evk_cm7 + - mimxrt1160_evk_cm7 + - lpcxpresso55s69_cpu0 integration_platforms: - nrf5340dk_nrf5340_cpuapp - harness: remote + 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\\)" + + sample.drivers.mbox.nrf54h20_vevif: + platform_allow: + - nrf54h20pdk_nrf54h20_cpuapp + integration_platforms: + - nrf54h20pdk_nrf54h20_cpuapp + extra_args: + mbox_SNIPPET=nordic-ppr + mbox_EXTRA_CONF_FILE=boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.conf + mbox_DTC_OVERLAY_FILE=boards/nrf54h20pdk_nrf54h20_cpuapp_vevif.overlay + remote_EXTRA_CONF_FILE=boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.conf + remote_DTC_OVERLAY_FILE=boards/nrf54h20pdk_nrf54h20_cpuppr_vevif.overlay + sysbuild: true + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Ping \\(on channel 4\\)" + - "Pong \\(on channel 4\\)" + + sample.drivers.mbox.nrf54h20_bellboard: + platform_allow: + - nrf54h20pdk_nrf54h20_cpuapp + integration_platforms: + - nrf54h20pdk_nrf54h20_cpuapp + extra_args: + mbox_SNIPPET=nordic-ppr + mbox_EXTRA_CONF_FILE=boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.conf + mbox_DTC_OVERLAY_FILE=boards/nrf54h20pdk_nrf54h20_cpuapp_bellboard.overlay + remote_EXTRA_CONF_FILE=boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.conf + remote_DTC_OVERLAY_FILE=boards/nrf54h20pdk_nrf54h20_cpuppr_bellboard.overlay + sysbuild: true + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Ping \\(on channel 0\\)" + - "Pong \\(on channel 0\\)" + sample.drivers.mbox.simu: platform_allow: - nrf5340bsim_nrf5340_cpuapp diff --git a/samples/drivers/mbox/src/main.c b/samples/drivers/mbox/src/main.c index d6c79729b4f..d4dd21d342f 100644 --- a/samples/drivers/mbox/src/main.c +++ b/samples/drivers/mbox/src/main.c @@ -4,52 +4,59 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include #include #include +#include -#define TX_ID (1) -#define RX_ID (0) - +#ifdef CONFIG_RX_ENABLED static void callback(const struct device *dev, uint32_t channel, void *user_data, struct mbox_msg *data) { printk("Pong (on channel %d)\n", channel); } +#endif int main(void) { - struct mbox_channel tx_channel; - struct mbox_channel rx_channel; - const struct device *dev; + int ret; + const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); printk("Hello from APP\n"); - dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); +#ifdef CONFIG_RX_ENABLED + struct mbox_channel rx_channel; - mbox_init_channel(&tx_channel, dev, TX_ID); - mbox_init_channel(&rx_channel, dev, RX_ID); + mbox_init_channel(&rx_channel, dev, CONFIG_RX_CHANNEL_ID); - if (mbox_register_callback(&rx_channel, callback, NULL)) { - printk("mbox_register_callback() error\n"); + ret = mbox_register_callback(&rx_channel, callback, NULL); + if (ret < 0) { + printk("Could not register callback (%d)\n", ret); return 0; } - if (mbox_set_enabled(&rx_channel, 1)) { - printk("mbox_set_enable() error\n"); + ret = mbox_set_enabled(&rx_channel, true); + if (ret < 0) { + printk("Could not enable RX channel %d (%d)\n", rx_channel.id, ret); return 0; } +#endif /* CONFIG_RX_ENABLED */ + +#ifdef CONFIG_TX_ENABLED + struct mbox_channel tx_channel; + + mbox_init_channel(&tx_channel, dev, CONFIG_TX_CHANNEL_ID); while (1) { k_sleep(K_MSEC(2000)); printk("Ping (on channel %d)\n", tx_channel.id); - if (mbox_send(&tx_channel, NULL) < 0) { - printk("mbox_send() error\n"); + ret = mbox_send(&tx_channel, NULL); + if (ret < 0) { + printk("Could not send (%d)\n", ret); return 0; } } +#endif /* CONFIG_TX_ENABLED */ return 0; } diff --git a/samples/drivers/mbox/sysbuild.cmake b/samples/drivers/mbox/sysbuild.cmake index 1bd6a00ae9e..063f6157ddb 100644 --- a/samples/drivers/mbox/sysbuild.cmake +++ b/samples/drivers/mbox/sysbuild.cmake @@ -1,4 +1,5 @@ # Copyright (c) 2023 Nordic Semiconductor ASA +# Copyright 2023-2024 NXP # SPDX-License-Identifier: Apache-2.0 if("${SB_CONFIG_REMOTE_BOARD}" STREQUAL "") @@ -15,24 +16,18 @@ 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}) +native_simulator_set_final_executable(${DEFAULT_IMAGE}) - # 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} +if ("${BOARD}" STREQUAL "mimxrt1170_evkb_cm7" OR + "${BOARD}" STREQUAL "mimxrt1170_evk_cm7" OR + "${BOARD}" STREQUAL "mimxrt1160_evk_cm7" OR + "${BOARD}" STREQUAL "lpcxpresso55s69_cpu0" ) + # For these NXP boards the main core application is dependent on + # 'zephyr_image_info.h' generated by remote application. + + # Let's build the remote application first + add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) endif() 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/drivers/mbox_data/CMakeLists.txt b/samples/drivers/mbox_data/CMakeLists.txt new file mode 100644 index 00000000000..a410ac3d214 --- /dev/null +++ b/samples/drivers/mbox_data/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../remote/zephyr) + +if(("${BOARD}" STREQUAL "mimxrt1170_evkb_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm7") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu0")) + message(STATUS "${BOARD} compile as Main in this sample") +else() + message(FATAL_ERROR "${BOARD} is not supported for this sample") +endif() + +project(mbox_data_ipc) + +enable_language(C ASM) + +if(CONFIG_INCLUDE_REMOTE_DIR) + target_include_directories(zephyr_interface + INTERFACE ${REMOTE_ZEPHYR_DIR}/include/public) +endif() + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/mbox_data/Kconfig b/samples/drivers/mbox_data/Kconfig new file mode 100644 index 00000000000..ee3874c39f9 --- /dev/null +++ b/samples/drivers/mbox_data/Kconfig @@ -0,0 +1,11 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config INCLUDE_REMOTE_DIR + bool "Include remote core header directory" + help + Include remote build header files. Can be used if primary image + needs to be aware of size or base address of secondary image diff --git a/samples/drivers/mbox_data/Kconfig.sysbuild b/samples/drivers/mbox_data/Kconfig.sysbuild new file mode 100644 index 00000000000..2ddab228177 --- /dev/null +++ b/samples/drivers/mbox_data/Kconfig.sysbuild @@ -0,0 +1,12 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config REMOTE_BOARD +string + default "mimxrt1170_evkb_cm4" if $(BOARD) = "mimxrt1170_evkb_cm7" + default "mimxrt1170_evk_cm4" if $(BOARD) = "mimxrt1170_evk_cm7" + default "mimxrt1160_evk_cm4" if $(BOARD) = "mimxrt1160_evk_cm7" + default "lpcxpresso55s69_cpu1" if $(BOARD) = "lpcxpresso55s69_cpu0" diff --git a/samples/drivers/mbox_data/README.rst b/samples/drivers/mbox_data/README.rst new file mode 100644 index 00000000000..1f8b1615f8e --- /dev/null +++ b/samples/drivers/mbox_data/README.rst @@ -0,0 +1,104 @@ +.. zephyr:code-sample:: mbox_data + :name: MBOX Data + :relevant-api: mbox_interface + + Perform inter-processor mailbox communication using the MBOX API with data. + +Overview +******** + +This sample demonstrates how to use the :ref:`MBOX API ` in data transfer mode. +It can be used only with mbox driver which supports data transfer mode. + +Sample will ping-pong up to 4 bytes of data between two cores via two mbox channels. +After each core receives data, it increments it by one and sends it back to other core. + +Building and Running +******************** + +The sample can be built and executed on boards supporting MBOX with data transfer mode. + +Building the application for mimxrt1160_evk_cm7 +=============================================== + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox_data/ + :board: mimxrt1160_evk_cm7 + :goals: debug + :west-args: --sysbuild + +Building the application for mimxrt1170_evk_cm7 +=============================================== + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox_data/ + :board: mimxrt1170_evk_cm7 + :goals: debug + :west-args: --sysbuild + +Building the application for mimxrt1170_evkb_cm7 +================================================ + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox_data/ + :board: mimxrt1170_evkb_cm7 + :goals: debug + :west-args: --sysbuild + +Building the application for lpcxpresso55s69_cpu1 +================================================= + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/mbox_data/ + :board: lpcxpresso55s69_cpu1 + :goals: debug + :west-args: --sysbuild + +Sample Output +============= + +Open a serial terminal (minicom, putty, etc.) and connect the board with the +following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board and the following message will appear on the corresponding +serial port, one is the main core another is the remote core: + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.5.0-4051-g12f4f4dc8679 *** + mbox_data Client demo started + Client send (on channel 3) value: 0 + Client received (on channel 2) value: 1 + Client send (on channel 3) value: 2 + Client received (on channel 2) value: 3 + Client send (on channel 3) value: 4 + ... + Client received (on channel 2) value: 95 + Client send (on channel 3) value: 96 + Client received (on channel 2) value: 97 + Client send (on channel 3) value: 98 + Client received (on channel 2) value: 99 + mbox_data Client demo ended + + +.. code-block:: console + + *** Booting Zephyr OS build zephyr-v3.5.0-4051-g12f4f4dc8679 *** + mbox_data Server demo started + Server receive (on channel 3) value: 0 + Server send (on channel 2) value: 1 + Server receive (on channel 3) value: 2 + Server send (on channel 2) value: 3 + Server receive (on channel 3) value: 4 + ... + Server send (on channel 2) value: 95 + Server receive (on channel 3) value: 96 + Server send (on channel 2) value: 97 + Server receive (on channel 3) value: 98 + Server send (on channel 2) value: 99 + mbox_data Server demo ended. diff --git a/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.conf b/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.conf new file mode 100644 index 00000000000..5077d775881 --- /dev/null +++ b/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.conf @@ -0,0 +1,3 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_MBOX_NXP_MAILBOX=y +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.overlay b/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 00000000000..b5919c4fd72 --- /dev/null +++ b/samples/drivers/mbox_data/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mailbox0@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.conf b/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.overlay b/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1160_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.conf b/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.overlay b/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1170_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.conf b/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.conf new file mode 100644 index 00000000000..0dfb100ed70 --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.overlay b/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/samples/drivers/mbox_data/boards/mimxrt1170_evkb_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox_data/prj.conf b/samples/drivers/mbox_data/prj.conf new file mode 100644 index 00000000000..293e2834f25 --- /dev/null +++ b/samples/drivers/mbox_data/prj.conf @@ -0,0 +1,2 @@ +CONFIG_PRINTK=y +CONFIG_MBOX=y diff --git a/samples/drivers/mbox_data/remote/CMakeLists.txt b/samples/drivers/mbox_data/remote/CMakeLists.txt new file mode 100644 index 00000000000..47e1cae8628 --- /dev/null +++ b/samples/drivers/mbox_data/remote/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +if(("${BOARD}" STREQUAL "mimxrt1170_evkb_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm4") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu1")) + message(STATUS "${BOARD} compile as remote in this sample") +else() + message(FATAL_ERROR "${BOARD} is not supported for this sample") +endif() + +project(mbox_data_ipc_remote) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf b/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf new file mode 100644 index 00000000000..14ed92ba8f4 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf @@ -0,0 +1,3 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_MBOX_NXP_MAILBOX=y diff --git a/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay b/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay new file mode 100644 index 00000000000..96bd5aa1c3a --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mbox@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf b/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay b/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay new file mode 100644 index 00000000000..3f6115b9c58 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay @@ -0,0 +1,54 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay new file mode 100644 index 00000000000..3f6115b9c58 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay @@ -0,0 +1,54 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay new file mode 100644 index 00000000000..e3576826702 --- /dev/null +++ b/samples/drivers/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay @@ -0,0 +1,55 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; + +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/samples/drivers/mbox_data/remote/prj.conf b/samples/drivers/mbox_data/remote/prj.conf new file mode 100644 index 00000000000..473e4280601 --- /dev/null +++ b/samples/drivers/mbox_data/remote/prj.conf @@ -0,0 +1,2 @@ +CONFIG_STDOUT_CONSOLE=n +CONFIG_MBOX=y diff --git a/samples/drivers/mbox_data/remote/src/main.c b/samples/drivers/mbox_data/remote/src/main.c new file mode 100644 index 00000000000..0f3ad77a4d0 --- /dev/null +++ b/samples/drivers/mbox_data/remote/src/main.c @@ -0,0 +1,83 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static K_SEM_DEFINE(g_mbox_data_rx_sem, 0, 1); + +static uint32_t g_mbox_received_data; +static uint32_t g_mbox_received_channel; + +#define TX_ID (2) +#define RX_ID (3) + +static void callback(const struct device *dev, uint32_t channel, void *user_data, + struct mbox_msg *data) +{ + memcpy(&g_mbox_received_data, data->data, data->size); + g_mbox_received_channel = channel; + + k_sem_give(&g_mbox_data_rx_sem); +} + +int main(void) +{ + struct mbox_channel tx_channel; + struct mbox_channel rx_channel; + const struct device *dev; + struct mbox_msg msg = {0}; + uint32_t message = 0; + + printk("mbox_data Server demo started\n"); + + dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); + + mbox_init_channel(&tx_channel, dev, TX_ID); + mbox_init_channel(&rx_channel, dev, RX_ID); + + const int max_transfer_size_bytes = mbox_mtu_get(dev); + /* Sample currently supports only transfer size up to 4 bytes */ + if ((max_transfer_size_bytes <= 0) || (max_transfer_size_bytes > 4)) { + printk("mbox_mtu_get() error\n"); + return 0; + } + + if (mbox_register_callback(&rx_channel, callback, NULL)) { + printk("mbox_register_callback() error\n"); + return 0; + } + + if (mbox_set_enabled(&rx_channel, 1)) { + printk("mbox_set_enable() error\n"); + return 0; + } + + while (message < 99) { + k_sem_take(&g_mbox_data_rx_sem, K_FOREVER); + message = g_mbox_received_data; + + printk("Server receive (on channel %d) value: %d\n", g_mbox_received_channel, + g_mbox_received_data); + + message++; + + msg.data = &message; + msg.size = max_transfer_size_bytes; + + printk("Server send (on channel %d) value: %d\n", tx_channel.id, message); + if (mbox_send(&tx_channel, &msg) < 0) { + printk("mbox_send() error\n"); + return 0; + } + } + + printk("mbox_data Server demo ended.\n"); + return 0; +} diff --git a/samples/drivers/mbox_data/sample.yaml b/samples/drivers/mbox_data/sample.yaml new file mode 100644 index 00000000000..b4a1e23a9bc --- /dev/null +++ b/samples/drivers/mbox_data/sample.yaml @@ -0,0 +1,29 @@ +sample: + name: MBOX Data IPC sample +common: + sysbuild: true + tags: mbox +tests: + sample.drivers.mbox_data.real_hw: + platform_allow: + - mimxrt1170_evkb_cm7 + - mimxrt1170_evk_cm7 + - mimxrt1160_evk_cm7 + - lpcxpresso55s69_cpu0 + integration_platforms: + - mimxrt1160_evk_cm7 + - lpcxpresso55s69_cpu0 + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "Client received \\(on channel 2\\) value: 1" + - "Client send \\(on channel 3\\) value: 2" + - "Client received \\(on channel 2\\) value: 3" + - "Client send \\(on channel 3\\) value: 4" + - "Client received \\(on channel 2\\) value: 41" + - "Client send \\(on channel 3\\) value: 42" + - "Client received \\(on channel 2\\) value: 97" + - "Client send \\(on channel 3\\) value: 98" + - "Client received \\(on channel 2\\) value: 99" diff --git a/samples/drivers/mbox_data/src/main.c b/samples/drivers/mbox_data/src/main.c new file mode 100644 index 00000000000..85df24940c4 --- /dev/null +++ b/samples/drivers/mbox_data/src/main.c @@ -0,0 +1,82 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static K_SEM_DEFINE(g_mbox_data_rx_sem, 0, 1); + +static uint32_t g_mbox_received_data; +static uint32_t g_mbox_received_channel; + +#define TX_ID (3) +#define RX_ID (2) + +static void callback(const struct device *dev, uint32_t channel, void *user_data, + struct mbox_msg *data) +{ + memcpy(&g_mbox_received_data, data->data, data->size); + g_mbox_received_channel = channel; + + k_sem_give(&g_mbox_data_rx_sem); +} + +int main(void) +{ + struct mbox_channel tx_channel; + struct mbox_channel rx_channel; + const struct device *dev; + struct mbox_msg msg = {0}; + uint32_t message = 0; + + printk("mbox_data Client demo started\n"); + + dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); + + mbox_init_channel(&tx_channel, dev, TX_ID); + mbox_init_channel(&rx_channel, dev, RX_ID); + + const int max_transfer_size_bytes = mbox_mtu_get(dev); + /* Sample currently supports only transfer size up to 4 bytes */ + if ((max_transfer_size_bytes < 0) || (max_transfer_size_bytes > 4)) { + printk("mbox_mtu_get() error\n"); + return 0; + } + + if (mbox_register_callback(&rx_channel, callback, NULL)) { + printk("mbox_register_callback() error\n"); + return 0; + } + + if (mbox_set_enabled(&rx_channel, 1)) { + printk("mbox_set_enable() error\n"); + return 0; + } + + while (message < 100) { + msg.data = &message; + msg.size = max_transfer_size_bytes; + + printk("Client send (on channel %d) value: %d\n", tx_channel.id, message); + if (mbox_send(&tx_channel, &msg) < 0) { + printk("mbox_send() error\n"); + return 0; + } + + k_sem_take(&g_mbox_data_rx_sem, K_FOREVER); + message = g_mbox_received_data; + + printk("Client received (on channel %d) value: %d\n", g_mbox_received_channel, + message); + message++; + } + + printk("mbox_data Client demo ended\n"); + return 0; +} diff --git a/samples/drivers/mbox_data/sysbuild.cmake b/samples/drivers/mbox_data/sysbuild.cmake new file mode 100644 index 00000000000..5c536a6229a --- /dev/null +++ b/samples/drivers/mbox_data/sysbuild.cmake @@ -0,0 +1,28 @@ +# Copyright 2024 NXP +# +# 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 "mimxrt1170_evkb_cm7" OR + "${BOARD}" STREQUAL "mimxrt1170_evk_cm7" OR + "${BOARD}" STREQUAL "mimxrt1160_evk_cm7" + ) + # For these NXP boards the main core application is dependent on + # 'zephyr_image_info.h' generated by remote application. + + # Let's build the remote application first + add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) +endif() diff --git a/samples/drivers/soc_flash_nrf/README.rst b/samples/drivers/soc_flash_nrf/README.rst index 496688e8b65..2ee87739aad 100644 --- a/samples/drivers/soc_flash_nrf/README.rst +++ b/samples/drivers/soc_flash_nrf/README.rst @@ -62,7 +62,7 @@ Sample Output Data read: 1234 Data read matches data written. Good! - Test 3: Flash erase (4 pages at 0x80000) + Test 3: Flash erase (2 pages at 0x80000) Flash erase succeeded! Test 4: Flash write (word array 2) @@ -131,3 +131,5 @@ Sample Output Test 8: Write block size API write-block-size = 1 + + Finished! diff --git a/samples/drivers/soc_flash_nrf/prj.conf b/samples/drivers/soc_flash_nrf/prj.conf index 9909ef3b29f..48e64121b6a 100644 --- a/samples/drivers/soc_flash_nrf/prj.conf +++ b/samples/drivers/soc_flash_nrf/prj.conf @@ -3,3 +3,7 @@ CONFIG_FLASH=y CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_MPU_ALLOW_FLASH_WRITE=y CONFIG_SOC_FLASH_NRF_EMULATE_ONE_BYTE_WRITE_ACCESS=y +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/samples/drivers/soc_flash_nrf/sample.yaml b/samples/drivers/soc_flash_nrf/sample.yaml index b8a59328be4..d1f635ca93f 100644 --- a/samples/drivers/soc_flash_nrf/sample.yaml +++ b/samples/drivers/soc_flash_nrf/sample.yaml @@ -29,3 +29,4 @@ tests: - "Data read matches data written. Good!" - "SoC flash consists of \\d+ pages." - "write-block-size = 1" + - "Finished!" diff --git a/samples/drivers/soc_flash_nrf/src/main.c b/samples/drivers/soc_flash_nrf/src/main.c index a438a67cf2f..29606a9ca5d 100644 --- a/samples/drivers/soc_flash_nrf/src/main.c +++ b/samples/drivers/soc_flash_nrf/src/main.c @@ -13,11 +13,7 @@ #include -#ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE -#define TEST_PARTITION slot1_ns_partition -#else -#define TEST_PARTITION slot1_partition -#endif +#define TEST_PARTITION storage_partition #define TEST_PARTITION_OFFSET FIXED_PARTITION_OFFSET(TEST_PARTITION) #define TEST_PARTITION_DEVICE FIXED_PARTITION_DEVICE(TEST_PARTITION) @@ -84,9 +80,9 @@ int main(void) } } - offset = TEST_PARTITION_OFFSET - FLASH_PAGE_SIZE * 2; - printf("\nTest 3: Flash erase (4 pages at 0x%x)\n", offset); - if (flash_erase(flash_dev, offset, FLASH_PAGE_SIZE * 4) != 0) { + offset = TEST_PARTITION_OFFSET; + printf("\nTest 3: Flash erase (2 pages at 0x%x)\n", offset); + if (flash_erase(flash_dev, offset, FLASH_PAGE_SIZE * 2) != 0) { printf(" Flash erase failed!\n"); } else { printf(" Flash erase succeeded!\n"); @@ -191,5 +187,7 @@ int main(void) printf("\nTest 8: Write block size API\n"); printf(" write-block-size = %u\n", flash_get_write_block_size(flash_dev)); + + printf("\nFinished!\n"); return 0; } diff --git a/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..66157d79fb3 --- /dev/null +++ b/samples/drivers/watchdog/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,8 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt30 { + status = "okay"; +}; diff --git a/samples/net/cellular_modem/README.rst b/samples/net/cellular_modem/README.rst index 384d8b3bef5..b845b2e37d8 100644 --- a/samples/net/cellular_modem/README.rst +++ b/samples/net/cellular_modem/README.rst @@ -18,7 +18,7 @@ Notes This sample uses the devicetree alias modem to identify the modem instance to use. The sample also presumes that -the modem driver creates the only network interface. +the modem driver creates the only PPP network interface. Setup ***** diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf new file mode 100644 index 00000000000..2af3b6d2a41 --- /dev/null +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.conf @@ -0,0 +1,13 @@ +CONFIG_UART_ASYNC_API=y + +# Align with the Serial LTE Modem (SLM) application. +CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500 +CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES=1500 + +# Allow large UART TXs to go through @115200. +CONFIG_MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS=200 + +# Print logs and printk() output on uart0. +CONFIG_LOG=y +CONFIG_LOG_BACKEND_UART=y +CONFIG_MODEM_LOG_LEVEL_DBG=y diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.overlay b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.overlay new file mode 100644 index 00000000000..c639ec8b305 --- /dev/null +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf52840.overlay @@ -0,0 +1,18 @@ +#include + +/ { + aliases { + modem = &modem; + }; +}; + +&uart1 { + current-speed = <115200>; + hw-flow-control; + + modem: modem { + compatible = "nordic,nrf91-slm"; + status = "okay"; + mdm-power-gpios = <&interface_to_nrf9160 4 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf new file mode 100644 index 00000000000..441a5395ca1 --- /dev/null +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.conf @@ -0,0 +1,16 @@ +CONFIG_UART_ASYNC_API=y + +# Align with the Serial LTE Modem (SLM) application. +CONFIG_MODEM_CELLULAR_CMUX_MAX_FRAME_SIZE=1500 +CONFIG_MODEM_CELLULAR_UART_BUFFER_SIZES=1500 + +# Allow large UART TXs to go through @115200. +CONFIG_MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS=200 + +# Prevent sockets getting offloaded to the modem. +CONFIG_NET_SOCKETS_OFFLOAD=n + +# Print logs and printk() output on uart0. +CONFIG_LOG=y +CONFIG_LOG_BACKEND_UART=y +CONFIG_MODEM_LOG_LEVEL_DBG=y diff --git a/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.overlay b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.overlay new file mode 100644 index 00000000000..44ce80601a1 --- /dev/null +++ b/samples/net/cellular_modem/boards/nrf9160dk_nrf9160_ns.overlay @@ -0,0 +1,34 @@ +/ { + aliases { + modem = &modem; + }; +}; + +&uart1 { + compatible = "nordic,nrf-uarte"; + current-speed = <115200>; + hw-flow-control; + status = "okay"; + + pinctrl-0 = <&uart1_default_alt>; + + modem: modem { + compatible = "nordic,nrf91-slm"; + status = "okay"; + mdm-power-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + uart1_default_alt: uart1_default_alt { + group1 { + psels = ; + bias-pull-up; + }; + group2 { + psels = , + , + ; + }; + }; +}; diff --git a/samples/net/cellular_modem/prj.conf b/samples/net/cellular_modem/prj.conf index 52d0ca26bde..ab44ca9528e 100644 --- a/samples/net/cellular_modem/prj.conf +++ b/samples/net/cellular_modem/prj.conf @@ -22,3 +22,7 @@ CONFIG_NET_CONNECTION_MANAGER=y CONFIG_MODEM=y CONFIG_PM_DEVICE=y CONFIG_MODEM_CELLULAR=y + +# Logging +CONFIG_MODEM_MODULES_LOG_LEVEL_DBG=y +#CONFIG_MODEM_CMUX_LOG_LEVEL_DBG=y diff --git a/samples/net/cellular_modem/src/main.c b/samples/net/cellular_modem/src/main.c index 95e1c45f160..422b19b3c34 100644 --- a/samples/net/cellular_modem/src/main.c +++ b/samples/net/cellular_modem/src/main.c @@ -83,7 +83,7 @@ static int sample_dns_request(void) return 0; } -int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen) +int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen, uint16_t *port) { int ret; int socket_fd; @@ -96,22 +96,16 @@ int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen) socket_fd = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (socket_fd < 0) { - printk("Failed to open socket\n"); + printk("Failed to open socket (%d)\n", errno); return -1; } printk("Socket opened\n"); - if (ai_addr->sa_family == AF_INET) { - net_sin(ai_addr)->sin_port = htons(SAMPLE_TEST_ENDPOINT_UDP_ECHO_PORT); - } else if (ai_addr->sa_family == AF_INET6) { - net_sin6(ai_addr)->sin6_port = htons(SAMPLE_TEST_ENDPOINT_UDP_ECHO_PORT); - } else { - printk("Unsupported address family\n"); - return -1; - } + *port = htons(SAMPLE_TEST_ENDPOINT_UDP_ECHO_PORT); for (uint32_t i = 0; i < SAMPLE_TEST_ECHO_PACKETS; i++) { + printk("Sending echo packet\n"); send_start_ms = k_uptime_get_32(); ret = zsock_sendto(socket_fd, sample_test_packet, sizeof(sample_test_packet), 0, @@ -122,6 +116,7 @@ int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen) continue; } + printk("Receiving echoed packet\n"); ret = zsock_recv(socket_fd, sample_recv_buffer, sizeof(sample_recv_buffer), 0); if (ret != sizeof(sample_test_packet)) { printk("Echoed sample test packet has incorrect size\n"); @@ -142,10 +137,10 @@ int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen) printk("Echo transmit time %ums\n", echo_received_ms - send_start_ms); } - printk("Successfully sent %u packets of %u packets\n", packets_sent, + printk("Successfully sent and received %u of %u packets\n", packets_sent, SAMPLE_TEST_ECHO_PACKETS); - printk("Average time per echo: %u ms\n", + printk("Average time per successful echo: %u ms\n", accumulated_ms / packets_sent); printk("Close UDP socket\n"); @@ -160,7 +155,7 @@ int sample_echo_packet(struct sockaddr *ai_addr, socklen_t ai_addrlen) } -int sample_transmit_packets(struct sockaddr *ai_addr, socklen_t ai_addrlen) +int sample_transmit_packets(struct sockaddr *ai_addr, socklen_t ai_addrlen, uint16_t *port) { int ret; int socket_fd; @@ -180,14 +175,7 @@ int sample_transmit_packets(struct sockaddr *ai_addr, socklen_t ai_addrlen) printk("Socket opened\n"); - if (ai_addr->sa_family == AF_INET) { - net_sin(ai_addr)->sin_port = htons(SAMPLE_TEST_ENDPOINT_UDP_RECEIVE_PORT); - } else if (ai_addr->sa_family == AF_INET6) { - net_sin6(ai_addr)->sin6_port = htons(SAMPLE_TEST_ENDPOINT_UDP_RECEIVE_PORT); - } else { - printk("Unsupported address family\n"); - return -1; - } + *port = htons(SAMPLE_TEST_ENDPOINT_UDP_RECEIVE_PORT); printk("Sending %u packets\n", SAMPLE_TEST_TRANSMIT_PACKETS); send_start_ms = k_uptime_get_32(); @@ -232,9 +220,8 @@ int sample_transmit_packets(struct sockaddr *ai_addr, socklen_t ai_addrlen) int main(void) { - uint32_t raised_event; - const void *info; - size_t info_len; + struct net_if *const iface = net_if_get_first_by_type(&NET_L2_GET_NAME(PPP)); + uint16_t *port; int ret; init_sample_test_packet(); @@ -243,16 +230,15 @@ int main(void) pm_device_action_run(modem, PM_DEVICE_ACTION_RESUME); printk("Bring up network interface\n"); - ret = net_if_up(net_if_get_default()); + ret = net_if_up(iface); if (ret < 0) { printk("Failed to bring up network interface\n"); return -1; } printk("Waiting for L4 connected\n"); - ret = net_mgmt_event_wait_on_iface(net_if_get_default(), - NET_EVENT_L4_CONNECTED, &raised_event, &info, - &info_len, K_SECONDS(120)); + ret = net_mgmt_event_wait_on_iface(iface, NET_EVENT_L4_CONNECTED, NULL, NULL, NULL, + K_SECONDS(120)); if (ret != 0) { printk("L4 was not connected in time\n"); @@ -260,9 +246,12 @@ int main(void) } printk("Waiting for DNS server added\n"); - ret = net_mgmt_event_wait_on_iface(net_if_get_default(), - NET_EVENT_DNS_SERVER_ADD, &raised_event, &info, - &info_len, K_SECONDS(10)); + ret = net_mgmt_event_wait_on_iface(iface, NET_EVENT_DNS_SERVER_ADD, NULL, NULL, NULL, + K_SECONDS(10)); + if (ret) { + printk("DNS server was not added in time\n"); + return -1; + } printk("Performing DNS lookup of %s\n", SAMPLE_TEST_ENDPOINT_HOSTNAME); ret = sample_dns_request(); @@ -271,16 +260,37 @@ int main(void) return -1; } + { + char ip_str[INET6_ADDRSTRLEN]; + const void *src; + + switch (sample_test_dns_addrinfo.ai_addr.sa_family) { + case AF_INET: + src = &net_sin(&sample_test_dns_addrinfo.ai_addr)->sin_addr; + port = &net_sin(&sample_test_dns_addrinfo.ai_addr)->sin_port; + break; + case AF_INET6: + src = &net_sin6(&sample_test_dns_addrinfo.ai_addr)->sin6_addr; + port = &net_sin6(&sample_test_dns_addrinfo.ai_addr)->sin6_port; + break; + default: + printk("Unsupported address family\n"); + return -1; + } + inet_ntop(sample_test_dns_addrinfo.ai_addr.sa_family, src, ip_str, sizeof(ip_str)); + printk("Resolved to %s\n", ip_str); + } + ret = sample_echo_packet(&sample_test_dns_addrinfo.ai_addr, - sample_test_dns_addrinfo.ai_addrlen); + sample_test_dns_addrinfo.ai_addrlen, port); if (ret < 0) { - printk("Failed to send echo\n"); + printk("Failed to send echos\n"); return -1; } ret = sample_transmit_packets(&sample_test_dns_addrinfo.ai_addr, - sample_test_dns_addrinfo.ai_addrlen); + sample_test_dns_addrinfo.ai_addrlen, port); if (ret < 0) { printk("Failed to send packets\n"); @@ -295,24 +305,28 @@ int main(void) } pm_device_action_run(modem, PM_DEVICE_ACTION_RESUME); - ret = net_mgmt_event_wait_on_iface(net_if_get_default(), - NET_EVENT_L4_CONNECTED, &raised_event, &info, - &info_len, K_SECONDS(60)); + printk("Waiting for L4 connected\n"); + ret = net_mgmt_event_wait_on_iface(iface, NET_EVENT_L4_CONNECTED, NULL, NULL, NULL, + K_SECONDS(60)); if (ret != 0) { printk("L4 was not connected in time\n"); return -1; } + printk("L4 connected\n"); + + /* Wait a bit to avoid (unsuccessfully) trying to send the first echo packet too quickly. */ + k_sleep(K_SECONDS(1)); ret = sample_echo_packet(&sample_test_dns_addrinfo.ai_addr, - sample_test_dns_addrinfo.ai_addrlen); + sample_test_dns_addrinfo.ai_addrlen, port); if (ret < 0) { - printk("Failed to send echo after restart\n"); + printk("Failed to send echos after restart\n"); return -1; } - ret = net_if_down(net_if_get_default()); + ret = net_if_down(iface); if (ret < 0) { printk("Failed to bring down network interface\n"); return -1; diff --git a/samples/net/dhcpv4_client/overlay-nrf700x.conf b/samples/net/dhcpv4_client/overlay-nrf700x.conf new file mode 100644 index 00000000000..2d552e9c623 --- /dev/null +++ b/samples/net/dhcpv4_client/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/dns_resolve/overlay-nrf700x.conf b/samples/net/dns_resolve/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/dns_resolve/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/ipv4_autoconf/overlay-nrf700x.conf b/samples/net/ipv4_autoconf/overlay-nrf700x.conf new file mode 100644 index 00000000000..2d552e9c623 --- /dev/null +++ b/samples/net/ipv4_autoconf/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/lwm2m_client/overlay-nrf700x.conf b/samples/net/lwm2m_client/overlay-nrf700x.conf new file mode 100644 index 00000000000..2409886fe42 --- /dev/null +++ b/samples/net/lwm2m_client/overlay-nrf700x.conf @@ -0,0 +1,68 @@ +# General +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_ENTROPY_GENERATOR=y +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WIFI_MGMT_EXT=y +CONFIG_NRF_WIFI_IF_AUTO_START=n + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" + +# WPA +CONFIG_WPA_SUPP=y +CONFIG_WPA_SUPP_LOG_LEVEL_ERR=y + +CONFIG_NET_NATIVE=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_UDP=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETS_OFFLOAD=n +CONFIG_NET_BUF_RX_COUNT=18 +CONFIG_NET_BUF_TX_COUNT=18 +CONFIG_NET_DEFAULT_IF_WIFI=y + +# DNS +CONFIG_DNS_RESOLVER=y + +# DHCPv4 +CONFIG_NET_DHCPV4=y +CONFIG_NET_CONFIG_AUTO_INIT=n +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV4=n + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Zephyr NET Connection Manager Connectivity layer. +CONFIG_L2_WIFI_CONNECTIVITY=y +CONFIG_L2_WIFI_CONNECTIVITY_AUTO_DOWN=n +CONFIG_L2_WIFI_CONNECTIVITY_AUTO_CONNECT=n + +CONFIG_LWM2M_APP_ID="nrf700x" +CONFIG_LWM2M_APP_SERVER="coaps://leshan.eclipseprojects.io:5684" +CONFIG_LWM2M_DNS_SUPPORT=y + +# Enable DTLS support +CONFIG_LWM2M_DTLS_SUPPORT=y +CONFIG_LWM2M_TLS_SESSION_CACHING=y + +# TLS networking +CONFIG_NET_SOCKETS_ENABLE_DTLS=y +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 +CONFIG_NET_SOCKETS_SOCKOPT_TLS=y + +# nRF Security +CONFIG_NRF_SECURITY=y + +# mbedTLS +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=120000 +CONFIG_MBEDTLS_RSA_C=y diff --git a/samples/net/lwm2m_client/overlay-nrf91x.conf b/samples/net/lwm2m_client/overlay-nrf91x.conf new file mode 100644 index 00000000000..9597791c10e --- /dev/null +++ b/samples/net/lwm2m_client/overlay-nrf91x.conf @@ -0,0 +1,53 @@ +# Configuration file for nRF91x +# This file is merged with prj.conf in the application folder, and options +# set here will take precedence if they are present in both files. + +# General +CONFIG_MAIN_STACK_SIZE=4096 + +CONFIG_NET_SOCKETS=y +CONFIG_NET_NATIVE=y +CONFIG_NET_SOCKETS_OFFLOAD=y + +CONFIG_NET_CONFIG_MY_IPV6_ADDR="" +CONFIG_NET_CONFIG_PEER_IPV6_ADDR="" +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_MY_IPV4_GW="" + +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV4=n +CONFIG_NET_CONFIG_AUTO_INIT=n + +# Modem related configurations +CONFIG_NRF_MODEM_LIB_NET_IF=y +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_DOWN=n +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n +CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=n +CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y + +CONFIG_LTE_LINK_CONTROL_LOG_LEVEL_DBG=n +CONFIG_NRF_MODEM_LIB_NET_IF_LOG_LEVEL_DBG=n + +# Disable Duplicate Address Detection (DAD) +# due to not being properly implemented for offloaded interfaces. +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_MLD=n + +# Zephyr NET Connection Manager and Connectivity layer. +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 + +CONFIG_LWM2M_APP_ID="nrf91x" +CONFIG_LWM2M_APP_SERVER="coaps://leshan.eclipseprojects.io:5684" +CONFIG_LWM2M_DNS_SUPPORT=y + +## Enable DTLS support +CONFIG_LWM2M_DTLS_SUPPORT=y +CONFIG_LWM2M_TLS_SESSION_CACHING=y +CONFIG_LWM2M_DTLS_CID=y +CONFIG_TLS_CREDENTIALS=y + +## Crypto +CONFIG_OBERON_BACKEND=y +CONFIG_NORDIC_SECURITY_BACKEND=y +CONFIG_MBEDTLS_SHA256_C=y diff --git a/samples/net/lwm2m_client/overlay-queue.conf b/samples/net/lwm2m_client/overlay-queue.conf index 1adc9eda5ec..946c0fbab67 100644 --- a/samples/net/lwm2m_client/overlay-queue.conf +++ b/samples/net/lwm2m_client/overlay-queue.conf @@ -1,5 +1,7 @@ CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 +CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE=y + # Default lifetime is 1 day CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME=86400 # Send update once an hour diff --git a/samples/net/lwm2m_client/src/lwm2m-client.c b/samples/net/lwm2m_client/src/lwm2m-client.c index 748f654d9ee..2e9792e51ea 100644 --- a/samples/net/lwm2m_client/src/lwm2m-client.c +++ b/samples/net/lwm2m_client/src/lwm2m-client.c @@ -16,6 +16,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include +#include #include "modules.h" #define APP_BANNER "Run LWM2M client" @@ -29,6 +31,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_FIRMWARE_VER "1.0" #define CLIENT_HW_VER "1.0.1" +/* Macros used to subscribe to specific Zephyr NET management events. */ +#define L4_EVENT_MASK (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED) +#define CONN_LAYER_EVENT_MASK (NET_EVENT_CONN_IF_FATAL_ERROR) + static uint8_t bat_idx = LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT; static int bat_mv = 3800; static int bat_ma = 125; @@ -52,6 +58,12 @@ BUILD_ASSERT(sizeof(endpoint) <= CONFIG_LWM2M_SECURITY_KEY_SIZE, static struct k_sem quit_lock; +/* Zephyr NET management event callback structures. */ +static struct net_mgmt_event_callback l4_cb; +static struct net_mgmt_event_callback conn_cb; + +static K_SEM_DEFINE(network_connected_sem, 0, 1); + static int device_reboot_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { @@ -179,6 +191,10 @@ static void rd_client_event(struct lwm2m_ctx *client, /* do nothing */ break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_DBG("LwM2M server disabled"); + break; + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: LOG_DBG("Bootstrap registration failure!"); break; @@ -237,6 +253,25 @@ static void rd_client_event(struct lwm2m_ctx *client, } } +static void socket_state(int fd, enum lwm2m_socket_states state) +{ + (void) fd; + switch (state) { + case LWM2M_SOCKET_STATE_ONGOING: + LOG_DBG("LWM2M_SOCKET_STATE_ONGOING"); + break; + case LWM2M_SOCKET_STATE_ONE_RESPONSE: + LOG_DBG("LWM2M_SOCKET_STATE_ONE_RESPONSE"); + break; + case LWM2M_SOCKET_STATE_LAST: + LOG_DBG("LWM2M_SOCKET_STATE_LAST"); + break; + case LWM2M_SOCKET_STATE_NO_DATA: + LOG_DBG("LWM2M_SOCKET_STATE_NO_DATA"); + break; + } +} + static void observe_cb(enum lwm2m_observe_event event, struct lwm2m_obj_path *path, void *user_data) { @@ -265,6 +300,47 @@ static void observe_cb(enum lwm2m_observe_event event, } } +static void on_net_event_l4_disconnected(void) +{ + LOG_INF("Disconnected from network"); + lwm2m_engine_pause(); +} + +static void on_net_event_l4_connected(void) +{ + LOG_INF("Connected to network"); + k_sem_give(&network_connected_sem); + lwm2m_engine_resume(); +} + +static void l4_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, + struct net_if *iface) +{ + switch (event) { + case NET_EVENT_L4_CONNECTED: + LOG_INF("IP Up"); + on_net_event_l4_connected(); + break; + case NET_EVENT_L4_DISCONNECTED: + LOG_INF("IP down"); + on_net_event_l4_disconnected(); + break; + default: + break; + } +} + +static void connectivity_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, + struct net_if *iface) +{ + if (event == NET_EVENT_CONN_IF_FATAL_ERROR) { + LOG_ERR("Fatal error received from the connectivity layer"); + return; + } +} + int main(void) { uint32_t flags = IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) ? @@ -275,6 +351,31 @@ int main(void) k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT); + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { + /* Setup handler for Zephyr NET Connection Manager events. */ + net_mgmt_init_event_callback(&l4_cb, l4_event_handler, L4_EVENT_MASK); + net_mgmt_add_event_callback(&l4_cb); + + /* Setup handler for Zephyr NET Connection Manager Connectivity layer. */ + net_mgmt_init_event_callback(&conn_cb, connectivity_event_handler, + CONN_LAYER_EVENT_MASK); + net_mgmt_add_event_callback(&conn_cb); + + ret = net_if_up(net_if_get_default()); + + if (ret < 0 && ret != -EALREADY) { + LOG_ERR("net_if_up, error: %d", ret); + return ret; + } + + ret = conn_mgr_if_connect(net_if_get_default()); + /* Ignore errors from interfaces not requiring connectivity */ + if (ret == 0) { + LOG_INF("Connecting to network"); + k_sem_take(&network_connected_sem, K_FOREVER); + } + } + ret = lwm2m_setup(); if (ret < 0) { LOG_ERR("Cannot setup LWM2M fields (%d)", ret); @@ -285,6 +386,7 @@ int main(void) #if defined(CONFIG_LWM2M_DTLS_SUPPORT) client_ctx.tls_tag = CONFIG_LWM2M_APP_TLS_TAG; #endif + client_ctx.set_socket_state = socket_state; /* client_ctx.sec_obj_inst is 0 as a starting point */ lwm2m_rd_client_start(&client_ctx, endpoint, flags, rd_client_event, observe_cb); diff --git a/samples/net/mdns_responder/overlay-nrf700x.conf b/samples/net/mdns_responder/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/mdns_responder/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_publisher/overlay-nrf700x.conf b/samples/net/mqtt_publisher/overlay-nrf700x.conf new file mode 100644 index 00000000000..a812c7896f6 --- /dev/null +++ b/samples/net/mqtt_publisher/overlay-nrf700x.conf @@ -0,0 +1,19 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf new file mode 100644 index 00000000000..cbc47b96572 --- /dev/null +++ b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_client/overlay-nrf700x.conf b/samples/net/sockets/coap_client/overlay-nrf700x.conf new file mode 100644 index 00000000000..a0e436e3537 --- /dev/null +++ b/samples/net/sockets/coap_client/overlay-nrf700x.conf @@ -0,0 +1,16 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_server/overlay-nrf700x.conf b/samples/net/sockets/coap_server/overlay-nrf700x.conf new file mode 100644 index 00000000000..4817a4f73ba --- /dev/null +++ b/samples/net/sockets/coap_server/overlay-nrf700x.conf @@ -0,0 +1,26 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# The sample can run either IPv4 or IPv6, not both +CONFIG_NET_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_CONFIG_NEED_IPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_server/prj.conf b/samples/net/sockets/coap_server/prj.conf index 1a26e614786..59d444db456 100644 --- a/samples/net/sockets/coap_server/prj.conf +++ b/samples/net/sockets/coap_server/prj.conf @@ -13,7 +13,6 @@ 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 @@ -30,6 +29,11 @@ CONFIG_COAP_SERVER_SHELL=y # Configuration CONFIG_NET_CONFIG_SETTINGS=y +# Events +CONFIG_NET_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y + # Enable only one protocol, if you enable both sources # won't compile. # IPv6 Support diff --git a/samples/net/sockets/coap_server/src/core.c b/samples/net/sockets/coap_server/src/core.c index 276ab0d5de1..00f4adb4d34 100644 --- a/samples/net/sockets/coap_server/src/core.c +++ b/samples/net/sockets/coap_server/src/core.c @@ -45,7 +45,7 @@ static int core_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/events.c b/samples/net/sockets/coap_server/src/events.c new file mode 100644 index 00000000000..3f843fba017 --- /dev/null +++ b/samples/net/sockets/coap_server/src/events.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2023 Basalte bv + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_coap_service_sample); + +#include +#include + +#define COAP_EVENTS_SET (NET_EVENT_COAP_OBSERVER_ADDED | NET_EVENT_COAP_OBSERVER_REMOVED | \ + NET_EVENT_COAP_SERVICE_STARTED | NET_EVENT_COAP_SERVICE_STOPPED) + +void coap_event_handler(uint32_t mgmt_event, struct net_if *iface, + void *info, size_t info_length, void *user_data) +{ + ARG_UNUSED(iface); + ARG_UNUSED(user_data); + + switch (mgmt_event) { + case NET_EVENT_COAP_OBSERVER_ADDED: + LOG_INF("CoAP observer added"); + break; + case NET_EVENT_COAP_OBSERVER_REMOVED: + LOG_INF("CoAP observer removed"); + break; + case NET_EVENT_COAP_SERVICE_STARTED: + if (info != NULL && info_length == sizeof(struct net_event_coap_service)) { + struct net_event_coap_service *net_event = info; + + LOG_INF("CoAP service %s started", net_event->service->name); + } else { + LOG_INF("CoAP service started"); + } + break; + case NET_EVENT_COAP_SERVICE_STOPPED: + if (info != NULL && info_length == sizeof(struct net_event_coap_service)) { + struct net_event_coap_service *net_event = info; + + LOG_INF("CoAP service %s stopped", net_event->service->name); + } else { + LOG_INF("CoAP service stopped"); + } + break; + } +} + +NET_MGMT_REGISTER_EVENT_HANDLER(coap_events, COAP_EVENTS_SET, coap_event_handler, NULL); diff --git a/samples/net/sockets/coap_server/src/large.c b/samples/net/sockets/coap_server/src/large.c index 28a3eebe099..8656a5b53b1 100644 --- a/samples/net/sockets/coap_server/src/large.c +++ b/samples/net/sockets/coap_server/src/large.c @@ -87,7 +87,7 @@ static int large_get(struct coap_resource *resource, memset(&ctx, 0, sizeof(ctx)); } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -167,7 +167,7 @@ static int large_update_put(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -239,7 +239,7 @@ static int large_create_post(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/location_query.c b/samples/net/sockets/coap_server/src/location_query.c index b13079bc456..bce4eb67b86 100644 --- a/samples/net/sockets/coap_server/src/location_query.c +++ b/samples/net/sockets/coap_server/src/location_query.c @@ -59,7 +59,7 @@ static int location_query_post(struct coap_resource *resource, } } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/observer.c b/samples/net/sockets/coap_server/src/observer.c index 29b7b4ed472..8a14d316c61 100644 --- a/samples/net/sockets/coap_server/src/observer.c +++ b/samples/net/sockets/coap_server/src/observer.c @@ -17,16 +17,6 @@ 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, @@ -90,7 +80,7 @@ static int send_notification_packet(struct coap_resource *resource, k_work_reschedule(&obs_work, K_SECONDS(5)); - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -138,9 +128,6 @@ 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) diff --git a/samples/net/sockets/coap_server/src/query.c b/samples/net/sockets/coap_server/src/query.c index 10479b1e6f1..95272189d9c 100644 --- a/samples/net/sockets/coap_server/src/query.c +++ b/samples/net/sockets/coap_server/src/query.c @@ -89,7 +89,7 @@ static int query_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/separate.c b/samples/net/sockets/coap_server/src/separate.c index c3f6f6c256e..68bba0bb473 100644 --- a/samples/net/sockets/coap_server/src/separate.c +++ b/samples/net/sockets/coap_server/src/separate.c @@ -43,7 +43,7 @@ static int separate_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); if (r < 0) { return r; } @@ -86,7 +86,7 @@ static int separate_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/coap_server/src/test.c b/samples/net/sockets/coap_server/src/test.c index aa496a125b1..52885b31a5d 100644 --- a/samples/net/sockets/coap_server/src/test.c +++ b/samples/net/sockets/coap_server/src/test.c @@ -73,7 +73,7 @@ static int piggyback_get(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -113,7 +113,7 @@ static int test_del(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -160,7 +160,7 @@ static int test_put(struct coap_resource *resource, return r; } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } @@ -221,7 +221,7 @@ static int test_post(struct coap_resource *resource, } } - r = coap_resource_send(resource, &response, addr, addr_len); + r = coap_resource_send(resource, &response, addr, addr_len, NULL); return r; } diff --git a/samples/net/sockets/echo/overlay-nrf700x.conf b/samples/net/sockets/echo/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/sockets/echo/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_async/overlay-nrf700x.conf b/samples/net/sockets/echo_async/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/sockets/echo_async/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_client/overlay-nrf700x.conf b/samples/net/sockets/echo_client/overlay-nrf700x.conf new file mode 100644 index 00000000000..cbc47b96572 --- /dev/null +++ b/samples/net/sockets/echo_client/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_server/overlay-nrf700x.conf b/samples/net/sockets/echo_server/overlay-nrf700x.conf new file mode 100644 index 00000000000..cbc47b96572 --- /dev/null +++ b/samples/net/sockets/echo_server/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/http_get/overlay-nrf700x.conf b/samples/net/sockets/http_get/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/sockets/http_get/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/sntp_client/overlay-nrf700x.conf b/samples/net/sockets/sntp_client/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/sockets/sntp_client/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/syslog_net/overlay-nrf700x.conf b/samples/net/syslog_net/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/syslog_net/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/telnet/overlay-nrf700x.conf b/samples/net/telnet/overlay-nrf700x.conf new file mode 100644 index 00000000000..aa59e5d5ea2 --- /dev/null +++ b/samples/net/telnet/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..3d872a2071b --- /dev/null +++ b/samples/sensor/qdec/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + qdec0 = &qdec20; + qenca = &phase_a; + qencb = &phase_b; + }; + + encoder-emulate { + compatible = "gpio-leds"; + phase_a: phase_a { + gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; + }; + phase_b: phase_b { + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&pinctrl { + qdec_pinctrl: qdec_pinctrl { + group1 { + psels = , + ; + }; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&qdec20 { + status = "okay"; + pinctrl-0 = <&qdec_pinctrl>; + pinctrl-names = "default"; + steps = <120>; + led-pre = <500>; +}; 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/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 = { 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.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}) 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/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf new file mode 100644 index 00000000000..98260877332 --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf new file mode 100644 index 00000000000..98260877332 --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sysbuild/hci_rpmsg.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 diff --git a/samples/subsys/usb/mass/CMakeLists.txt b/samples/subsys/usb/mass/CMakeLists.txt index ef71596104d..2ac19d9b016 100644 --- a/samples/subsys/usb/mass/CMakeLists.txt +++ b/samples/subsys/usb/mass/CMakeLists.txt @@ -15,6 +15,6 @@ target_sources(app PRIVATE ${app_sources}) if(CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/samples/tfm_integration/psa_crypto/CMakeLists.txt b/samples/tfm_integration/psa_crypto/CMakeLists.txt index 17339b470b8..f8ef1eca23f 100644 --- a/samples/tfm_integration/psa_crypto/CMakeLists.txt +++ b/samples/tfm_integration/psa_crypto/CMakeLists.txt @@ -16,7 +16,7 @@ target_sources(app PRIVATE src/util_app_log.c) target_sources(app PRIVATE src/util_sformat.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) # In TF-M, default value of CRYPTO_ENGINE_BUF_SIZE is 0x2080. It causes diff --git a/samples/tfm_integration/psa_protected_storage/CMakeLists.txt b/samples/tfm_integration/psa_protected_storage/CMakeLists.txt index bbb8a2041fd..dfb0169eda6 100644 --- a/samples/tfm_integration/psa_protected_storage/CMakeLists.txt +++ b/samples/tfm_integration/psa_protected_storage/CMakeLists.txt @@ -13,5 +13,5 @@ project(protected_storage) target_sources(app PRIVATE src/main.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) diff --git a/samples/tfm_integration/tfm_ipc/CMakeLists.txt b/samples/tfm_integration/tfm_ipc/CMakeLists.txt index f11b67af843..896af7bfbda 100644 --- a/samples/tfm_integration/tfm_ipc/CMakeLists.txt +++ b/samples/tfm_integration/tfm_ipc/CMakeLists.txt @@ -9,5 +9,5 @@ project(tfm_ipc) target_sources(app PRIVATE src/main.c) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) diff --git a/samples/tfm_integration/tfm_ipc/src/main.c b/samples/tfm_integration/tfm_ipc/src/main.c index 7179705cbe3..133c7203b0e 100644 --- a/samples/tfm_integration/tfm_ipc/src/main.c +++ b/samples/tfm_integration/tfm_ipc/src/main.c @@ -7,7 +7,6 @@ #include #include -#include "tfm_api.h" #include "tfm_ns_interface.h" #ifdef TFM_PSA_API #include "psa_manifest/sid.h" diff --git a/samples/tfm_integration/tfm_psa_test/CMakeLists.txt b/samples/tfm_integration/tfm_psa_test/CMakeLists.txt index 9dcbf12ae64..0d11c021627 100644 --- a/samples/tfm_integration/tfm_psa_test/CMakeLists.txt +++ b/samples/tfm_integration/tfm_psa_test/CMakeLists.txt @@ -8,10 +8,103 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(tfm_psa_storage_test) +project(tfm_psa_arch_test) target_sources(app PRIVATE src/main.c) -target_include_directories(app PRIVATE - $/install/interface/include +get_target_property(TFM_BINARY_DIR tfm TFM_BINARY_DIR) +get_target_property(TFM_NS_BIN_FILE tfm TFM_NS_BIN_FILE) +get_target_property(TFM_NS_HEX_FILE tfm TFM_NS_HEX_FILE) +get_target_property(TFM_NS_SIGNED_BIN_FILE tfm TFM_NS_SIGNED_BIN_FILE) + +get_target_property(TFM_TOOLCHAIN_PATH tfm TFM_TOOLCHAIN_PATH) +get_target_property(TFM_TOOLCHAIN_PREFIX tfm TFM_TOOLCHAIN_PREFIX) +get_target_property(TFM_TOOLCHAIN_NS_FILE tfm TFM_TOOLCHAIN_NS_FILE) + +set(TFM_TEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../tf-m-tests) +set(TFM_PSA_ARCHTEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../psa-arch-tests) + +if (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION AND CONFIG_TFM_QCBOR_PATH STREQUAL "") +# TODO: Remove this when QCBOR licensing issues w/t_cose have been resolved, +# or only allow it when 'QCBOR_PATH' is set to a local path where QCBOR has +# been manually downloaded by the user before starting the build. +message(FATAL_ERROR "CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION is not available " + "with TF-M 2.0.0 due to licensing issues with a dependent library. This " + "restriction will be removed once licensing issues have been resolved." + ) +endif() + + +set(TFM_TEST_DIR "${TFM_TEST_REPO_PATH}/tests_psa_arch/spe/partitions") +set(PSA_ARCH_TESTS_CONFIG_FILE "${TFM_TEST_REPO_PATH}/tests_psa_arch/spe/config/config_test_psa_api.cmake") +if (CONFIG_TFM_PSA_TEST_CRYPTO) +set(TFM_PSA_TEST_SUITE CRYPTO) +elseif (CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE) +set(TFM_PSA_TEST_SUITE PROTECTED_STORAGE) +elseif (CONFIG_TFM_PSA_TEST_INTERNAL_TRUSTED_STORAGE) +set(TFM_PSA_TEST_SUITE INTERNAL_TRUSTED_STORAGE) +elseif (CONFIG_TFM_PSA_TEST_STORAGE) +set(TFM_PSA_TEST_SUITE STORAGE) +elseif (CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION) +set(TFM_PSA_TEST_SUITE INITIAL_ATTESTATION) +endif() + +if (NOT DEFINED TFM_PSA_TEST_SUITE) + message(FATAL_ERROR "Please define witch test suite to run: + CONFIG_TFM_PSA_TEST_CRYPTO + CONFIG_TFM_PSA_TEST_PROTECTED_STORAGE + CONFIG_TFM_PSA_TEST_STORAGE + CONFIG_TFM_PSA_TEST_INITIAL_ATTESTATION") +endif() +set(TEST_PSA_API "${TFM_PSA_TEST_SUITE}") + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DPSA_ARCH_TESTS_PATH=${TFM_PSA_ARCHTEST_REPO_PATH} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_DIR=${TFM_TEST_DIR} ) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_PSA_ARCH_TESTS_CONFIG_FILE=${PSA_ARCH_TESTS_CONFIG_FILE} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DTEST_PSA_API=${TEST_PSA_API} +) + +include(ExternalProject) + +ExternalProject_Add(tfm_psa_arch_test_app + SOURCE_DIR ${TFM_TEST_REPO_PATH}/tests_psa_arch + BINARY_DIR ${PROJECT_BINARY_DIR}/tfm_ns + CONFIGURE_COMMAND + ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} + -S ${TFM_TEST_REPO_PATH}/tests_psa_arch + -B ${PROJECT_BINARY_DIR}/tfm_ns + -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX} + -DPSA_TOOLCHAIN_FILE=${TFM_BINARY_DIR}/api_ns/cmake/${TFM_TOOLCHAIN_NS_FILE} + -DCONFIG_SPE_PATH=${TFM_BINARY_DIR}/api_ns + -DTFM_TOOLCHAIN_FILE=cmake/${TFM_TOOLCHAIN_NS_FILE} + -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH} + -DCMAKE_BUILD_TYPE=RelWithDebInfo + -DTEST_PSA_API=${TEST_PSA_API} + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tfm_ns + DEPENDS tfm + BUILD_BYPRODUCTS + ${TFM_NS_HEX_FILE} + ${TFM_NS_BIN_FILE} + ${TFM_NS_SIGNED_BIN_FILE} +) + +add_dependencies(app tfm_psa_arch_test_app) diff --git a/samples/tfm_integration/tfm_psa_test/prj.conf b/samples/tfm_integration/tfm_psa_test/prj.conf index 3ceca574528..bab1254229d 100644 --- a/samples/tfm_integration/tfm_psa_test/prj.conf +++ b/samples/tfm_integration/tfm_psa_test/prj.conf @@ -5,9 +5,10 @@ # CONFIG_BUILD_WITH_TFM=y -CONFIG_TFM_BUILD_NS=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y +CONFIG_TFM_USE_NS_APP=y CONFIG_QEMU_ICOUNT_SHIFT=1 + # Needed for CRYPTO and INITIAL_ATTESTATION CONFIG_MAIN_STACK_SIZE=4096 diff --git a/samples/tfm_integration/tfm_psa_test/src/main.c b/samples/tfm_integration/tfm_psa_test/src/main.c index 232fc505cfd..9d2809fe269 100644 --- a/samples/tfm_integration/tfm_psa_test/src/main.c +++ b/samples/tfm_integration/tfm_psa_test/src/main.c @@ -1,21 +1,15 @@ /* - * Copyright (c) 2021 Nordic Semiconductor ASA. + * Copyright (c) 2023 Nordic Semiconductor ASA. * * SPDX-License-Identifier: Apache-2.0 */ #include -/* Run the PSA test suite */ -void psa_test(void); - int main(void) { -#ifdef CONFIG_TFM_PSA_TEST_NONE - #error "No PSA test suite set. Use Kconfig to enable a test suite.\n" -#else - psa_test(); -#endif + printk("Should not be printed, expected TF-M's NS application to be run instead.\n"); + k_panic(); for (;;) { } diff --git a/samples/tfm_integration/tfm_regression_test/CMakeLists.txt b/samples/tfm_integration/tfm_regression_test/CMakeLists.txt index 5f34b1c0b26..b86eebc4a81 100644 --- a/samples/tfm_integration/tfm_regression_test/CMakeLists.txt +++ b/samples/tfm_integration/tfm_regression_test/CMakeLists.txt @@ -11,3 +11,56 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(tfm_regression_test) target_sources(app PRIVATE src/main.c) + +get_target_property(TFM_BINARY_DIR tfm TFM_BINARY_DIR) +get_target_property(TFM_NS_BIN_FILE tfm TFM_NS_BIN_FILE) +get_target_property(TFM_NS_HEX_FILE tfm TFM_NS_HEX_FILE) +get_target_property(TFM_NS_SIGNED_BIN_FILE tfm TFM_NS_SIGNED_BIN_FILE) + +get_target_property(TFM_TOOLCHAIN_PATH tfm TFM_TOOLCHAIN_PATH) +get_target_property(TFM_TOOLCHAIN_PREFIX tfm TFM_TOOLCHAIN_PREFIX) +get_target_property(TFM_TOOLCHAIN_NS_FILE tfm TFM_TOOLCHAIN_NS_FILE) + +set(TFM_TEST_REPO_PATH ${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/../tf-m-tests) + +set(TFM_TEST_DIR "${TFM_TEST_REPO_PATH}/tests_reg/test/secure_regression") +set(TFM_TEST_CONFIG_FILE "${TFM_TEST_REPO_PATH}/tests_reg/test/config/config.cmake") + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_DIR=${TFM_TEST_DIR} +) + +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS + -DCONFIG_TFM_TEST_CONFIG_FILE=${TFM_TEST_CONFIG_FILE} +) + +include(ExternalProject) + +ExternalProject_Add(tfm_regression_test_app + SOURCE_DIR ${TFM_TEST_REPO_PATH}/tests_reg + BINARY_DIR ${PROJECT_BINARY_DIR}/tfm_ns + CONFIGURE_COMMAND + ${CMAKE_COMMAND} + -G ${CMAKE_GENERATOR} + -S ${TFM_TEST_REPO_PATH}/tests_reg + -B ${PROJECT_BINARY_DIR}/tfm_ns + -DCONFIG_SPE_PATH=${TFM_BINARY_DIR}/api_ns + -DTFM_TOOLCHAIN_FILE=cmake/${TFM_TOOLCHAIN_NS_FILE} + -DCROSS_COMPILE=${TFM_TOOLCHAIN_PATH}/${TFM_TOOLCHAIN_PREFIX} + -DQCBOR_PATH${QCBOR_PATH_TYPE}=${CONFIG_TFM_QCBOR_PATH} + -DCMAKE_BUILD_TYPE=RelWithDebInfo + BUILD_COMMAND ${CMAKE_COMMAND} --build . + INSTALL_COMMAND "" + BUILD_ALWAYS True + USES_TERMINAL_BUILD True + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tfm_ns + DEPENDS tfm + BUILD_BYPRODUCTS + ${TFM_NS_HEX_FILE} + ${TFM_NS_BIN_FILE} + ${TFM_NS_SIGNED_BIN_FILE} +) + +add_dependencies(app tfm_regression_test_app) diff --git a/samples/tfm_integration/tfm_regression_test/prj.conf b/samples/tfm_integration/tfm_regression_test/prj.conf index 6817a7f717b..0a6573f811c 100644 --- a/samples/tfm_integration/tfm_regression_test/prj.conf +++ b/samples/tfm_integration/tfm_regression_test/prj.conf @@ -6,7 +6,6 @@ CONFIG_BUILD_WITH_TFM=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y -CONFIG_TFM_BUILD_NS=y CONFIG_TFM_USE_NS_APP=y CONFIG_TFM_REGRESSION_S=y CONFIG_TFM_REGRESSION_NS=y diff --git a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt index 69901f73928..beadae9230a 100644 --- a/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt +++ b/samples/tfm_integration/tfm_secure_partition/CMakeLists.txt @@ -28,7 +28,7 @@ target_sources(app PRIVATE ) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) target_compile_definitions(app diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt b/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt index 0e335a73028..013332ccb1a 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/CMakeLists.txt @@ -50,7 +50,7 @@ target_link_libraries(tfm_partitions tfm_app_rot_partition_dp ) -target_compile_definitions(tfm_partition_defs +target_compile_definitions(tfm_config INTERFACE TFM_PARTITION_DUMMY_PARTITION ) diff --git a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c index 6519723058c..d618868ddbf 100644 --- a/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c +++ b/samples/tfm_integration/tfm_secure_partition/dummy_partition/dummy_partition.c @@ -7,7 +7,6 @@ #include #include #include -#include "tfm_api.h" #include "psa/service.h" #include "psa_manifest/tfm_dummy_partition.h" diff --git a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h index b31ce897d27..7ca52b3c5c4 100644 --- a/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h +++ b/samples/tfm_integration/tfm_secure_partition/src/dummy_partition.h @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include "tfm_api.h" - psa_status_t dp_secret_digest(uint32_t secret_index, void *p_digest, size_t digest_size); diff --git a/scripts/build/gen_isr_tables.py b/scripts/build/gen_isr_tables.py index cd329f85551..84812d708e8 100755 --- a/scripts/build/gen_isr_tables.py +++ b/scripts/build/gen_isr_tables.py @@ -2,118 +2,280 @@ # # Copyright (c) 2017 Intel Corporation # Copyright (c) 2018 Foundries.io +# Copyright (c) 2023 Nordic Semiconductor NA # # SPDX-License-Identifier: Apache-2.0 # import argparse -import struct import sys import os +import importlib from elftools.elf.elffile import ELFFile from elftools.elf.sections import SymbolTableSection -ISR_FLAG_DIRECT = 1 << 0 - -# The below few hardware independent magic numbers represent various -# levels of interrupts in a multi-level interrupt system. -# 0x000000FF - represents the 1st level (i.e. the interrupts -# that directly go to the processor). -# 0x0000FF00 - represents the 2nd level (i.e. the interrupts funnel -# into 1 line which then goes into the 1st level) -# 0x00FF0000 - represents the 3rd level (i.e. the interrupts funnel -# into 1 line which then goes into the 2nd level) -FIRST_LVL_INTERRUPTS = 0x000000FF -SECND_LVL_INTERRUPTS = 0x0000FF00 -THIRD_LVL_INTERRUPTS = 0x00FF0000 - -INTERRUPT_BITS = [8, 8, 8] - -def debug(text): - if args.debug: - sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n") - -def error(text): - sys.exit(os.path.basename(sys.argv[0]) + ": error: " + text + "\n") - -def endian_prefix(): - if args.big_endian: - return ">" - else: - return "<" - -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: - - struct { - uint32_t num_vectors; <- typically CONFIG_NUM_IRQS - struct _isr_list isrs[]; <- Usually of smaller size than num_vectors - } - - Followed by instances of struct _isr_list created by IRQ_CONNECT() - calls: - - struct _isr_list { - /** IRQ line number */ - int32_t irq; - /** Flags for this IRQ, see ISR_FLAG_* definitions */ - int32_t flags; - /** ISR to call */ - void *func; - /** Parameter for non-direct IRQs */ - const void *param; - }; - """ - intList_sect = None - intlist = {} - prefix = endian_prefix() +class gen_isr_log: - intlist_header_fmt = prefix + "II" - if "CONFIG_64BIT" in syms: - intlist_entry_fmt = prefix + "iiQQ" - else: - intlist_entry_fmt = prefix + "iiII" + def __init__(self, debug = False): + self.__debug = debug - 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 + def debug(self, text): + """Print debug message if debugging is enabled. - if intList_sect is None: - error("Cannot find the intlist section!") + Note - this function requires config global variable to be initialized. + """ + if self.__debug: + sys.stdout.write(os.path.basename(sys.argv[0]) + ": " + text + "\n") - intdata = intList_sect.data() + @staticmethod + def error(text): + sys.exit(os.path.basename(sys.argv[0]) + ": error: " + text + "\n") - header_sz = struct.calcsize(intlist_header_fmt) - header = struct.unpack_from(intlist_header_fmt, intdata, 0) - intdata = intdata[header_sz:] + def set_debug(self, state): + self.__debug = state - debug(str(header)) - intlist["num_vectors"] = header[0] - intlist["offset"] = header[1] +log = gen_isr_log() - intlist["interrupts"] = [i for i in - struct.iter_unpack(intlist_entry_fmt, intdata)] - debug("Configured interrupt routing") - debug("handler irq flags param") - debug("--------------------------") +class gen_isr_config: + """All the constants and configuration gathered in single class for readability. + """ + # Constants + __ISR_FLAG_DIRECT = 1 << 0 + __swt_spurious_handler = "z_irq_spurious" + __swt_shared_handler = "z_shared_isr" + __vt_spurious_handler = "z_irq_spurious" + __vt_irq_handler = "_isr_wrapper" + __shared_array_name = "z_shared_sw_isr_table" + __sw_isr_array_name = "_sw_isr_table" + __irq_vector_array_name = "_irq_vector_table" + + @staticmethod + def __bm(bits): + return (1 << bits) - 1 + + def __init__(self, args, syms, log): + """Initialize the configuration object. + + The configuration object initialization takes only arguments as a parameter. + This is done to allow debug function work as soon as possible. + """ + # Store the arguments required for work + self.__args = args + self.__syms = syms + self.__log = log + + # Select the default interrupt vector handler + if self.args.sw_isr_table: + self.__vt_default_handler = self.__vt_irq_handler + else: + self.__vt_default_handler = self.__vt_spurious_handler + # Calculate interrupt bits + self.__int_bits = [8, 8, 8] + # The below few hardware independent magic numbers represent various + # levels of interrupts in a multi-level interrupt system. + # 0x000000FF - represents the 1st level (i.e. the interrupts + # that directly go to the processor). + # 0x0000FF00 - represents the 2nd level (i.e. the interrupts funnel + # into 1 line which then goes into the 1st level) + # 0x00FF0000 - represents the 3rd level (i.e. the interrupts funnel + # into 1 line which then goes into the 2nd level) + self.__int_lvl_masks = [0x000000FF, 0x0000FF00, 0x00FF0000] + + self.__irq2_baseoffset = None + self.__irq3_baseoffset = None + self.__irq2_offsets = None + self.__irq3_offsets = None + + if self.check_multi_level_interrupts(): + self.__max_irq_per = self.get_sym("CONFIG_MAX_IRQ_PER_AGGREGATOR") + + self.__int_bits[0] = self.get_sym("CONFIG_1ST_LEVEL_INTERRUPT_BITS") + self.__int_bits[1] = self.get_sym("CONFIG_2ND_LEVEL_INTERRUPT_BITS") + self.__int_bits[2] = self.get_sym("CONFIG_3RD_LEVEL_INTERRUPT_BITS") + + if sum(self.int_bits) > 32: + raise ValueError("Too many interrupt bits") + + self.__int_lvl_masks[0] = self.__bm(self.int_bits[0]) + self.__int_lvl_masks[1] = self.__bm(self.int_bits[1]) << self.int_bits[0] + self.__int_lvl_masks[2] = self.__bm(self.int_bits[2]) << (self.int_bits[0] + self.int_bits[1]) + + self.__log.debug("Level Bits Bitmask") + self.__log.debug("----------------------------") + for i in range(3): + bitmask_str = "0x" + format(self.__int_lvl_masks[i], '08X') + self.__log.debug(f"{i + 1:>5} {self.__int_bits[i]:>7} {bitmask_str:>14}") + + if self.check_sym("CONFIG_2ND_LEVEL_INTERRUPTS"): + num_aggregators = self.get_sym("CONFIG_NUM_2ND_LEVEL_AGGREGATORS") + self.__irq2_baseoffset = self.get_sym("CONFIG_2ND_LVL_ISR_TBL_OFFSET") + self.__irq2_offsets = [self.get_sym('CONFIG_2ND_LVL_INTR_{}_OFFSET'. + format(str(i).zfill(2))) for i in + range(num_aggregators)] + + self.__log.debug('2nd level offsets: {}'.format(self.__irq2_offsets)) + + if self.check_sym("CONFIG_3RD_LEVEL_INTERRUPTS"): + num_aggregators = self.get_sym("CONFIG_NUM_3RD_LEVEL_AGGREGATORS") + self.__irq3_baseoffset = self.get_sym("CONFIG_3RD_LVL_ISR_TBL_OFFSET") + self.__irq3_offsets = [self.get_sym('CONFIG_3RD_LVL_INTR_{}_OFFSET'. + format(str(i).zfill(2))) for i in + range(num_aggregators)] + + self.__log.debug('3rd level offsets: {}'.format(self.__irq3_offsets)) + + @property + def args(self): + return self.__args + + @property + def swt_spurious_handler(self): + return self.__swt_spurious_handler + + @property + def swt_shared_handler(self): + return self.__swt_shared_handler + + @property + def vt_default_handler(self): + return self.__vt_default_handler + + @property + def shared_array_name(self): + return self.__shared_array_name + + @property + def sw_isr_array_name(self): + return self.__sw_isr_array_name + + @property + def irq_vector_array_name(self): + return self.__irq_vector_array_name + + @property + def int_bits(self): + return self.__int_bits + + @property + def int_lvl_masks(self): + return self.__int_lvl_masks + + def endian_prefix(self): + if self.args.big_endian: + return ">" + else: + return "<" + + def get_irq_baseoffset(self, lvl): + if lvl == 2: + return self.__irq2_baseoffset + if lvl == 3: + return self.__irq3_baseoffset + self.__log.error("Unsupported irq level: {}".format(lvl)) + + def get_irq_index(self, irq, lvl): + if lvl == 2: + offsets = self.__irq2_offsets + elif lvl == 3: + offsets = self.__irq3_offsets + else: + self.__log.error("Unsupported irq level: {}".format(lvl)) + try: + return offsets.index(irq) + except ValueError: + self.__log.error("IRQ {} not present in parent offsets ({}). ". + format(irq, offsets) + + " Recheck interrupt configuration.") + + def get_swt_table_index(self, offset, irq): + if not self.check_multi_level_interrupts(): + return irq - offset + # Calculate index for multi level interrupts + self.__log.debug('IRQ = ' + hex(irq)) + irq3 = (irq & self.int_lvl_masks[2]) >> (self.int_bits[0] + self.int_bits[1]) + irq2 = (irq & self.int_lvl_masks[1]) >> (self.int_bits[0]) + irq1 = irq & self.int_lvl_masks[0] + # Figure out third level interrupt position + if irq3: + list_index = self.get_irq_index(irq2, 3) + irq3_pos = self.get_irq_baseoffset(3) + self.__max_irq_per * list_index + irq3 - 1 + self.__log.debug('IRQ_level = 3') + self.__log.debug('IRQ_Indx = ' + str(irq3)) + self.__log.debug('IRQ_Pos = ' + str(irq3_pos)) + return irq3_pos - offset + # Figure out second level interrupt position + if irq2: + list_index = self.get_irq_index(irq1, 2) + irq2_pos = self.get_irq_baseoffset(2) + self.__max_irq_per * list_index + irq2 - 1 + self.__log.debug('IRQ_level = 2') + self.__log.debug('IRQ_Indx = ' + str(irq2)) + self.__log.debug('IRQ_Pos = ' + str(irq2_pos)) + return irq2_pos - offset + # Figure out first level interrupt position + self.__log.debug('IRQ_level = 1') + self.__log.debug('IRQ_Indx = ' + str(irq1)) + self.__log.debug('IRQ_Pos = ' + str(irq1)) + return irq1 - offset + + def get_intlist_snames(self): + return self.args.intlist_section + + def test_isr_direct(self, flags): + return flags & self.__ISR_FLAG_DIRECT + + def get_sym_from_addr(self, addr): + for key, value in self.__syms.items(): + if addr == value: + return key + return None + + def get_sym(self, name): + return self.__syms.get(name) + + def check_sym(self, name): + return name in self.__syms + + def check_multi_level_interrupts(self): + return self.check_sym("CONFIG_MULTI_LEVEL_INTERRUPTS") + + def check_shared_interrupts(self): + return self.check_sym("CONFIG_SHARED_INTERRUPTS") + + def check_64b(self): + return self.check_sym("CONFIG_64BIT") - for irq in intlist["interrupts"]: - debug("{0:<10} {1:<3} {2:<3} {3}".format( - hex(irq[2]), irq[0], irq[1], hex(irq[3]))) - return intlist +def get_symbols(obj): + for section in obj.iter_sections(): + if isinstance(section, SymbolTableSection): + return {sym.name: sym.entry.st_value + for sym in section.iter_symbols()} + log.error("Could not find symbol table") -def parse_args(): - global args +def read_intList_sect(elfobj, snames): + """ + Load the raw intList section data in a form of byte array. + """ + intList_sect = None + for sname in snames: + intList_sect = elfobj.get_section_by_name(sname) + if intList_sect is not None: + log.debug("Found intlist section: \"{}\"".format(sname)) + break + + if intList_sect is None: + log.error("Cannot find the intlist section!") + + intdata = intList_sect.data() + + return intdata + +def parse_args(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False) @@ -124,6 +286,12 @@ def parse_args(): help="Print additional debugging information") parser.add_argument("-o", "--output-source", required=True, help="Output source file") + parser.add_argument("-l", "--linker-output-files", + nargs=2, + metavar=("vector_table_link", "software_interrupt_link"), + help="Output linker files. " + "Used only if CONFIG_ISR_TABLES_LOCAL_DECLARATION is enabled. " + "In other case empty file would be generated.") parser.add_argument("-k", "--kernel", required=True, help="Zephyr kernel image") parser.add_argument("-s", "--sw-isr-table", action="store_true", @@ -134,313 +302,43 @@ def parse_args(): 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() - -source_assembly_header = """ -#ifndef ARCH_IRQ_VECTOR_JUMP_CODE -#error "ARCH_IRQ_VECTOR_JUMP_CODE not defined" -#endif -""" - -def get_symbol_from_addr(syms, addr): - for key, value in syms.items(): - if addr == value: - return key - return None - -def write_code_irq_vector_table(fp, vt, nv, syms): - fp.write(source_assembly_header) - - fp.write("void __irq_vector_table __attribute__((naked)) _irq_vector_table(void) {\n") - for i in range(nv): - func = vt[i] - - if isinstance(func, int): - func_as_string = get_symbol_from_addr(syms, func) - else: - func_as_string = func - - fp.write("\t__asm(ARCH_IRQ_VECTOR_JUMP_CODE({}));\n".format(func_as_string)) - fp.write("}\n") - -def write_address_irq_vector_table(fp, vt, nv): - fp.write("uintptr_t __irq_vector_table _irq_vector_table[%d] = {\n" % nv) - for i in range(nv): - func = vt[i] - - if isinstance(func, int): - fp.write("\t{},\n".format(vt[i])) - else: - fp.write("\t((uintptr_t)&{}),\n".format(vt[i])) - - fp.write("};\n") - -source_header = """ -/* AUTO-GENERATED by gen_isr_tables.py, do not edit! */ - -#include -#include -#include -#include - -typedef void (* ISR)(const void *); -""" - -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) - elif "CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE" in syms: - write_code_irq_vector_table(fp, vt, nv, syms) - else: - error("CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_{ADDRESS,CODE} not set") - - if not swt: - return - - fp.write("struct _isr_table_entry __sw_isr_table _sw_isr_table[%d] = {\n" - % nv) - - level2_offset = syms.get("CONFIG_2ND_LVL_ISR_TBL_OFFSET") - level3_offset = syms.get("CONFIG_3RD_LVL_ISR_TBL_OFFSET") - - for i in range(nv): - 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: - func_as_string = func - - if level2_offset is not None and i == level2_offset: - fp.write("\t/* Level 2 interrupts start here (offset: {}) */\n". - format(level2_offset)) - if level3_offset is not None and i == level3_offset: - fp.write("\t/* Level 3 interrupts start here (offset: {}) */\n". - format(level3_offset)) - - fp.write("\t{{(const void *){0}, (ISR){1}}},\n".format(param, func_as_string)) - fp.write("};\n") - -def get_symbols(obj): - for section in obj.iter_sections(): - if isinstance(section, SymbolTableSection): - return {sym.name: sym.entry.st_value - for sym in section.iter_symbols()} - - error("Could not find symbol table") - -def getindex(irq, irq_aggregator_pos): - try: - return irq_aggregator_pos.index(irq) - except ValueError: - error("IRQ {} not present in parent offsets ({}). ". - format(irq, irq_aggregator_pos) + - " Recheck interrupt configuration.") - -def bit_mask(bits): - mask = 0 - for _ in range(0, bits): - mask = (mask << 1) | 1 - return mask - -def update_masks(): - global FIRST_LVL_INTERRUPTS - global SECND_LVL_INTERRUPTS - global THIRD_LVL_INTERRUPTS - - if sum(INTERRUPT_BITS) > 32: - raise ValueError("Too many interrupt bits") - - FIRST_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[0]) - SECND_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[1]) << INTERRUPT_BITS[0] - THIRD_LVL_INTERRUPTS = bit_mask(INTERRUPT_BITS[2]) << INTERRUPT_BITS[0] + INTERRUPT_BITS[2] + return parser.parse_args() def main(): - parse_args() + args = parse_args() + # Configure logging as soon as possible + log.set_debug(args.debug) 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"] - - INTERRUPT_BITS[0] = syms["CONFIG_1ST_LEVEL_INTERRUPT_BITS"] - INTERRUPT_BITS[1] = syms["CONFIG_2ND_LEVEL_INTERRUPT_BITS"] - INTERRUPT_BITS[2] = syms["CONFIG_3RD_LEVEL_INTERRUPT_BITS"] - update_masks() - - if "CONFIG_2ND_LEVEL_INTERRUPTS" in syms: - num_aggregators = syms["CONFIG_NUM_2ND_LEVEL_AGGREGATORS"] - irq2_baseoffset = syms["CONFIG_2ND_LVL_ISR_TBL_OFFSET"] - list_2nd_lvl_offsets = [syms['CONFIG_2ND_LVL_INTR_{}_OFFSET'. - format(str(i).zfill(2))] for i in - range(num_aggregators)] - - debug('2nd level offsets: {}'.format(list_2nd_lvl_offsets)) - - if "CONFIG_3RD_LEVEL_INTERRUPTS" in syms: - num_aggregators = syms["CONFIG_NUM_3RD_LEVEL_AGGREGATORS"] - irq3_baseoffset = syms["CONFIG_3RD_LVL_ISR_TBL_OFFSET"] - list_3rd_lvl_offsets = [syms['CONFIG_3RD_LVL_INTR_{}_OFFSET'. - format(str(i).zfill(2))] for i in - range(num_aggregators)] - - debug('3rd level offsets: {}'.format(list_3rd_lvl_offsets)) - - nvec = intlist["num_vectors"] - offset = intlist["offset"] - - if nvec > pow(2, 15): - 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" - - debug('offset is ' + str(offset)) - debug('num_vectors is ' + str(nvec)) - - # Set default entries in both tables - if args.sw_isr_table: - # All vectors just jump to the common vt_irq_handler. If some entries - # are used for direct interrupts, they will be replaced later. - if args.vector_table: - vt = [vt_irq_handler for i in range(nvec)] - else: - vt = None - # 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)] - else: - error("one or both of -s or -V needs to be specified on command line") - swt = None - - for irq, flags, func, param in intlist["interrupts"]: - if flags & ISR_FLAG_DIRECT: - if param != 0: - error("Direct irq %d declared, but has non-NULL parameter" - % irq) - if not 0 <= irq - offset < len(vt): - error("IRQ %d (offset=%d) exceeds the maximum of %d" % - (irq - offset, offset, len(vt) - 1)) - vt[irq - offset] = func + config = gen_isr_config(args, get_symbols(kernel), log) + intlist_data = read_intList_sect(kernel, config.get_intlist_snames()) + + if config.check_sym("CONFIG_ISR_TABLES_LOCAL_DECLARATION"): + sys.stdout.write( + "Warning: The EXPERIMENTAL ISR_TABLES_LOCAL_DECLARATION feature selected\n") + parser_module = importlib.import_module('gen_isr_tables_parser_local') + parser = parser_module.gen_isr_parser(intlist_data, config, log) else: - # Regular interrupt - if not swt: - error("Regular Interrupt %d declared with parameter 0x%x " - "but no SW ISR_TABLE in use" - % (irq, param)) - - if not "CONFIG_MULTI_LEVEL_INTERRUPTS" in syms: - table_index = irq - offset - else: - # Figure out third level interrupt position - debug('IRQ = ' + hex(irq)) - irq3 = (irq & THIRD_LVL_INTERRUPTS) >> INTERRUPT_BITS[0] + INTERRUPT_BITS[1] - irq2 = (irq & SECND_LVL_INTERRUPTS) >> INTERRUPT_BITS[0] - irq1 = irq & FIRST_LVL_INTERRUPTS - - if irq3: - irq_parent = irq2 - list_index = getindex(irq_parent, list_3rd_lvl_offsets) - irq3_pos = irq3_baseoffset + max_irq_per*list_index + irq3 - 1 - debug('IRQ_level = 3') - debug('IRQ_Indx = ' + str(irq3)) - debug('IRQ_Pos = ' + str(irq3_pos)) - table_index = irq3_pos - offset - - # Figure out second level interrupt position - elif irq2: - irq_parent = irq1 - list_index = getindex(irq_parent, list_2nd_lvl_offsets) - irq2_pos = irq2_baseoffset + max_irq_per*list_index + irq2 - 1 - debug('IRQ_level = 2') - debug('IRQ_Indx = ' + str(irq2)) - debug('IRQ_Pos = ' + str(irq2_pos)) - table_index = irq2_pos - offset - - # Figure out first level interrupt position - else: - debug('IRQ_level = 1') - debug('IRQ_Indx = ' + str(irq1)) - debug('IRQ_Pos = ' + str(irq1)) - table_index = irq1 - offset - - if not 0 <= table_index < len(swt): - error("IRQ %d (offset=%d) exceeds the maximum of %d" % - (table_index, offset, len(swt) - 1)) - 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) + parser_module = importlib.import_module('gen_isr_tables_parser_carrays') + parser = parser_module.gen_isr_parser(intlist_data, config, log) with open(args.output_source, "w") as fp: - write_source_file(fp, vt, swt, intlist, syms, shared) + parser.write_source(fp) + + if args.linker_output_files is not None: + with open(args.linker_output_files[0], "w") as fp_vt, \ + open(args.linker_output_files[1], "w") as fp_swi: + if hasattr(parser, 'write_linker_vt'): + parser.write_linker_vt(fp_vt) + else: + log.debug("Chosen parser does not support vector table linker file") + fp_vt.write('/* Empty */\n') + if hasattr(parser, 'write_linker_swi'): + parser.write_linker_swi(fp_swi) + else: + log.debug("Chosen parser does not support software interrupt linker file") + fp_swi.write('/* Empty */\n') if __name__ == "__main__": main() diff --git a/scripts/build/gen_isr_tables_parser_carrays.py b/scripts/build/gen_isr_tables_parser_carrays.py new file mode 100644 index 00000000000..e13ef19c1f8 --- /dev/null +++ b/scripts/build/gen_isr_tables_parser_carrays.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2017 Intel Corporation +# Copyright (c) 2018 Foundries.io +# Copyright (c) 2023 Nordic Semiconductor NA +# +# SPDX-License-Identifier: Apache-2.0 +# + +import struct + +class gen_isr_parser: + source_header = """ +/* AUTO-GENERATED by gen_isr_tables.py, do not edit! */ + +#include +#include +#include +#include + +typedef void (* ISR)(const void *); +""" + + source_assembly_header = """ +#ifndef ARCH_IRQ_VECTOR_JUMP_CODE +#error "ARCH_IRQ_VECTOR_JUMP_CODE not defined" +#endif +""" + + def __init__(self, intlist_data, config, log): + """Initialize the parser. + + The function prepares parser to work. + Parameters: + - intlist_data: The binnary data from intlist section + - config: The configuration object + - log: The logging object, has to have error and debug methods + """ + self.__config = config + self.__log = log + intlist = self.__read_intlist(intlist_data) + self.__vt, self.__swt, self.__nv = self.__parse_intlist(intlist) + + def __read_intlist(self, intlist_data): + """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: + + struct { + uint32_t num_vectors; <- typically CONFIG_NUM_IRQS + struct _isr_list isrs[]; <- Usually of smaller size than num_vectors + } + + Followed by instances of struct _isr_list created by IRQ_CONNECT() + calls: + + struct _isr_list { + /** IRQ line number */ + int32_t irq; + /** Flags for this IRQ, see ISR_FLAG_* definitions */ + int32_t flags; + /** ISR to call */ + void *func; + /** Parameter for non-direct IRQs */ + const void *param; + }; + """ + intlist = {} + prefix = self.__config.endian_prefix() + + # Extract header and the rest of the data + intlist_header_fmt = prefix + "II" + header_sz = struct.calcsize(intlist_header_fmt) + header_raw = struct.unpack_from(intlist_header_fmt, intlist_data, 0) + self.__log.debug(str(header_raw)) + + intlist["num_vectors"] = header_raw[0] + intlist["offset"] = header_raw[1] + intdata = intlist_data[header_sz:] + + # Extract information about interrupts + if self.__config.check_64b(): + intlist_entry_fmt = prefix + "iiQQ" + else: + intlist_entry_fmt = prefix + "iiII" + + intlist["interrupts"] = [i for i in + struct.iter_unpack(intlist_entry_fmt, intdata)] + + self.__log.debug("Configured interrupt routing") + self.__log.debug("handler irq flags param") + self.__log.debug("--------------------------") + + for irq in intlist["interrupts"]: + self.__log.debug("{0:<10} {1:<3} {2:<3} {3}".format( + hex(irq[2]), irq[0], irq[1], hex(irq[3]))) + + return intlist + + def __parse_intlist(self, intlist): + """All the intlist data are parsed into swt and vt arrays. + + The vt array is prepared for hardware interrupt table. + Every entry in the selected position would contain None or the name of the function pointer + (address or string). + + The swt is a little more complex. At every position it would contain an array of parameter and + function pointer pairs. If CONFIG_SHARED_INTERRUPTS is enabled there may be more than 1 entry. + If empty array is placed on selected position - it means that the application does not implement + this interrupt. + + Parameters: + - intlist: The preprocessed list of intlist section content (see read_intlist) + + Return: + vt, swt - parsed vt and swt arrays (see function description above) + """ + nvec = intlist["num_vectors"] + offset = intlist["offset"] + + if nvec > pow(2, 15): + raise ValueError('nvec is too large, check endianness.') + + self.__log.debug('offset is ' + str(offset)) + self.__log.debug('num_vectors is ' + str(nvec)) + + # Set default entries in both tables + if not(self.__config.args.sw_isr_table or self.__config.args.vector_table): + self.__log.error("one or both of -s or -V needs to be specified on command line") + if self.__config.args.vector_table: + vt = [None for i in range(nvec)] + else: + vt = None + if self.__config.args.sw_isr_table: + swt = [[] for i in range(nvec)] + else: + swt = None + + # Process intlist and write to the tables created + for irq, flags, func, param in intlist["interrupts"]: + if self.__config.test_isr_direct(flags): + if not vt: + self.__log.error("Direct Interrupt %d declared with parameter 0x%x " + "but no vector table in use" + % (irq, param)) + if param != 0: + self.__log.error("Direct irq %d declared, but has non-NULL parameter" + % irq) + if not 0 <= irq - offset < len(vt): + self.__log.error("IRQ %d (offset=%d) exceeds the maximum of %d" + % (irq - offset, offset, len(vt) - 1)) + vt[irq - offset] = func + else: + # Regular interrupt + if not swt: + self.__log.error("Regular Interrupt %d declared with parameter 0x%x " + "but no SW ISR_TABLE in use" + % (irq, param)) + + table_index = self.__config.get_swt_table_index(offset, irq) + + if not 0 <= table_index < len(swt): + self.__log.error("IRQ %d (offset=%d) exceeds the maximum of %d" % + (table_index, offset, len(swt) - 1)) + if self.__config.check_shared_interrupts(): + lst = swt[table_index] + if (param, func) in lst: + self.__log.error("Attempting to register the same ISR/arg pair twice.") + if len(lst) >= self.__config.get_sym("CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS"): + self.__log.error(f"Reached shared interrupt client limit. Maybe increase" + + f" CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS?") + else: + if len(swt[table_index]) > 0: + self.__log.error(f"multiple registrations at table_index {table_index} for irq {irq} (0x{irq:x})" + + f"\nExisting handler 0x{swt[table_index][0][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].append((param, func)) + + return vt, swt, nvec + + def __write_code_irq_vector_table(self, fp): + fp.write(self.source_assembly_header) + + fp.write("void __irq_vector_table __attribute__((naked)) _irq_vector_table(void) {\n") + for i in range(self.__nv): + func = self.__vt[i] + + if func is None: + func = self.__config.vt_default_handler + + if isinstance(func, int): + func_as_string = self.__config.get_sym_from_addr(func) + else: + func_as_string = func + + fp.write("\t__asm(ARCH_IRQ_VECTOR_JUMP_CODE({}));\n".format(func_as_string)) + fp.write("}\n") + + def __write_address_irq_vector_table(self, fp): + fp.write("uintptr_t __irq_vector_table _irq_vector_table[%d] = {\n" % self.__nv) + for i in range(self.__nv): + func = self.__vt[i] + + if func is None: + func = self.__config.vt_default_handler + + if isinstance(func, int): + fp.write("\t{},\n".format(func)) + else: + fp.write("\t((uintptr_t)&{}),\n".format(func)) + + fp.write("};\n") + + def __write_shared_table(self, fp): + fp.write("struct z_shared_isr_table_entry __shared_sw_isr_table" + " z_shared_sw_isr_table[%d] = {\n" % self.__nv) + + for i in range(self.__nv): + if self.__swt[i] is None: + client_num = 0 + client_list = None + else: + client_num = len(self.__swt[i]) + client_list = self.__swt[i] + + if client_num <= 1: + 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(self, fp): + fp.write(self.source_header) + + if self.__config.check_shared_interrupts(): + self.__write_shared_table(fp) + + if self.__vt: + if self.__config.check_sym("CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS"): + self.__write_address_irq_vector_table(fp) + elif self.__config.check_sym("CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_CODE"): + self.__write_code_irq_vector_table(fp) + else: + self.__log.error("CONFIG_IRQ_VECTOR_TABLE_JUMP_BY_{ADDRESS,CODE} not set") + + if not self.__swt: + return + + fp.write("struct _isr_table_entry __sw_isr_table _sw_isr_table[%d] = {\n" + % self.__nv) + + level2_offset = self.__config.get_irq_baseoffset(2) + level3_offset = self.__config.get_irq_baseoffset(3) + + for i in range(self.__nv): + if len(self.__swt[i]) == 0: + # Not used interrupt + param = "0x0" + func = self.__config.swt_spurious_handler + elif len(self.__swt[i]) == 1: + # Single interrupt + param = "{0:#x}".format(self.__swt[i][0][0]) + func = self.__swt[i][0][1] + else: + # Shared interrupt + param = "&z_shared_sw_isr_table[{0}]".format(i) + func = self.__config.swt_shared_handler + + if isinstance(func, int): + func_as_string = "{0:#x}".format(func) + else: + func_as_string = func + + if level2_offset is not None and i == level2_offset: + fp.write("\t/* Level 2 interrupts start here (offset: {}) */\n". + format(level2_offset)) + if level3_offset is not None and i == level3_offset: + fp.write("\t/* Level 3 interrupts start here (offset: {}) */\n". + format(level3_offset)) + + fp.write("\t{{(const void *){0}, (ISR){1}}}, /* {2} */\n".format(param, func_as_string, i)) + fp.write("};\n") diff --git a/scripts/build/gen_isr_tables_parser_local.py b/scripts/build/gen_isr_tables_parser_local.py new file mode 100644 index 00000000000..91bd4a65471 --- /dev/null +++ b/scripts/build/gen_isr_tables_parser_local.py @@ -0,0 +1,375 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2017 Intel Corporation +# Copyright (c) 2018 Foundries.io +# Copyright (c) 2023 Nordic Semiconductor NA +# +# SPDX-License-Identifier: Apache-2.0 +# + +import struct + +class gen_isr_parser: + source_header = """ +/* AUTO-GENERATED by gen_isr_tables.py, do not edit! */ + +#include +#include +#include +#include + +""" + + shared_isr_table_header = """ + +/* For this parser to work, we have to be sure that shared interrupts table entry + * and the normal isr table entry have exactly the same layout + */ +BUILD_ASSERT(sizeof(struct _isr_table_entry) + == + sizeof(struct z_shared_isr_table_entry), + "Shared ISR and ISR table entries layout do not match"); +BUILD_ASSERT(offsetof(struct _isr_table_entry, arg) + == + offsetof(struct z_shared_isr_table_entry, arg), + "Shared ISR and ISR table entries layout do not match"); +BUILD_ASSERT(offsetof(struct _isr_table_entry, isr) + == + offsetof(struct z_shared_isr_table_entry, isr), + "Shared ISR and ISR table entries layout do not match"); + +""" + + def __init__(self, intlist_data, config, log): + """Initialize the parser. + + The function prepares parser to work. + Parameters: + - intlist_data: The binnary data from intlist section + - config: The configuration object + - log: The logging object, has to have error and debug methods + """ + self.__config = config + self.__log = log + intlist = self.__read_intlist(intlist_data) + self.__vt, self.__swt, self.__nv, header = self.__parse_intlist(intlist) + self.__swi_table_entry_size = header["swi_table_entry_size"] + self.__shared_isr_table_entry_size = header["shared_isr_table_entry_size"] + self.__shared_isr_client_num_offset = header["shared_isr_client_num_offset"] + + def __read_intlist(self, intlist_data): + """read an intList section from the elf file. + This is version 2 of a header created by include/zephyr/linker/intlist.ld: + + struct { + uint32_t num_vectors; <- typically CONFIG_NUM_IRQS + uint8_t stream[]; <- the stream with the interrupt data + }; + + The stream is contained from variable length records in a form: + + struct _isr_list_sname { + /** IRQ line number */ + int32_t irq; + /** Flags for this IRQ, see ISR_FLAG_* definitions */ + int32_t flags; + /** The section name */ + const char sname[]; + }; + + The flexible array member here (sname) contains the name of the section where the structure + with interrupt data is located. + It is always Null-terminated string thus we have to search through the input data for the + structure end. + + """ + intlist = {} + prefix = self.__config.endian_prefix() + + # Extract header and the rest of the data + intlist_header_fmt = prefix + "IIIII" + header_sz = struct.calcsize(intlist_header_fmt) + header_raw = struct.unpack_from(intlist_header_fmt, intlist_data, 0) + self.__log.debug(str(header_raw)) + + intlist["num_vectors"] = header_raw[0] + intlist["offset"] = header_raw[1] + intlist["swi_table_entry_size"] = header_raw[2] + intlist["shared_isr_table_entry_size"] = header_raw[3] + intlist["shared_isr_client_num_offset"] = header_raw[4] + + intdata = intlist_data[header_sz:] + + # Extract information about interrupts + intlist_entry_fmt = prefix + "ii" + entry_sz = struct.calcsize(intlist_entry_fmt) + intlist["interrupts"] = [] + + while len(intdata) > entry_sz: + entry_raw = struct.unpack_from(intlist_entry_fmt, intdata, 0) + intdata = intdata[entry_sz:] + null_idx = intdata.find(0) + if null_idx < 0: + self.__log.error("Cannot find sname null termination at IRQ{}".format(entry_raw[0])) + bname = intdata[:null_idx] + # Next structure starts with 4B alignment + next_idx = null_idx + 1 + next_idx = (next_idx + 3) & ~3 + intdata = intdata[next_idx:] + sname = bname.decode() + intlist["interrupts"].append([entry_raw[0], entry_raw[1], sname]) + self.__log.debug("Unpacked IRQ{}, flags: {}, sname: \"{}\"\n".format( + entry_raw[0], entry_raw[1], sname)) + + # If any data left at the end - it has to be all the way 0 - this is just a check + if (len(intdata) and not all([d == 0 for d in intdata])): + self.__log.error("Non-zero data found at the end of the intList data.\n") + + self.__log.debug("Configured interrupt routing with linker") + self.__log.debug("irq flags sname") + self.__log.debug("--------------------------") + + for irq in intlist["interrupts"]: + self.__log.debug("{0:<3} {1:<5} {2}".format( + hex(irq[0]), irq[1], irq[2])) + + return intlist + + def __parse_intlist(self, intlist): + """All the intlist data are parsed into swt and vt arrays. + + The vt array is prepared for hardware interrupt table. + Every entry in the selected position would contain None or the name of the function pointer + (address or string). + + The swt is a little more complex. At every position it would contain an array of parameter and + function pointer pairs. If CONFIG_SHARED_INTERRUPTS is enabled there may be more than 1 entry. + If empty array is placed on selected position - it means that the application does not implement + this interrupt. + + Parameters: + - intlist: The preprocessed list of intlist section content (see read_intlist) + + Return: + vt, swt - parsed vt and swt arrays (see function description above) + """ + nvec = intlist["num_vectors"] + offset = intlist["offset"] + header = { + "swi_table_entry_size": intlist["swi_table_entry_size"], + "shared_isr_table_entry_size": intlist["shared_isr_table_entry_size"], + "shared_isr_client_num_offset": intlist["shared_isr_client_num_offset"] + } + + if nvec > pow(2, 15): + raise ValueError('nvec is too large, check endianness.') + + self.__log.debug('offset is ' + str(offset)) + self.__log.debug('num_vectors is ' + str(nvec)) + + # Set default entries in both tables + if not(self.__config.args.sw_isr_table or self.__config.args.vector_table): + self.__log.error("one or both of -s or -V needs to be specified on command line") + if self.__config.args.vector_table: + vt = [None for i in range(nvec)] + else: + vt = None + if self.__config.args.sw_isr_table: + swt = [[] for i in range(nvec)] + else: + swt = None + + # Process intlist and write to the tables created + for irq, flags, sname in intlist["interrupts"]: + if self.__config.test_isr_direct(flags): + if not 0 <= irq - offset < len(vt): + self.__log.error("IRQ %d (offset=%d) exceeds the maximum of %d" % + (irq - offset, offset, len(vt) - 1)) + vt[irq - offset] = sname + else: + # Regular interrupt + if not swt: + self.__log.error("Regular Interrupt %d declared with section name %s " + "but no SW ISR_TABLE in use" + % (irq, sname)) + + table_index = self.__config.get_swt_table_index(offset, irq) + + if not 0 <= table_index < len(swt): + self.__log.error("IRQ %d (offset=%d) exceeds the maximum of %d" % + (table_index, offset, len(swt) - 1)) + # Check if the given section name does not repeat outside of current interrupt + for i in range(nvec): + if i == irq: + continue + if sname in swt[i]: + self.__log.error(("Attempting to register the same section name \"{}\"for" + + "different interrupts: {} and {}").format(sname, i, irq)) + if self.__config.check_shared_interrupts(): + lst = swt[table_index] + if len(lst) >= self.__config.get_sym("CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS"): + self.__log.error(f"Reached shared interrupt client limit. Maybe increase" + + f" CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS?") + else: + if len(swt[table_index]) > 0: + self.__log.error(f"multiple registrations at table_index {table_index} for irq {irq} (0x{irq:x})" + + f"\nExisting section {swt[table_index]}, new section {sname}" + + "\nHas IRQ_CONNECT or IRQ_DIRECT_CONNECT accidentally been invoked on the same irq multiple times?" + ) + swt[table_index].append(sname) + + return vt, swt, nvec, header + + @staticmethod + def __irq_spurious_section(irq): + return '.irq_spurious.0x{:x}'.format(irq) + + @staticmethod + def __isr_generated_section(irq): + return '.isr_generated.0x{:x}'.format(irq) + + @staticmethod + def __shared_entry_section(irq, ent): + return '.isr_shared.0x{:x}_0x{:x}'.format(irq, ent) + + @staticmethod + def __shared_client_num_section(irq): + return '.isr_shared.0x{:x}_client_num'.format(irq) + + def __isr_spurious_entry(self, irq): + return '_Z_ISR_TABLE_ENTRY({irq}, {func}, NULL, "{sect}");'.format( + irq = irq, + func = self.__config.swt_spurious_handler, + sect = self.__isr_generated_section(irq) + ) + + def __isr_shared_entry(self, irq): + return '_Z_ISR_TABLE_ENTRY({irq}, {func}, {arg}, "{sect}");'.format( + irq = irq, + arg = '&{}[{}]'.format(self.__config.shared_array_name, irq), + func = self.__config.swt_shared_handler, + sect = self.__isr_generated_section(irq) + ) + + def __irq_spurious_entry(self, irq): + return '_Z_ISR_DIRECT_TABLE_ENTRY({irq}, {func}, "{sect}");'.format( + irq = irq, + func = self.__config.vt_default_handler, + sect = self.__irq_spurious_section(irq) + ) + + def __write_isr_handlers(self, fp): + for i in range(self.__nv): + if len(self.__swt[i]) <= 0: + fp.write(self.__isr_spurious_entry(i) + '\n') + elif len(self.__swt[i]) > 1: + # Connect to shared handlers + fp.write(self.__isr_shared_entry(i) + '\n') + else: + fp.write('/* ISR: {} implemented in app in "{}" section. */\n'.format( + i, self.__swt[i][0])) + + def __write_irq_handlers(self, fp): + for i in range(self.__nv): + if self.__vt[i] is None: + fp.write(self.__irq_spurious_entry(i) + '\n') + else: + fp.write('/* ISR: {} implemented in app. */\n'.format(i)) + + def __write_shared_handlers(self, fp): + fp.write("extern struct z_shared_isr_table_entry " + "{}[{}];\n".format(self.__config.shared_array_name, self.__nv)) + + shared_cnt = self.__config.get_sym('CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS') + for i in range(self.__nv): + swt_len = len(self.__swt[i]) + for j in range(shared_cnt): + if (swt_len <= 1) or (swt_len <= j): + # Add all unused entry + fp.write('static Z_DECL_ALIGN(struct _isr_table_entry)\n' + + '\tZ_GENERIC_SECTION({})\n'.format(self.__shared_entry_section(i, j)) + + '\t__used isr_shared_empty_entry_0x{:x}_0x{:x} = {{\n'.format(i, j) + + '\t\t.arg = (const void *)NULL,\n' + + '\t\t.isr = (void (*)(const void *))(void *)0\n' + + '};\n' + ) + else: + # Add information about entry implemented by application + fp.write('/* Shared isr {} entry {} implemented in "{}" section*/\n'.format( + i, j, self.__swt[i][j])) + + # Add information about clients count + fp.write(('static size_t Z_GENERIC_SECTION({}) __used\n' + + 'isr_shared_client_num_0x{:x} = {};\n\n').format( + self.__shared_client_num_section(i), + i, + 0 if swt_len < 2 else swt_len) + ) + + def write_source(self, fp): + fp.write(self.source_header) + + if self.__vt: + self.__write_irq_handlers(fp) + + if not self.__swt: + return + + if self.__config.check_shared_interrupts(): + self.__write_shared_handlers(fp) + + self.__write_isr_handlers(fp) + + def __write_linker_irq(self, fp): + fp.write('{} = .;\n'.format(self.__config.irq_vector_array_name)) + for i in range(self.__nv): + if self.__vt[i] is None: + sname = self.__irq_spurious_section(i) + else: + sname = self.__vt[i] + fp.write('KEEP(*("{}"))\n'.format(sname)) + + def __write_linker_shared(self, fp): + fp.write(". = ALIGN({});\n".format(self.__shared_isr_table_entry_size)) + fp.write('{} = .;\n'.format(self.__config.shared_array_name)) + shared_cnt = self.__config.get_sym('CONFIG_SHARED_IRQ_MAX_NUM_CLIENTS') + client_num_pads = self.__shared_isr_client_num_offset - \ + shared_cnt * self.__swi_table_entry_size + if client_num_pads < 0: + self.__log.error("Invalid __shared_isr_client_num_offset header value") + for i in range(self.__nv): + swt_len = len(self.__swt[i]) + # Add all entries + for j in range(shared_cnt): + if (swt_len <= 1) or (swt_len <= j): + fp.write('KEEP(*("{}"))\n'.format(self.__shared_entry_section(i, j))) + else: + sname = self.__swt[i][j] + if (j != 0) and (sname in self.__swt[i][0:j]): + fp.write('/* Repetition of "{}" section */\n'.format(sname)) + else: + fp.write('KEEP(*("{}"))\n'.format(sname)) + fp.write('. = . + {};\n'.format(client_num_pads)) + fp.write('KEEP(*("{}"))\n'.format(self.__shared_client_num_section(i))) + fp.write(". = ALIGN({});\n".format(self.__shared_isr_table_entry_size)) + + def __write_linker_isr(self, fp): + fp.write(". = ALIGN({});\n".format(self.__swi_table_entry_size)) + fp.write('{} = .;\n'.format(self.__config.sw_isr_array_name)) + for i in range(self.__nv): + if (len(self.__swt[i])) == 1: + sname = self.__swt[i][0] + else: + sname = self.__isr_generated_section(i) + fp.write('KEEP(*("{}"))\n'.format(sname)) + + def write_linker_vt(self, fp): + if self.__vt: + self.__write_linker_irq(fp) + + def write_linker_swi(self, fp): + if self.__swt: + self.__write_linker_isr(fp) + + if self.__config.check_shared_interrupts(): + self.__write_linker_shared(fp) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index 0a2da6bc9ca..d8b147f8ab0 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -314,6 +314,13 @@ def get_modules(self, modules_file): modules = [name for name in os.listdir(modules_dir) if os.path.exists(os.path.join(modules_dir, name, 'Kconfig'))] + nrf_modules_dir = ZEPHYR_BASE + '/../nrf/modules' + nrf_modules = [] + if os.path.exists(nrf_modules_dir): + nrf_modules = [name for name in os.listdir(nrf_modules_dir) if + os.path.exists(os.path.join(nrf_modules_dir, name, + 'Kconfig'))] + with open(modules_file, 'r') as fp_module_file: content = fp_module_file.read() @@ -323,6 +330,15 @@ def get_modules(self, modules_file): re.sub('[^a-zA-Z0-9]', '_', module).upper(), modules_dir + '/' + module + '/Kconfig' )) + for module in nrf_modules: + fp_module_file.write("ZEPHYR_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + nrf_modules_dir + '/' + module + '/Kconfig' + )) + fp_module_file.write("NCS_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + modules_dir + '/' + module + '/Kconfig' + )) fp_module_file.write(content) def get_kconfig_dts(self, kconfig_dts_file): diff --git a/scripts/ci/test_plan.py b/scripts/ci/test_plan.py index a2ba406d8ce..26227d570aa 100755 --- a/scripts/ci/test_plan.py +++ b/scripts/ci/test_plan.py @@ -95,7 +95,7 @@ def __repr__(self): class Filters: def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, - pull_request=False, platforms=[], detailed_test_id=True): + pull_request=False, platforms=[], detailed_test_id=True, quarantine_list=None): self.modified_files = modified_files self.testsuite_root = testsuite_root self.resolved_files = [] @@ -108,6 +108,7 @@ def __init__(self, modified_files, ignore_path, alt_tags, testsuite_root, self.detailed_test_id = detailed_test_id self.ignore_path = ignore_path self.tag_cfg_file = alt_tags + self.quarantine_list = quarantine_list def process(self): self.find_modules() @@ -128,6 +129,9 @@ def get_plan(self, options, integration=False, use_testsuite_root=True): cmd+=["-T", root] if integration: cmd.append("--integration") + if self.quarantine_list: + for q in self.quarantine_list: + cmd += ["--quarantine-list", q] logging.info(" ".join(cmd)) _ = subprocess.call(cmd) @@ -415,6 +419,12 @@ def parse_args(): "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.") + parser.add_argument( + "--quarantine-list", action="append", metavar="FILENAME", + help="Load list of test scenarios under quarantine. The entries in " + "the file need to correspond to the test scenarios names as in " + "corresponding tests .yaml files. These scenarios " + "will be skipped with quarantine as the reason.") # Include paths in names by default. parser.set_defaults(detailed_test_id=True) @@ -443,7 +453,7 @@ def parse_args(): print("=========") f = Filters(files, args.ignore_path, args.alt_tags, args.testsuite_root, - args.pull_request, args.platform, args.detailed_test_id) + args.pull_request, args.platform, args.detailed_test_id, args.quarantine_list) f.process() # remove dupes and filtered cases diff --git a/scripts/gitlint/zephyr_commit_rules.py b/scripts/gitlint/zephyr_commit_rules.py index ea31c6737f3..d39c7997e26 100644 --- a/scripts/gitlint/zephyr_commit_rules.py +++ b/scripts/gitlint/zephyr_commit_rules.py @@ -78,7 +78,7 @@ class TitleMaxLengthRevert(LineRule): name = "title-max-length-no-revert" id = "UC5" target = CommitMessageTitle - options_spec = [IntOption('line-length', 75, "Max line length")] + options_spec = [IntOption('line-length', 120, "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', 75, "Max line length")] + options_spec = [IntOption('line-length', 120, "Max line length")] violation_message = "Commit message body line exceeds max length ({0}>{1})" def validate(self, line, _commit): 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 diff --git a/scripts/kconfig/kconfigfunctions.py b/scripts/kconfig/kconfigfunctions.py index 621ec3cb3a8..754a312ebb7 100644 --- a/scripts/kconfig/kconfigfunctions.py +++ b/scripts/kconfig/kconfigfunctions.py @@ -309,6 +309,48 @@ def dt_chosen_reg(kconf, name, chosen, index=0, unit=None): return hex(_dt_chosen_reg_addr(kconf, chosen, index, unit)) +def _dt_chosen_partition_addr(kconf, chosen, index=0, unit=None): + """ + This function takes a 'chosen' property and treats that property as a path + to an EDT node. If it finds an EDT node, it will look to see if that + node has a register, and if that node has a grandparent that has a register + at the given 'index'. The addition of both addresses will be returned, if + not, we return 0. + + The function will divide the value based on 'unit': + None No division + 'k' or 'K' divide by 1024 (1 << 10) + 'm' or 'M' divide by 1,048,576 (1 << 20) + 'g' or 'G' divide by 1,073,741,824 (1 << 30) + 'kb' or 'Kb' divide by 8192 (1 << 13) + 'mb' or 'Mb' divide by 8,388,608 (1 << 23) + 'gb' or 'Gb' divide by 8,589,934,592 (1 << 33) + """ + if doc_mode or edt is None: + return 0 + + node = edt.chosen_node(chosen) + if not node: + return 0 + + p_node = node.parent + if not p_node: + return 0 + + return _node_reg_addr(p_node.parent, index, unit) + _node_reg_addr(node, 0, unit) + + +def dt_chosen_partition_addr(kconf, name, chosen, index=0, unit=None): + """ + This function just routes to the proper function and converts + the result to either a string int or string hex value. + """ + if name == "dt_chosen_partition_addr_int": + return str(_dt_chosen_partition_addr(kconf, chosen, index, unit)) + if name == "dt_chosen_partition_addr_hex": + return hex(_dt_chosen_partition_addr(kconf, chosen, index, unit)) + + def _dt_node_reg_addr(kconf, path, index=0, unit=None): """ This function takes a 'path' and looks for an EDT node at that path. If it @@ -806,5 +848,7 @@ def shields_list_contains(kconf, _, shield): "dt_node_parent": (dt_node_parent, 1, 1), "dt_nodelabel_array_prop_has_val": (dt_nodelabel_array_prop_has_val, 3, 3), "dt_gpio_hogs_enabled": (dt_gpio_hogs_enabled, 0, 0), + "dt_chosen_partition_addr_int": (dt_chosen_partition_addr, 1, 3), + "dt_chosen_partition_addr_hex": (dt_chosen_partition_addr, 1, 3), "shields_list_contains": (shields_list_contains, 1, 1), } diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 86965f1f9cf..16e19c85fec 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -216,6 +216,12 @@ 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", + 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/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 5e90b7c84c6..a0ea7c59a8e 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -13,7 +13,6 @@ import scl import logging from pathlib import Path -from natsort import natsorted from twisterlib.environment import ZEPHYR_BASE @@ -322,7 +321,7 @@ def readlink(link): def save(self, hwm_file): # use existing map - self.detected = natsorted(self.detected, key=lambda x: x.serial or '') + self.detected.sort(key=lambda x: x.serial or '') if os.path.exists(hwm_file): with open(hwm_file, 'r') as yaml_file: hwm = yaml.load(yaml_file, Loader=SafeLoader) diff --git a/scripts/pylib/twister/twisterlib/harness.py b/scripts/pylib/twister/twisterlib/harness.py index 052def7162a..8b8ad92fc51 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,10 @@ 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 - if handler.options.verbose > 1: command.extend([ '--log-cli-level=DEBUG', @@ -346,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): @@ -489,6 +498,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/quarantine.yaml b/scripts/quarantine.yaml new file mode 100644 index 00000000000..20c4f9248ea --- /dev/null +++ b/scripts/quarantine.yaml @@ -0,0 +1,88 @@ +# The configurations resulting as a product of scenarios and platforms +# will be skipped if quarantine is used. More details here: +# https://docs.zephyrproject.org/latest/guides/test/twister.html#quarantine + +- scenarios: + - testing.ztest.busy_sim + - testing.ztest.busy_sim_nrf52840dk_pin + platforms: + - nrf52840dk_nrf52840 + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.unary_f64 + platforms: + - nrf5340dk_nrf5340_cpunet + - qemu_cortex_m3 + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_f16 + - libraries.cmsis_dsp.matrix.binary_f16.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_q15 + - libraries.cmsis_dsp.matrix.binary_q15.fpu + - libraries.cmsis_dsp.matrix.unary_f32 + - libraries.cmsis_dsp.matrix.unary_f32.fpu + - libraries.cmsis_dsp.matrix.unary_f64 + - libraries.cmsis_dsp.matrix.unary_f64.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Flash overflows" + +# libsdl2-dev package should be added into docker image +- scenarios: + - sample.boards.nrf.nrf_led_matrix + - sample.display.lvgl.gui + platforms: + - native_posix + comment: "libsdl2-dev package not available" + +- scenarios: + - sample.net.sockets.echo_server.usbnet + - sample.net.sockets.echo_server.usbnet_composite + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - sample.net.zperf.netusb_ecm + - sample.net.zperf.netusb_eem + - sample.net.zperf.netusb_rndis + platforms: + - nrf52833dk_nrf52833 + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - net.mqtt.tls + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - kernel.common.picolibc + - libraries.picolibc + - libraries.libc.picolibc.mem_alloc + - libraries.picolibc.sprintf_new + platforms: + - nrf52dk_nrf52832 + comment: "Ram overflows, also in the upstream" + +- scenarios: + - sample.psa_crypto + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Due to using sdk-zephyr manifest instead of nrf. Should be fixed after the change" diff --git a/scripts/requirements-extras.txt b/scripts/requirements-extras.txt index f210f069de9..99fa4f16cf4 100644 --- a/scripts/requirements-extras.txt +++ b/scripts/requirements-extras.txt @@ -32,4 +32,4 @@ PyGithub graphviz # used to generate CBOR encoders and decoders, e.g. lwm2m_senml_cbor. -zcbor>=0.6.0 +zcbor>=0.8.0 diff --git a/scripts/requirements-run-test.txt b/scripts/requirements-run-test.txt index 83692128110..3bb0b21c44e 100644 --- a/scripts/requirements-run-test.txt +++ b/scripts/requirements-run-test.txt @@ -7,7 +7,6 @@ pyocd>=0.35.0 # used by twister for board/hardware map tabulate -natsort # used by mcuboot cbor>=1.0.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..befd384be37 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,19 @@ 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[0] in command + assert pytest_args_from_cmd[1] in command + assert pytest_args_from_yaml not in command + + @pytest.mark.parametrize( ('pytest_root', 'expected'), [ @@ -222,3 +236,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" diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index 2ff51d7e85d..76662c72ea9 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -24,11 +24,26 @@ ErrNotAvailableBecauseProtection = 24 ErrVerify = 25 +UICR_RANGES = { + 'NRF53_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), + 'NRFDL_DEVICE_CORE_NETWORK': (0x01FF8000, 0x01FF8800), + }, + 'NRF54H_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x0FFF8000, 0x0FFF8800), + 'NRFDL_DEVICE_CORE_NETWORK': (0x0FFFA000, 0x0FFFA800), + }, + 'NRF91_FAMILY': { + 'NRFDL_DEVICE_CORE_APPLICATION': (0x00FF8000, 0x00FF8800), + } +} + class NrfBinaryRunner(ZephyrBinaryRunner): '''Runner front-end base class for nrf tools.''' def __init__(self, cfg, family, softreset, dev_id, erase=False, - reset=True, tool_opt=[], force=False, recover=False): + reset=True, tool_opt=[], force=False, recover=False, + erase_all_uicrs=False): super().__init__(cfg) self.hex_ = cfg.hex_file if family and not family.endswith('_FAMILY'): @@ -40,6 +55,7 @@ def __init__(self, cfg, family, softreset, dev_id, erase=False, self.reset = bool(reset) self.force = force self.recover = bool(recover) + self.erase_all_uicrs = bool(erase_all_uicrs) self.tool_opt = [] for opts in [shlex.split(opt) for opt in tool_opt]: @@ -59,7 +75,8 @@ def dev_id_help(cls) -> str: @classmethod def do_add_parser(cls, parser): parser.add_argument('--nrf-family', - choices=['NRF51', 'NRF52', 'NRF53', 'NRF91'], + choices=['NRF51', 'NRF52', 'NRF53', 'NRF54L', + 'NRF54H', 'NRF91'], help='''MCU family; still accepted for compatibility only''') parser.add_argument('--softreset', required=False, @@ -75,6 +92,11 @@ def do_add_parser(cls, parser): help='''erase all user available non-volatile memory and disable read back protection before flashing (erases flash for both cores on nRF53)''') + parser.add_argument('--erase-all-uicrs', required=False, + action='store_true', + help='''Erase all UICR registers before flashing + (nRF54H only). When not set, only UICR registers + present in the hex file will be erased.''') parser.set_defaults(reset=True) @@ -161,6 +183,10 @@ def ensure_family(self): self.family = 'NRF52_FAMILY' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF53X'): self.family = 'NRF53_FAMILY' + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54LX'): + self.family = 'NRF54L_FAMILY' + elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF54HX'): + self.family = 'NRF54H_FAMILY' elif self.build_conf.getboolean('CONFIG_SOC_SERIES_NRF91X'): self.family = 'NRF91_FAMILY' else: @@ -172,21 +198,15 @@ def hex_refers_region(self, region_start, region_end): return True return False - def hex_has_uicr_content(self): - # A map from SoCs which need this check to their UICR address - # ranges. If self.family isn't in here, do nothing. - uicr_ranges = { - 'NRF53': ((0x00FF8000, 0x00FF8800), - (0x01FF8000, 0x01FF8800)), - 'NRF91': ((0x00FF8000, 0x00FF8800),), - } + def hex_get_uicrs(self): + hex_uicrs = {} - if self.family not in uicr_ranges: - return + if self.family in UICR_RANGES: + for uicr_core, uicr_range in UICR_RANGES[self.family].items(): + if self.hex_refers_region(*uicr_range): + hex_uicrs[uicr_core] = uicr_range - for region_start, region_end in uicr_ranges[self.family]: - if self.hex_refers_region(region_start, region_end): - return True + return hex_uicrs def flush(self, force=False): try: @@ -211,7 +231,7 @@ def flush(self, force=False): # If there are data in the UICR region it is likely that the # verify failed du to the UICR not been erased before, so giving # a warning here will hopefully enhance UX. - if self.hex_has_uicr_content(): + if self.hex_get_uicrs(): self.logger.warning( 'The hex file contains data placed in the UICR, which ' 'may require a full erase before reprogramming. Run ' @@ -264,11 +284,24 @@ def program_hex(self): if self.family == 'NRF53_FAMILY': # nRF53 requires special treatment due to the extra coprocessor. self.program_hex_nrf53(erase_arg, qspi_erase_opt) + elif self.family == 'NRF54H_FAMILY': + self.program_hex_nrf54h() else: self.op_program(self.hex_, erase_arg, qspi_erase_opt, defer=True) self.flush(force=False) + def program_hex_nrf54h(self): + if self.erase_all_uicrs: + uicrs = UICR_RANGES['NRF54H_FAMILY'] + else: + uicrs = self.hex_get_uicrs() + + for uicr_core, range in uicrs.items(): + self.exec_op('erasepage', defer=True, core=uicr_core, page=range[0]) + + self.op_program(self.hex_, 'NO_ERASE', None, defer=True) + def program_hex_nrf53(self, erase_arg, qspi_erase_opt): # program_hex() helper for nRF53. diff --git a/scripts/west_commands/runners/nrfjprog.py b/scripts/west_commands/runners/nrfjprog.py index 8762ce0e740..723080d56c3 100644 --- a/scripts/west_commands/runners/nrfjprog.py +++ b/scripts/west_commands/runners/nrfjprog.py @@ -32,7 +32,8 @@ def do_create(cls, cfg, args): args.dev_id, erase=args.erase, reset=args.reset, tool_opt=args.tool_opt, force=args.force, - recover=args.recover) + recover=args.recover, + erase_all_uicrs=args.erase_all_uicrs) def do_get_boards(self): snrs = self.check_output(['nrfjprog', '--ids']) @@ -46,7 +47,8 @@ def do_exec_op(self, op, force=False): # Translate the op families = {'NRF51_FAMILY': 'NRF51', 'NRF52_FAMILY': 'NRF52', - 'NRF53_FAMILY': 'NRF53', 'NRF91_FAMILY': 'NRF91'} + 'NRF53_FAMILY': 'NRF53', 'NRF54L_FAMILY': 'NRF54L', + 'NRF54H_FAMILY': 'NRF54H', 'NRF91_FAMILY': 'NRF91'} cores = {'NRFDL_DEVICE_CORE_APPLICATION': 'CP_APPLICATION', 'NRFDL_DEVICE_CORE_NETWORK': 'CP_NETWORK'} @@ -69,6 +71,8 @@ def do_exec_op(self, op, force=False): cmd.append('--sectorerase') elif erase == 'ERASE_PAGES_INCLUDING_UICR': cmd.append('--sectoranduicrerase') + elif erase == 'NO_ERASE': + pass else: raise RuntimeError(f'Invalid erase mode: {erase}') @@ -85,6 +89,9 @@ def do_exec_op(self, op, force=False): cmd.append('--reset') if _op['option'] == 'RESET_PIN': cmd.append('--pinreset') + elif op_type == 'erasepage': + cmd.append('--erasepage') + cmd.append(f"0x{_op['page']:08x}") else: raise RuntimeError(f'Invalid operation: {op_type}') 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() diff --git a/snippets/nordic-ppr-ram/README.rst b/snippets/nordic-ppr-ram/README.rst new file mode 100644 index 00000000000..501e5073357 --- /dev/null +++ b/snippets/nordic-ppr-ram/README.rst @@ -0,0 +1,11 @@ +.. _nordic-ppr-ram: + +Nordic boot PPR snippet with execution from RAM (nordic-ppr-ram) +################################################################ + +Overview +******** + +This snippet allows users to build Zephyr with the capability to boot Nordic PPR +(Peripheral Processor) from another core. PPR code is executed from RAM. Note +that PPR image must be built with :kconfig:option:`CONFIG_XIP` disabled. diff --git a/snippets/nordic-ppr-ram/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay b/snippets/nordic-ppr-ram/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..5597c886b85 --- /dev/null +++ b/snippets/nordic-ppr-ram/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuppr_ram3x_region { + status = "okay"; +}; + +&cpuppr_vpr { + execution-memory = <&cpuppr_ram3x_region>; +}; + +&uart135 { + status = "reserved"; +}; diff --git a/snippets/nordic-ppr-ram/nordic-ppr-ram.overlay b/snippets/nordic-ppr-ram/nordic-ppr-ram.overlay new file mode 100644 index 00000000000..e69c3a0d2bf --- /dev/null +++ b/snippets/nordic-ppr-ram/nordic-ppr-ram.overlay @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +/* code is sourced from cpuppr code partition */ +&cpuppr_vpr { + status = "okay"; + source-memory = <&cpuppr_code_partition>; +}; + +/* code partition size must match RAM size */ +&cpuppr_code_partition { + reg = <0x126000 DT_SIZE_K(28)>; +}; diff --git a/snippets/nordic-ppr-ram/snippet.yml b/snippets/nordic-ppr-ram/snippet.yml new file mode 100644 index 00000000000..0d6039af2e5 --- /dev/null +++ b/snippets/nordic-ppr-ram/snippet.yml @@ -0,0 +1,8 @@ +name: nordic-ppr-ram +append: + EXTRA_DTC_OVERLAY_FILE: nordic-ppr-ram.overlay + +boards: + nrf54h20pdk_nrf54h20_cpuapp: + append: + EXTRA_DTC_OVERLAY_FILE: boards/nrf54h20pdk_nrf54h20_cpuapp.overlay diff --git a/snippets/nordic-ppr/README.rst b/snippets/nordic-ppr/README.rst new file mode 100644 index 00000000000..36eb74d193f --- /dev/null +++ b/snippets/nordic-ppr/README.rst @@ -0,0 +1,10 @@ +.. _nordic-ppr: + +Nordic PPR snippet (nordic-ppr) +############################### + +Overview +******** + +This snippet allows users to build Zephyr with the capability to boot Nordic PPR +(Peripheral Processor) from another core. diff --git a/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay b/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..75128f42a13 --- /dev/null +++ b/snippets/nordic-ppr/boards/nrf54h20pdk_nrf54h20_cpuapp.overlay @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuppr_ram3x_region { + status = "okay"; +}; + +&uart135 { + status = "reserved"; +}; diff --git a/snippets/nordic-ppr/nordic-ppr.overlay b/snippets/nordic-ppr/nordic-ppr.overlay new file mode 100644 index 00000000000..e33885fc10d --- /dev/null +++ b/snippets/nordic-ppr/nordic-ppr.overlay @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor + * SPDX-License-Identifier: Apache-2.0 + */ + +&cpuppr_vpr { + status = "okay"; +}; diff --git a/snippets/nordic-ppr/snippet.yml b/snippets/nordic-ppr/snippet.yml new file mode 100644 index 00000000000..9e1f20bb757 --- /dev/null +++ b/snippets/nordic-ppr/snippet.yml @@ -0,0 +1,8 @@ +name: nordic-ppr +append: + EXTRA_DTC_OVERLAY_FILE: nordic-ppr.overlay + +boards: + nrf54h20pdk_nrf54h20_cpuapp: + append: + EXTRA_DTC_OVERLAY_FILE: boards/nrf54h20pdk_nrf54h20_cpuapp.overlay diff --git a/soc/CMakeLists.txt b/soc/CMakeLists.txt index 6706168281e..d55bd63f496 100644 --- a/soc/CMakeLists.txt +++ b/soc/CMakeLists.txt @@ -9,6 +9,8 @@ if(_SOC_IS_IN_TREE) endif() unset(_SOC_IS_IN_TREE) +add_subdirectory(common) + if(EXISTS ${SOC_DIR}/${ARCH}/CMakeLists.txt) add_subdirectory(${SOC_DIR}/${ARCH} soc/${ARCH}) else() diff --git a/soc/arm/ambiq/apollo4x/Kconfig.series b/soc/arm/ambiq/apollo4x/Kconfig.series index b7982d3609e..a9e72567206 100644 --- a/soc/arm/ambiq/apollo4x/Kconfig.series +++ b/soc/arm/ambiq/apollo4x/Kconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES_APOLLO4X select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_FPU + select CPU_HAS_ARM_MPU select SOC_FAMILY_AMBIQ select HAS_SWO select AMBIQ_HAL diff --git a/soc/arm/arm/designstart/soc.h b/soc/arm/arm/designstart/soc.h index ec58467f923..a9bcdb4e9cd 100644 --- a/soc/arm/arm/designstart/soc.h +++ b/soc/arm/arm/designstart/soc.h @@ -7,7 +7,6 @@ #ifndef _SOC_H_ #define _SOC_H_ - -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include #endif /* _SOC_H_ */ diff --git a/soc/arm/arm/mps2/soc.h b/soc/arm/arm/mps2/soc.h index 594d3d084c1..822c7ee01bd 100644 --- a/soc/arm/arm/mps2/soc.h +++ b/soc/arm/arm/mps2/soc.h @@ -7,15 +7,7 @@ #ifndef _SOC_H_ #define _SOC_H_ -#define __MPU_PRESENT 1 - -#if defined(CONFIG_SOC_MPS2_AN521) -#define __SAUREGION_PRESENT CONFIG_CPU_HAS_ARM_SAU -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __DSP_PRESENT CONFIG_ARMV8_M_DSP - -#endif - +#include #include extern void wakeup_cpu1(void); diff --git a/soc/arm/arm/mps3/Kconfig.soc b/soc/arm/arm/mps3/Kconfig.soc index 86970e288cc..ae577fa549b 100644 --- a/soc/arm/arm/mps3/Kconfig.soc +++ b/soc/arm/arm/mps3/Kconfig.soc @@ -14,5 +14,10 @@ config SOC_MPS3_AN547 select ARMV8_M_DSP select ARMV8_1_M_MVEI select ARMV8_1_M_MVEF + select ARMV8_1_M_PMU endchoice + +config ARMV8_1_M_PMU_EVENTCNT + int + default 8 if SOC_MPS3_AN547 diff --git a/soc/arm/arm/mps3/soc.h b/soc/arm/arm/mps3/soc.h index 6a325074cf2..c3a59da1c0d 100644 --- a/soc/arm/arm/mps3/soc.h +++ b/soc/arm/arm/mps3/soc.h @@ -7,19 +7,6 @@ #ifndef _SOC_H_ #define _SOC_H_ -#define __MPU_PRESENT 1 - -#if defined(CONFIG_SOC_MPS3_AN547) -#define __SAUREGION_PRESENT 1U /* SAU regions present */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __DSP_PRESENT 1U /* DSP extension present */ -#define __MVE_PRESENT 1U /* MVE extensions present */ -#define __MVE_FP 1U /* MVE floating point present */ -#define __ICACHE_PRESENT 1U /* ICACHE present */ -#define __DCACHE_PRESENT 1U /* DCACHE present */ -#define __PMU_PRESENT 1U /* PMU present */ -#define __PMU_NUM_EVENTCNT 8U /* PMU Event Counters */ -#endif - +#include #endif /* _SOC_H_ */ diff --git a/soc/arm/arm/musca_s1/Kconfig.soc b/soc/arm/arm/musca_s1/Kconfig.soc index 9bf02614308..0c0763fae2a 100644 --- a/soc/arm/arm/musca_s1/Kconfig.soc +++ b/soc/arm/arm/musca_s1/Kconfig.soc @@ -11,5 +11,7 @@ config SOC_V2M_MUSCA_S1 select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_FPU + select ARMV8_M_DSP endchoice diff --git a/soc/arm/aspeed/ast10x0/soc.h b/soc/arm/aspeed/ast10x0/soc.h index f45df84c128..be1cced5da2 100644 --- a/soc/arm/aspeed/ast10x0/soc.h +++ b/soc/arm/aspeed/ast10x0/soc.h @@ -25,4 +25,6 @@ void aspeed_print_sysrst_info(void); +#include + #endif /* ZEPHYR_SOC_ARM_ASPEED_AST10X0_SOC_H_*/ diff --git a/soc/arm/atmel_sam0/samc21/Kconfig.series b/soc/arm/atmel_sam0/samc21/Kconfig.series index 044a7aea229..acb83679e18 100644 --- a/soc/arm/atmel_sam0/samc21/Kconfig.series +++ b/soc/arm/atmel_sam0/samc21/Kconfig.series @@ -10,6 +10,7 @@ config SOC_SERIES_SAMC21 select CPU_CORTEX_M0PLUS select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU select SOC_FAMILY_SAM0 select PLATFORM_SPECIFIC_INIT select ASF diff --git a/soc/arm/bcm_vk/valkyrie/soc.h b/soc/arm/bcm_vk/valkyrie/soc.h index 26863fbfea0..c3e21a89581 100644 --- a/soc/arm/bcm_vk/valkyrie/soc.h +++ b/soc/arm/bcm_vk/valkyrie/soc.h @@ -292,4 +292,6 @@ typedef enum IRQn { #define PCIE0_PERST_FE_INTR BIT(1) #define PCIE0_PERST_INB_FE_INTR BIT(3) +#include + #endif diff --git a/soc/arm/bcm_vk/viper/soc.h b/soc/arm/bcm_vk/viper/soc.h index 6695e92ef5c..06bf59fb24d 100644 --- a/soc/arm/bcm_vk/viper/soc.h +++ b/soc/arm/bcm_vk/viper/soc.h @@ -9,10 +9,10 @@ #include #include +#include #ifndef _ASMLANGUAGE - /* Interrupt Number Definition */ typedef enum IRQn { /* CORTEX-M7 Processor Exceptions Numbers */ @@ -301,4 +301,6 @@ typedef enum IRQn { #define LS_ICFG_PMON_LITE_SW_RESETN 0x482f0120 #define PCIE_PMON_LITE_SW_RESETN BIT(0) +#include + #endif diff --git a/soc/arm/cypress/Kconfig b/soc/arm/cypress/Kconfig index 352c66b4e76..cb76ccb1090 100644 --- a/soc/arm/cypress/Kconfig +++ b/soc/arm/cypress/Kconfig @@ -12,12 +12,15 @@ config SOC_PSOC6_M0 select CPU_CORTEX_M0PLUS select CPU_CORTEX_M_HAS_SYSTICK select CPU_CORTEX_M_HAS_VTOR + select CPU_HAS_ARM_MPU config SOC_PSOC6_M4 bool "SOC_PSOC6_M4" select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_CORTEX_M_HAS_SYSTICK + select CPU_HAS_ARM_MPU + select CPU_HAS_FPU endchoice diff --git a/soc/arm/gigadevice/gd32a50x/Kconfig.series b/soc/arm/gigadevice/gd32a50x/Kconfig.series index 96fc8c1d0af..2488c643727 100644 --- a/soc/arm/gigadevice/gd32a50x/Kconfig.series +++ b/soc/arm/gigadevice/gd32a50x/Kconfig.series @@ -6,6 +6,7 @@ config SOC_SERIES_GD32A50X select ARM select CPU_HAS_ARM_MPU select CPU_HAS_FPU + select ARMV8_M_DSP select CPU_CORTEX_M33 select SOC_FAMILY_GD32_ARM select GD32_HAS_AF_PINMUX diff --git a/soc/arm/gigadevice/gd32e50x/Kconfig.series b/soc/arm/gigadevice/gd32e50x/Kconfig.series index 8bc3f71118e..546ca456793 100644 --- a/soc/arm/gigadevice/gd32e50x/Kconfig.series +++ b/soc/arm/gigadevice/gd32e50x/Kconfig.series @@ -7,6 +7,7 @@ config SOC_SERIES_GD32E50X select CPU_HAS_ARM_MPU select CPU_HAS_FPU select CPU_CORTEX_M33 + select ARMV8_M_DSP select SOC_FAMILY_GD32_ARM select GD32_HAS_AFIO_PINMUX select GD32_HAS_IRC_40K diff --git a/soc/arm/gigadevice/gd32l23x/Kconfig.series b/soc/arm/gigadevice/gd32l23x/Kconfig.series index 5bdb0dba7d3..d6125ca4152 100644 --- a/soc/arm/gigadevice/gd32l23x/Kconfig.series +++ b/soc/arm/gigadevice/gd32l23x/Kconfig.series @@ -6,6 +6,7 @@ config SOC_SERIES_GD32L23X select ARM select CPU_CORTEX_M23 select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select SOC_FAMILY_GD32_ARM select GD32_HAS_AF_PINMUX select GD32_HAS_IRC_32K diff --git a/soc/arm/microchip_mec/mec1501/Kconfig.series b/soc/arm/microchip_mec/mec1501/Kconfig.series index d3b679bb557..92dc6f3f8f9 100644 --- a/soc/arm/microchip_mec/mec1501/Kconfig.series +++ b/soc/arm/microchip_mec/mec1501/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_MEC1501X select ARM select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT + select CPU_HAS_ARM_MPU select SOC_FAMILY_MEC select HAS_PM help diff --git a/soc/arm/microchip_mec/mec172x/soc.h b/soc/arm/microchip_mec/mec172x/soc.h index 3bf4f533fdb..19afc4e920a 100644 --- a/soc/arm/microchip_mec/mec172x/soc.h +++ b/soc/arm/microchip_mec/mec172x/soc.h @@ -242,6 +242,8 @@ typedef enum { MAX_IRQn } IRQn_Type; +#include + #include /* chip specific register defines */ diff --git a/soc/arm/nordic_nrf/CMakeLists.txt b/soc/arm/nordic_nrf/CMakeLists.txt index 47364b35ffb..bd7725404b8 100644 --- a/soc/arm/nordic_nrf/CMakeLists.txt +++ b/soc/arm/nordic_nrf/CMakeLists.txt @@ -1,9 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 +zephyr_library() + add_subdirectory(${SOC_SERIES}) add_subdirectory(common) -zephyr_sources( +zephyr_library_sources( validate_base_addresses.c validate_enabled_instances.c ) @@ -25,4 +27,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..ba0c9d4b164 100644 --- a/soc/arm/nordic_nrf/Kconfig +++ b/soc/arm/nordic_nrf/Kconfig @@ -13,11 +13,12 @@ config SOC_FAMILY string default "nordic_nrf" -source "soc/arm/nordic_nrf/Kconfig.peripherals" +source "soc/common/nordic_nrf/Kconfig.peripherals" source "soc/arm/nordic_nrf/*/Kconfig.soc" config NRF_SOC_SECURE_SUPPORTED def_bool !TRUSTED_EXECUTION_NONSECURE || (BUILD_WITH_TFM && TFM_PARTITION_PLATFORM) + depends on !SOC_SERIES_NRF54HX help Hidden function to indicate that that the soc_secure functions are available. @@ -45,6 +46,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 diff --git a/soc/arm/nordic_nrf/Kconfig.defconfig b/soc/arm/nordic_nrf/Kconfig.defconfig index 3eedcf350c6..ad3c97443ff 100644 --- a/soc/arm/nordic_nrf/Kconfig.defconfig +++ b/soc/arm/nordic_nrf/Kconfig.defconfig @@ -7,22 +7,21 @@ if SOC_FAMILY_NRF source "soc/arm/nordic_nrf/*/Kconfig.defconfig.series" -# If the kernel has timer support, enable both clock control and timer +# If the kernel has timer support, enable clock control if SYS_CLOCK_EXISTS config CLOCK_CONTROL - default y - -config NRF_RTC_TIMER - default y + default y if !SOC_SERIES_NRF54HX endif # SYS_CLOCK_EXISTS config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 if NRF_GRTC_TIMER default 32768 config SYS_CLOCK_TICKS_PER_SEC default 128 if !TICKLESS_KERNEL + default 10000 if NRF_GRTC_TIMER default 32768 config ARCH_HAS_CUSTOM_BUSY_WAIT @@ -40,4 +39,7 @@ config GPIO default y depends on SPI +config UART_USE_RUNTIME_CONFIGURE + default n + endif # SOC_FAMILY_NRF diff --git a/soc/arm/nordic_nrf/common/CMakeLists.txt b/soc/arm/nordic_nrf/common/CMakeLists.txt index eb074dd0548..ea05f3d369e 100644 --- a/soc/arm/nordic_nrf/common/CMakeLists.txt +++ b/soc/arm/nordic_nrf/common/CMakeLists.txt @@ -3,11 +3,14 @@ zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_NRF soc_nrf_common.S) zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) + zephyr_include_directories(.) +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") + if (CONFIG_TFM_PARTITION_PLATFORM) - zephyr_sources(soc_secure.c) + zephyr_library_sources(soc_secure.c) zephyr_library_include_directories( - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/soc/arm/nordic_nrf/common/soc_nrf_common.h b/soc/arm/nordic_nrf/common/soc_nrf_common.h index 4c00d7c0237..1e5e603967b 100644 --- a/soc/arm/nordic_nrf/common/soc_nrf_common.h +++ b/soc/arm/nordic_nrf/common/soc_nrf_common.h @@ -149,6 +149,52 @@ (NRF_DT_GPIOS_TO_PSEL(node_id, prop)), \ (default_value)) +/** + * @brief Convert a devicetree GPIO phandle+specifier to GPIOTE instance number. + * + * Some of nRF SoCs may have more instances of GPIOTE. + * To handle this, we use the "gpiote-instance" property of the GPIO node. + * + * This macro converts a devicetree GPIO phandle array value + * "<&gpioX pin ...>" to a GPIOTE instance number. + * + * Examples: + * + * &gpiote0 { + * instance = <0>; + * }; + * + * &gpiote20 { + * instance = <20>; + * }; + * + * &gpio0 { + * gpiote-instance = <&gpiote0>; + * } + * + * &gpio1 { + * gpiote-instance = <&gpiote20>; + * } + * + * foo: my-node { + * tx-gpios = <&gpio0 4 ...>; + * rx-gpios = <&gpio0 5 ...>, <&gpio1 5 ...>; + * }; + * + * NRF_DT_GPIOTE_INST_BY_IDX(DT_NODELABEL(foo), tx_gpios, 0) // = 0 + * NRF_DT_GPIOTE_INST_BY_IDX(DT_NODELABEL(foo), rx_gpios, 1) // = 20 + */ +#define NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, idx) \ + DT_PROP(DT_PHANDLE(DT_GPIO_CTLR_BY_IDX(node_id, prop, idx), \ + gpiote_instance), \ + instance) + +/** + * @brief Equivalent to NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0) + */ +#define NRF_DT_GPIOTE_INST(node_id, prop) \ + NRF_DT_GPIOTE_INST_BY_IDX(node_id, prop, 0) + /** * Error out the build if 'prop' is set on node 'node_id' and * DT_GPIO_CTLR(node_id, prop) is not an SoC GPIO controller, diff --git a/soc/arm/nordic_nrf/common/soc_secure.h b/soc/arm/nordic_nrf/common/soc_secure.h index 948f38547aa..d38d66ab488 100644 --- a/soc/arm/nordic_nrf/common/soc_secure.h +++ b/soc/arm/nordic_nrf/common/soc_secure.h @@ -59,7 +59,7 @@ static inline void soc_secure_gpio_pin_mcu_select(uint32_t pin_number, #if defined(CONFIG_SOC_HFXO_CAP_INTERNAL) static inline uint32_t soc_secure_read_xosc32mtrim(void) { - return NRF_FICR_S->XOSC32MTRIM; + return NRF_FICR->XOSC32MTRIM; } #endif /* defined(CONFIG_SOC_HFXO_CAP_INTERNAL) */ diff --git a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt index 44d139e422a..35d47fb252b 100644 --- a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt @@ -1,14 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library() - -zephyr_library_sources( - soc.c - ) - -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 "") +zephyr_library_sources(soc.c) diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series index 8c0bc74c02f..a4053bf7fed 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.defconfig.series @@ -14,4 +14,8 @@ config SOC_SERIES config NUM_IRQS default 26 +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF51X diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index 04e255a3eb1..1b7d4d5257a 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -1,15 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_library() - -zephyr_library_sources( - soc.c - ) - -zephyr_library_include_directories( - ${ZEPHYR_BASE}/kernel/include - ${ZEPHYR_BASE}/arch/arm/include - ) +zephyr_library_sources(soc.c) 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") @@ -22,5 +13,3 @@ 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/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series index 4a7edf2aa95..2e89a5130a6 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf52/Kconfig.defconfig.nrf52*" config SOC_SERIES default "nrf52" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF52X 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 diff --git a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt index b4e82f52c28..be275df68f5 100644 --- a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt @@ -1,12 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( - soc.c - ) +zephyr_library_sources(soc.c) -zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC - sync_rtc.c - ) +zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC sync_rtc.c) if (CONFIG_SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED AND NOT CONFIG_SYS_CLOCK_EXISTS) @@ -19,5 +15,3 @@ 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/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series index 2857d5dd25d..7e5660cf514 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf53/Kconfig.defconfig.nrf53*" config SOC_SERIES default "nrf53" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF53X diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 3afcd96f70d..b3ca2661675 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -12,13 +12,14 @@ config SOC_NRF5340_CPUAPP select HAS_POWEROFF select SOC_COMPATIBLE_NRF5340_CPUAPP imply SOC_NRF53_RTC_PRETICK + imply SOC_NRF53_ANOMALY_168_WORKAROUND 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 + imply SOC_NRF53_ANOMALY_168_WORKAROUND choice prompt "nRF53x MCU Selection" @@ -79,6 +80,25 @@ config SOC_NRF53_RTC_PRETICK_IPC_CH_TO_NET endif +config SOC_NRF53_ANOMALY_168_WORKAROUND + bool "Workaround for nRF5340 anomaly 168" + select ARM_ON_EXIT_CPU_IDLE + help + Indicates that the workaround for the anomaly 168 that affects + the nRF5340 SoC should be applied. + The workaround involves execution of 8 NOP instructions when the CPU + exist its idle state (when the WFI/WFE instruction returns) and it is + enabled by default for both the application and network core. + +config SOC_NRF53_ANOMALY_168_WORKAROUND_FOR_EXECUTION_FROM_RAM + bool "Extend the workaround to execution at 128 MHz from RAM" + depends on SOC_NRF53_ANOMALY_168_WORKAROUND && SOC_NRF5340_CPUAPP + help + Indicates that the anomaly 168 workaround is to be extended to cover + also a specific case when the WFI/WFE instruction is executed at 128 + MHz from RAM. Then, 26 instead of 8 NOP instructions needs to be + executed after WFI/WFE. This extension is not enabled by default. + if SOC_NRF5340_CPUAPP config SOC_DCDC_NRF53X_APP @@ -104,12 +124,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 diff --git a/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h index b6cd92ca092..c02c9451419 100644 --- a/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h +++ b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h @@ -11,10 +11,16 @@ #if defined(_ASMLANGUAGE) +#if defined(CONFIG_SOC_NRF53_ANOMALY_168_WORKAROUND_FOR_EXECUTION_FROM_RAM) #define SOC_ON_EXIT_CPU_IDLE \ + .rept 26; \ nop; \ + .endr +#elif defined(CONFIG_SOC_NRF53_ANOMALY_168_WORKAROUND) +#define SOC_ON_EXIT_CPU_IDLE \ + .rept 8; \ nop; \ - nop; \ - nop; + .endr +#endif #endif /* _ASMLANGUAGE */ diff --git a/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt b/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt new file mode 100644 index 00000000000..8b4df42fa55 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources(soc.c) + +# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes +# for the image correctly +zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp new file mode 100644 index 00000000000..d90f87c0b89 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -0,0 +1,17 @@ +# Nordic Semiconductor nRF54H20 Application MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPUAPP + +config SOC + default "nrf54h20_enga_cpuapp" + +config NUM_IRQS + default 471 + +config NRF_REGTOOL_GENERATE_UICR + default y + +endif # SOC_NRF54H20_ENGA_CPUAPP diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad new file mode 100644 index 00000000000..6aae8c3a105 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -0,0 +1,17 @@ +# Nordic Semiconductor nRF54H20 Radio MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPURAD + +config SOC + default "nrf54h20_enga_cpurad" + +config NUM_IRQS + default 471 + +config NRF_REGTOOL_GENERATE_UICR + default y + +endif # SOC_NRF54H20_ENGA_CPURAD diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series new file mode 100644 index 00000000000..ddc902d213e --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.defconfig.series @@ -0,0 +1,16 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54HX + +rsource "Kconfig.defconfig.nrf54h*" + +config SOC_SERIES + default "nrf54h" + +config CACHE_NRF_CACHE + default y if EXTERNAL_CACHE + +endif # SOC_SERIES_NRF54HX diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.series b/soc/arm/nordic_nrf/nrf54h/Kconfig.series new file mode 100644 index 00000000000..0b896f477ac --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.series @@ -0,0 +1,16 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54HX + bool "Nordic Semiconductor nRF54H series MCU" + select ARM + select ARMV8_M_DSP + select CPU_CORTEX_M33 + select SOC_FAMILY_NRF + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + help + Enable support for nRF54H MCU series diff --git a/soc/arm/nordic_nrf/nrf54h/Kconfig.soc b/soc/arm/nordic_nrf/nrf54h/Kconfig.soc new file mode 100644 index 00000000000..9c065e79eaf --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/Kconfig.soc @@ -0,0 +1,37 @@ +# Nordic Semiconductor nRF54H MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF54H20 + bool "nRF54H20" + depends on SOC_SERIES_NRF54HX + +if SOC_NRF54H20 + +choice + prompt "nRF54H20 MCU Selection" + +config SOC_NRF54H20_ENGA_CPUAPP + bool "nRF54H20 ENGA CPUAPP" + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_FPU + +config SOC_NRF54H20_ENGA_CPURAD + bool "nRF54H20 ENGA CPURAD" + select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU + select CPU_HAS_DCACHE + select CPU_HAS_ICACHE + select CPU_HAS_FPU + +endchoice + +config NRF_ENABLE_ICACHE + bool "Instruction cache (I-Cache)" + default y + +endif # SOC_NRF54H20 diff --git a/soc/arm/nordic_nrf/nrf54h/align.ld b/soc/arm/nordic_nrf/nrf54h/align.ld new file mode 100644 index 00000000000..0905aa7f7bc --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/align.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.align16,,) +{ + . = (ALIGN(16) > 0 ? ALIGN(16) : 16) - 1; + BYTE(0); +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/arm/nordic_nrf/nrf54h/soc.c b/soc/arm/nordic_nrf/nrf54h/soc.c new file mode 100644 index 00000000000..9fefd414152 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/soc.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#if defined(NRF_APPLICATION) +#define HSFLL_NODE DT_NODELABEL(cpuapp_hsfll) +#elif defined(NRF_RADIOCORE) +#define HSFLL_NODE DT_NODELABEL(cpurad_hsfll) +#endif + +#define FICR_ADDR_GET(node_id, name) \ + DT_REG_ADDR(DT_PHANDLE_BY_NAME(node_id, nordic_ficrs, name)) + \ + DT_PHA_BY_NAME(node_id, nordic_ficrs, name, offset) + +static void power_domain_init(void) +{ + /* + * Set: + * - LRCCONF010.POWERON.MAIN: 1 + * - LRCCONF010.POWERON.ACT: 1 + * - LRCCONF010.RETAIN.MAIN: 1 + * - LRCCONF010.RETAIN.ACT: 1 + * + * This is done here at boot so that when the idle routine will hit + * WFI the power domain will be correctly retained. + */ + + nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true); + nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true); + + nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, true); + nrf_lrcconf_retain_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_DOMAIN_0, true); + +#if defined(CONFIG_SOC_NRF54H20_ENGA_CPUAPP) + nrf_lrcconf_poweron_force_set(NRF_LRCCONF000, NRF_LRCCONF_POWER_DOMAIN_0, true); +#endif +} + +static int trim_hsfll(void) +{ + NRF_HSFLL_Type *hsfll = (NRF_HSFLL_Type *)DT_REG_ADDR(HSFLL_NODE); + nrf_hsfll_trim_t trim = { + .vsup = sys_read32(FICR_ADDR_GET(HSFLL_NODE, vsup)), + .coarse = sys_read32(FICR_ADDR_GET(HSFLL_NODE, coarse)), + .fine = sys_read32(FICR_ADDR_GET(HSFLL_NODE, fine)) + }; + + LOG_DBG("Trim: HSFLL VSUP: 0x%.8x", trim.vsup); + LOG_DBG("Trim: HSFLL COARSE: 0x%.8x", trim.coarse); + LOG_DBG("Trim: HSFLL FINE: 0x%.8x", trim.fine); + + nrf_hsfll_clkctrl_mult_set(hsfll, + DT_PROP(HSFLL_NODE, clock_frequency) / + DT_PROP(DT_CLOCKS_CTLR(HSFLL_NODE), clock_frequency)); + nrf_hsfll_trim_set(hsfll, &trim); + + nrf_hsfll_task_trigger(hsfll, NRF_HSFLL_TASK_FREQ_CHANGE); +#if defined(CONFIG_SOC_NRF54H20_ENGA_CPUAPP) || defined(CONFIG_SOC_NRF54H20_ENGA_CPURAD) + /* In this HW revision, HSFLL task frequency change needs to be + * triggered additional time to take effect. + */ + nrf_hsfll_task_trigger(hsfll, NRF_HSFLL_TASK_FREQ_CHANGE); +#endif + + LOG_DBG("NRF_HSFLL->TRIM.VSUP = %d", hsfll->TRIM.VSUP); + LOG_DBG("NRF_HSFLL->TRIM.COARSE = %d", hsfll->TRIM.COARSE); + LOG_DBG("NRF_HSFLL->TRIM.FINE = %d", hsfll->TRIM.FINE); + + return 0; +} + +static int nordicsemi_nrf54h_init(void) +{ +#if defined(CONFIG_NRF_ENABLE_ICACHE) + sys_cache_instr_enable(); +#endif + + power_domain_init(); + + trim_hsfll(); + + return 0; +} + +void arch_busy_wait(uint32_t time_us) +{ + nrfx_coredep_delay_us(time_us); +} + +SYS_INIT(nordicsemi_nrf54h_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/nordic_nrf/nrf54h/soc.h b/soc/arm/nordic_nrf/nrf54h/soc.h new file mode 100644 index 00000000000..9a44ab24982 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54h/soc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ +#define SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ + +#include + +#endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */ diff --git a/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt b/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt new file mode 100644 index 00000000000..33036acce8f --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources( + soc.c + ../validate_rram_partitions.c) + +if (CONFIG_ELV_GRTC_LFXO_ALLOWED) + message(WARNING "WARNING! ELV mode feature is EXPERIMENTAL and may brick your device!") +endif() diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp new file mode 100644 index 00000000000..d19df604c02 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.nrf54l15_enga_cpuapp @@ -0,0 +1,18 @@ +# Nordic Semiconductor nRF54L15 MCU + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54L15_ENGA_CPUAPP + +config SOC + string + default "nrf54l15_cpuapp" + +config NUM_IRQS + default 271 + +config IEEE802154_NRF5 + default IEEE802154 + +endif # SOC_NRF54L15_ENGA_CPUAPP diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series new file mode 100644 index 00000000000..6c0a5bc606d --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.defconfig.series @@ -0,0 +1,19 @@ +# Nordic Semiconductor nRF54L MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54LX + +rsource "Kconfig.defconfig.nrf54l*" + +config SOC_SERIES + default "nrf54l" + +config CORTEX_M_SYSTICK + default !NRF_GRTC_TIMER + +config CACHE_NRF_CACHE + default y if EXTERNAL_CACHE + +endif # SOC_SERIES_NRF54LX diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.series b/soc/arm/nordic_nrf/nrf54l/Kconfig.series new file mode 100644 index 00000000000..a9367a0bf36 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.series @@ -0,0 +1,13 @@ +# Nordic Semiconductor nRF54L MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54LX + bool "Nordic Semiconductor nRF54L series MCU" + select HAS_NRFX + select HAS_NORDIC_DRIVERS + select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select SOC_FAMILY_NRF + help + Enable support for nRF54L MCU series diff --git a/soc/arm/nordic_nrf/nrf54l/Kconfig.soc b/soc/arm/nordic_nrf/nrf54l/Kconfig.soc new file mode 100644 index 00000000000..c42c8cfc9b3 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/Kconfig.soc @@ -0,0 +1,70 @@ +# Nordic Semiconductor nRF54 MCU line + +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54LX + +config SOC_NRF54L15 + bool "NRF54L15" + +config SOC_NRF54L15_ENGA + bool "NRF54L15 ENGA" + select SOC_NRF54L15 + +config SOC_NRF54L15_ENGA_CPUAPP + bool "NRF54L15 ENGA CPUAPP" + select ARM + select ARMV8_M_DSP + select CPU_CORTEX_M33 + select CPU_HAS_ARM_MPU + select CPU_HAS_ICACHE + select CPU_HAS_ARM_SAU + select CPU_HAS_FPU + select HAS_HW_NRF_RADIO_IEEE802154 + select HAS_POWEROFF + select SOC_NRF54L15_ENGA + +config SOC_NRF54LX_SKIP_CLOCK_CONFIG + bool "Skip clock frequency configuration in system initialization" + help + With this option, the CPU clock frequency is not set during system initialization. + The CPU runs with the default, hardware-selected frequency. + +config SOC_NRF_FORCE_CONSTLAT + bool "Force constant-latency mode" + help + In constant latency mode the CPU wakeup latency and the PPI task response + will be constant and kept at a minimum. This is secured by forcing a set + of base resources on while in sleep. The advantage of having a constant + and predictable latency will be at the cost of having increased power consumption. + +config SOC_NRF54L_VREG_MAIN_DCDC + bool "NRF54L DC/DC converter." + help + To enable, an inductor must be connected to the DC/DC converter pin. + +config SOC_NRF54L_NORMAL_VOLTAGE_MODE + bool "NRF54L Normal Voltage Mode." + +config SOC_NRF54L_GLITCHDET_WORKAROUND + bool "Workaround that disables glitch detector" + default y + help + Temporary workaround - disabling glitch detector to limit power consumption. + +if NRF_GRTC_TIMER + +config ELV_GRTC_LFXO_ALLOWED + bool + depends on NRF_GRTC_SLEEP_ALLOWED + select EXPERIMENTAL + help + This feature allows using ELV mode when GRTC operates with the LFXO as + a low-frequency clock source. The LFXO is automatically activated when + preparing to system-off. + WARNING! This feature is EXPERIMENTAL and may brick your device! + +endif # NRF_GRTC_TIMER + +endif # SOC_SERIES_NRF54LX diff --git a/soc/arm/nordic_nrf/nrf54l/soc.c b/soc/arm/nordic_nrf/nrf54l/soc.c new file mode 100644 index 00000000000..a7b286fa048 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/soc.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Nordic Semiconductor nRF54L family processor + * + * This module provides routines to initialize and support board-level hardware + * for the Nordic Semiconductor nRF54L family processor. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); + +#define LFXO_NODE DT_NODELABEL(lfxo) +#define HFXO_NODE DT_NODELABEL(hfxo) + +static int nordicsemi_nrf54l_init(void) +{ + /* Update the SystemCoreClock global variable with current core clock + * retrieved from hardware state. + */ + SystemCoreClockUpdate(); + + /* Enable ICACHE */ + sys_cache_instr_enable(); + + if (IS_ENABLED(CONFIG_SOC_NRF54L_GLITCHDET_WORKAROUND)) { + nrf_glitchdet_enable_set(NRF_GLITCHDET, false); + } + +#if DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, internal) + uint32_t xosc32ktrim = NRF_FICR->XOSC32KTRIM; + + uint32_t offset_k = + (xosc32ktrim & FICR_XOSC32KTRIM_OFFSET_Msk) >> FICR_XOSC32KTRIM_OFFSET_Pos; + + uint32_t slope_field_k = + (xosc32ktrim & FICR_XOSC32KTRIM_SLOPE_Msk) >> FICR_XOSC32KTRIM_SLOPE_Pos; + uint32_t slope_mask_k = FICR_XOSC32KTRIM_SLOPE_Msk >> FICR_XOSC32KTRIM_SLOPE_Pos; + uint32_t slope_sign_k = (slope_mask_k - (slope_mask_k >> 1)); + int32_t slope_k = (int32_t)(slope_field_k ^ slope_sign_k) - (int32_t)slope_sign_k; + + /* As specified in the nRF54L15 PS: + * CAPVALUE = round( (CAPACITANCE - 4) * (FICR->XOSC32KTRIM.SLOPE + 0.765625 * 2^9)/(2^9) + * + FICR->XOSC32KTRIM.OFFSET/(2^6) ); + * where CAPACITANCE is the desired capacitor value in pF, holding any + * value between 4 pF and 18 pF in 0.5 pF steps. + */ + uint32_t mid_val = + (((DT_PROP(LFXO_NODE, load_capacitance_femtofarad) * 2UL) / 1000UL - 8UL) * + (uint32_t)(slope_k + 392)) + (offset_k << 4UL); + uint32_t capvalue_k = mid_val >> 10UL; + + /* Round. */ + if ((mid_val % 1024UL) >= 512UL) { + capvalue_k++; + } + nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)capvalue_k); +#elif DT_ENUM_HAS_VALUE(LFXO_NODE, load_capacitors, external) + nrf_oscillators_lfxo_cap_set(NRF_OSCILLATORS, (nrf_oscillators_lfxo_cap_t)0); +#endif + +#if DT_ENUM_HAS_VALUE(HFXO_NODE, load_capacitors, internal) + uint32_t xosc32mtrim = NRF_FICR->XOSC32MTRIM; + /* The SLOPE field is in the two's complement form, hence this special + * handling. Ideally, it would result in just one SBFX instruction for + * extracting the slope value, at least gcc is capable of producing such + * output, but since the compiler apparently tries first to optimize + * additions and subtractions, it generates slightly less than optimal + * code. + */ + uint32_t slope_field = + (xosc32mtrim & FICR_XOSC32MTRIM_SLOPE_Msk) >> FICR_XOSC32MTRIM_SLOPE_Pos; + uint32_t slope_mask = FICR_XOSC32MTRIM_SLOPE_Msk >> FICR_XOSC32MTRIM_SLOPE_Pos; + uint32_t slope_sign = (slope_mask - (slope_mask >> 1)); + int32_t slope_m = (int32_t)(slope_field ^ slope_sign) - (int32_t)slope_sign; + uint32_t offset_m = + (xosc32mtrim & FICR_XOSC32MTRIM_OFFSET_Msk) >> FICR_XOSC32MTRIM_OFFSET_Pos; + /* As specified in the nRF54L15 PS: + * CAPVALUE = (((CAPACITANCE-5.5)*(FICR->XOSC32MTRIM.SLOPE+791)) + + * FICR->XOSC32MTRIM.OFFSET<<2)>>8; + * where CAPACITANCE is the desired total load capacitance value in pF, + * holding any value between 4.0 pF and 17.0 pF in 0.25 pF steps. + */ + uint32_t capvalue = + (((((DT_PROP(HFXO_NODE, load_capacitance_femtofarad) * 4UL) / 1000UL) - 22UL) * + (uint32_t)(slope_m + 791) / 4UL) + (offset_m << 2UL)) >> 8UL; + + nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, true, capvalue); +#elif DT_ENUM_HAS_VALUE(HFXO_NODE, load_capacitors, external) + nrf_oscillators_hfxo_cap_set(NRF_OSCILLATORS, false, 0); +#endif + + if (IS_ENABLED(CONFIG_SOC_NRF_FORCE_CONSTLAT)) { + nrf_power_task_trigger(NRF_POWER, NRF_POWER_TASK_CONSTLAT); + } + + if (IS_ENABLED(CONFIG_SOC_NRF54L_VREG_MAIN_DCDC)) { + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MAIN, true); + } + + if (IS_ENABLED(CONFIG_SOC_NRF54L_NORMAL_VOLTAGE_MODE)) { + nrf_regulators_vreg_enable_set(NRF_REGULATORS, NRF_REGULATORS_VREG_MEDIUM, false); + } + +#if defined(CONFIG_ELV_GRTC_LFXO_ALLOWED) + nrf_regulators_elv_mode_allow_set(NRF_REGULATORS, NRF_REGULATORS_ELV_ELVGRTCLFXO_MASK); +#endif /* CONFIG_ELV_GRTC_LFXO_ALLOWED */ + + return 0; +} + +void arch_busy_wait(uint32_t time_us) +{ + nrfx_coredep_delay_us(time_us); +} + +SYS_INIT(nordicsemi_nrf54l_init, PRE_KERNEL_1, 0); diff --git a/soc/arm/nordic_nrf/nrf54l/soc.h b/soc/arm/nordic_nrf/nrf54l/soc.h new file mode 100644 index 00000000000..b775fa9d0f3 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf54l/soc.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the Nordic Semiconductor NRF54L family processors. + */ + +#ifndef _NORDICSEMI_NRF54L_SOC_H_ +#define _NORDICSEMI_NRF54L_SOC_H_ + +#include + +#define FLASH_PAGE_ERASE_MAX_TIME_US 8000UL +#define FLASH_PAGE_MAX_CNT 381UL + +#endif /* _NORDICSEMI_NRF54L_SOC_H_ */ diff --git a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt index 7424bb9f7b9..35d47fb252b 100644 --- a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt @@ -1,7 +1,3 @@ # 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 "") +zephyr_library_sources(soc.c) diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA new file mode 100644 index 00000000000..1b3ea88e359 --- /dev/null +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf9151_LACA @@ -0,0 +1,14 @@ +# Nordic Semiconductor nRF9151 MCU + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF9151_LACA + +config SOC + default "nRF9151_LACA" + +config NUM_IRQS + default 65 + +endif # SOC_NRF9151_LACA diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series index 9612555a4c8..6d6cccab999 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.series @@ -10,4 +10,8 @@ source "soc/arm/nordic_nrf/nrf91/Kconfig.defconfig.nrf91*" config SOC_SERIES default "nrf91" +# If the kernel has timer support, enable the timer +config NRF_RTC_TIMER + default y if SYS_CLOCK_EXISTS + endif # SOC_SERIES_NRF91X 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 diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.soc b/soc/arm/nordic_nrf/nrf91/Kconfig.soc index c9b8c54438b..0267ada4850 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.soc @@ -34,6 +34,10 @@ config SOC_NRF9131_LACA bool "NRF9131_LACA" select SOC_NRF9120 +config SOC_NRF9151_LACA + bool "NRF9151_LACA" + select SOC_NRF9120 + endchoice config NRF_ENABLE_ICACHE diff --git a/soc/arm/nordic_nrf/validate_base_addresses.c b/soc/arm/nordic_nrf/validate_base_addresses.c index 58aaa5a7513..28ec231b132 100644 --- a/soc/arm/nordic_nrf/validate_base_addresses.c +++ b/soc/arm/nordic_nrf/validate_base_addresses.c @@ -16,6 +16,10 @@ #define NRF_CTRLAP NRF_CTRL_AP_PERI #endif +#if !defined(NRF_GPIOTE0) && defined(NRF_GPIOTE) +#define NRF_GPIOTE0 NRF_GPIOTE +#endif + #if !defined(NRF_I2S0) && defined(NRF_I2S) #define NRF_I2S0 NRF_I2S #endif @@ -141,6 +145,12 @@ CHECK_DT_REG(flash_controller, NRF_NVMC); CHECK_DT_REG(gpio0, NRF_P0); CHECK_DT_REG(gpio1, NRF_P1); CHECK_DT_REG(gpiote, NRF_GPIOTE); +CHECK_DT_REG(gpiote0, NRF_GPIOTE0); +CHECK_DT_REG(gpiote1, NRF_GPIOTE1); +CHECK_DT_REG(gpiote20, NRF_GPIOTE20); +CHECK_DT_REG(gpiote30, NRF_GPIOTE30); +CHECK_DT_REG(gpiote130, NRF_GPIOTE130); +CHECK_DT_REG(gpiote131, NRF_GPIOTE131); CHECK_I2C_REG(i2c0, 0); CHECK_I2C_REG(i2c1, 1); CHECK_DT_REG(i2c2, NRF_TWIM2); @@ -188,10 +198,31 @@ CHECK_DT_REG(timer1, NRF_TIMER1); CHECK_DT_REG(timer2, NRF_TIMER2); CHECK_DT_REG(timer3, NRF_TIMER3); CHECK_DT_REG(timer4, NRF_TIMER4); +CHECK_DT_REG(timer00, NRF_TIMER00); +CHECK_DT_REG(timer10, NRF_TIMER10); +CHECK_DT_REG(timer20, NRF_TIMER20); +CHECK_DT_REG(timer21, NRF_TIMER21); +CHECK_DT_REG(timer22, NRF_TIMER22); +CHECK_DT_REG(timer23, NRF_TIMER23); +CHECK_DT_REG(timer24, NRF_TIMER24); CHECK_UART_REG(uart0, 0); CHECK_DT_REG(uart1, NRF_UARTE1); CHECK_DT_REG(uart2, NRF_UARTE2); CHECK_DT_REG(uart3, NRF_UARTE3); +CHECK_DT_REG(uart00, NRF_UARTE00); +CHECK_DT_REG(uart20, NRF_UARTE20); +CHECK_DT_REG(uart21, NRF_UARTE21); +CHECK_DT_REG(uart22, NRF_UARTE22); +CHECK_DT_REG(uart30, NRF_UARTE30); +CHECK_DT_REG(uart120, NRF_UARTE120); +CHECK_DT_REG(uart130, NRF_UARTE130); +CHECK_DT_REG(uart131, NRF_UARTE131); +CHECK_DT_REG(uart132, NRF_UARTE132); +CHECK_DT_REG(uart133, NRF_UARTE133); +CHECK_DT_REG(uart134, NRF_UARTE134); +CHECK_DT_REG(uart135, NRF_UARTE135); +CHECK_DT_REG(uart136, NRF_UARTE136); +CHECK_DT_REG(uart137, NRF_UARTE137); CHECK_DT_REG(uicr, NRF_UICR); CHECK_DT_REG(usbd, NRF_USBD); CHECK_DT_REG(usbreg, NRF_USBREGULATOR); @@ -199,6 +230,8 @@ CHECK_DT_REG(vmc, NRF_VMC); CHECK_DT_REG(wdt, NRF_WDT0); /* this should be the same node as wdt0 */ CHECK_DT_REG(wdt0, NRF_WDT0); CHECK_DT_REG(wdt1, NRF_WDT1); +CHECK_DT_REG(wdt30, NRF_WDT30); +CHECK_DT_REG(wdt31, NRF_WDT31); /* nRF51/nRF52-specific addresses */ #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) diff --git a/soc/arm/nordic_nrf/validate_rram_partitions.c b/soc/arm/nordic_nrf/validate_rram_partitions.c new file mode 100644 index 00000000000..f35d9cf73f3 --- /dev/null +++ b/soc/arm/nordic_nrf/validate_rram_partitions.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define PAIR__(f, sep, arg_first, ...) FOR_EACH_FIXED_ARG(f, sep, arg_first, __VA_ARGS__) +#define PAIR_(f, sep, args_to_expand) PAIR__(f, sep, args_to_expand) +#define PAIR(n, f, sep, ...) PAIR_(f, sep, GET_ARGS_LESS_N(n, __VA_ARGS__)) + +/** + * @brief Call a macro on every unique pair of the given variadic arguments. + * + * For example, FOR_EACH_PAIR(f, (,), 1, 2, 3, 4) should expand to: + * + * f(2, 1) , f(3, 1) , f(4, 1) , f(3, 2) , f(4, 2) , f(4, 3) + * + * @param f Macro to call. Must accept two arguments. + * @param sep Separator between macro calls. Must be in parentheses. + * + * @see FOR_EACH + */ +#define FOR_EACH_PAIR(f, sep, ...) \ + LISTIFY(NUM_VA_ARGS_LESS_1(__VA_ARGS__), PAIR, sep, f, sep, __VA_ARGS__) + +/** + * @brief Get a node's non-secure register block start address. + * + * @param node_id Node identifier. + */ +#define REG_ADDR_NS(node_id) (DT_REG_ADDR(node_id) & 0xEFFFFFFFUL) + +/** + * @brief Get a node's non-secure register block end address. + * + * @param node_id Node identifier. + */ +#define REG_END_NS(node_id) (REG_ADDR_NS(node_id) + DT_REG_SIZE(node_id)) + +/* clang-format off */ + +#define RRAM_BASE REG_ADDR_NS(DT_NODELABEL(rram0)) +#define RRAM_CONTROLLER DT_NODELABEL(rram_controller) + +#if !DT_NODE_EXISTS(RRAM_CONTROLLER) +#error "Missing \"rram-controller\" node" +#endif + +#define CHECK_RRAM_NODE_COMPATIBLE(node_id) \ + BUILD_ASSERT(DT_NODE_HAS_COMPAT(node_id, soc_nv_flash), \ + "Missing compatible \"soc-nv-flash\" from " DT_NODE_FULL_NAME(node_id) \ + " (required for all children of " DT_NODE_PATH(RRAM_CONTROLLER) ")") + +#define CHECK_RRAM_PARTITION_WITHIN_PARENT(node_id) \ + BUILD_ASSERT(RRAM_BASE + REG_ADDR_NS(node_id) >= REG_ADDR_NS(DT_GPARENT(node_id)) && \ + RRAM_BASE + REG_END_NS(node_id) <= REG_END_NS(DT_GPARENT(node_id)), \ + DT_NODE_FULL_NAME(node_id) " is not fully contained within its parent " \ + DT_NODE_PATH(DT_GPARENT(node_id))) + +#define CHECK_NODES_NON_OVERLAPPING(node_id_1, node_id_2) \ + BUILD_ASSERT(REG_ADDR_NS(node_id_1) >= REG_END_NS(node_id_2) || \ + REG_ADDR_NS(node_id_2) >= REG_END_NS(node_id_1), \ + DT_NODE_PATH(node_id_1) " and " DT_NODE_PATH(node_id_2) " are overlapping") + +/* Retrieve all RRAM nodes that are children of "rram-controller". */ +#define COMMA(x) x, +#define RRAM_NODES_LIST LIST_DROP_EMPTY(DT_FOREACH_CHILD(RRAM_CONTROLLER, COMMA)) + +#if !IS_EMPTY(RRAM_NODES_LIST) + +/* Check that every RRAM node matches the "soc-nv-flash" compatible. */ +FOR_EACH(CHECK_RRAM_NODE_COMPATIBLE, (;), RRAM_NODES_LIST); + +/* Check that no two RRAM nodes are overlapping. */ +FOR_EACH_PAIR(CHECK_NODES_NON_OVERLAPPING, (;), RRAM_NODES_LIST); + +#endif + +/* Retrieve all RRAM partitions by looking for "fixed-partitions" compatibles in each RRAM node. */ +#define PARTITION_(x) \ + COND_CODE_1(DT_NODE_HAS_COMPAT(x, fixed_partitions), (DT_FOREACH_CHILD(x, COMMA)), ()) +#define PARTITION(x, ...) DT_FOREACH_CHILD_STATUS_OKAY(x, PARTITION_) +#define RRAM_PARTITION_LIST LIST_DROP_EMPTY(DT_FOREACH_CHILD_VARGS(RRAM_CONTROLLER, PARTITION)) + +#if !IS_EMPTY(RRAM_PARTITION_LIST) + +/* Check that every RRAM partition is within the bounds of its parent RRAM node. */ +FOR_EACH(CHECK_RRAM_PARTITION_WITHIN_PARENT, (;), RRAM_PARTITION_LIST); + +/* Check that no two RRAM partitions are overlapping. */ +FOR_EACH_PAIR(CHECK_NODES_NON_OVERLAPPING, (;), RRAM_PARTITION_LIST); + +#endif diff --git a/soc/arm/nuvoton_npcx/npcx4/soc.h b/soc/arm/nuvoton_npcx/npcx4/soc.h index a9d4e88424b..9c780ca034a 100644 --- a/soc/arm/nuvoton_npcx/npcx4/soc.h +++ b/soc/arm/nuvoton_npcx/npcx4/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX4 SCFG multi-registers */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nuvoton_npcx/npcx7/soc.h b/soc/arm/nuvoton_npcx/npcx7/soc.h index 7099552cec3..9b523ce1b8f 100644 --- a/soc/arm/nuvoton_npcx/npcx7/soc.h +++ b/soc/arm/nuvoton_npcx/npcx7/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX7 SCFG multi-registers offset */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nuvoton_npcx/npcx9/soc.h b/soc/arm/nuvoton_npcx/npcx9/soc.h index 6b6c3f30a44..2ce745650fb 100644 --- a/soc/arm/nuvoton_npcx/npcx9/soc.h +++ b/soc/arm/nuvoton_npcx/npcx9/soc.h @@ -7,9 +7,7 @@ #ifndef _NUVOTON_NPCX_SOC_H_ #define _NUVOTON_NPCX_SOC_H_ -/* CMSIS required definitions */ -#define __FPU_PRESENT CONFIG_CPU_HAS_FPU -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include /* NPCX9 SCFG multi-registers */ #define NPCX_DEVALT_OFFSET(n) (0x010 + n) diff --git a/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series b/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series index ac0428eff53..7279ac8596e 100644 --- a/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mcimx6x_m4/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_IMX_6X_M4 select HAS_IMX_HAL select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU select CLOCK_CONTROL help Enable support for M4 core of i.MX 6SoloX MCU series diff --git a/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series b/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series index be0065cb373..e7ae54bcbda 100644 --- a/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mcimx7_m4/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_IMX7_M4 select SOC_FAMILY_IMX select CLOCK_CONTROL select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX7 M4 MCU series diff --git a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series index dddb12d1b70..f860a7fbd26 100644 --- a/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mimx8mm6_m4/Kconfig.series @@ -9,5 +9,6 @@ config SOC_SERIES_IMX8MM_M4 select CPU_CORTEX_M4 select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX8MM M4 MCU series diff --git a/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series b/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series index c4b16d3fb5c..3933037c3a0 100644 --- a/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series +++ b/soc/arm/nxp_imx/mimx8mq6_m4/Kconfig.series @@ -9,5 +9,6 @@ config SOC_SERIES_IMX8MQ_M4 select CPU_CORTEX_M4 select SOC_FAMILY_IMX select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for i.MX8MQ M4 MCU series diff --git a/soc/arm/nxp_imx/rt/Kconfig.soc b/soc/arm/nxp_imx/rt/Kconfig.soc index 0058993e825..96dcd14dc86 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.soc +++ b/soc/arm/nxp_imx/rt/Kconfig.soc @@ -21,6 +21,7 @@ config SOC_MIMXRT1011 select HAS_MCUX_LPUART select HAS_MCUX_GPT select HAS_MCUX_TRNG + select CPU_HAS_FPU select CPU_HAS_ARM_MPU select INIT_ENET_PLL select HAS_MCUX_USB_EHCI @@ -45,6 +46,7 @@ config SOC_MIMXRT1015 select HAS_MCUX_LPUART select HAS_MCUX_GPT select HAS_MCUX_TRNG + select CPU_HAS_FPU select CPU_HAS_FPU_DOUBLE_PRECISION select CPU_HAS_ARM_MPU select INIT_ENET_PLL @@ -368,6 +370,7 @@ config SOC_MIMXRT1176_CM4 select HAS_MCUX_FLEXSPI select HAS_MCUX_LPUART select HAS_MCUX_GPT + select CPU_HAS_FPU select CPU_HAS_ARM_MPU select INIT_ARM_PLL select INIT_ENET_PLL if NET_L2_ETHERNET && ETH_DRIVER @@ -435,6 +438,7 @@ config SOC_MIMXRT1166_CM4 select HAS_MCUX_FLEXSPI select HAS_MCUX_GPT select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select INIT_ARM_PLL select INIT_ENET_PLL if NET_L2_ETHERNET && ETH_DRIVER select INIT_VIDEO_PLL diff --git a/soc/arm/nxp_kinetis/kl2x/Kconfig.series b/soc/arm/nxp_kinetis/kl2x/Kconfig.series index 53558c81648..3c606c7db27 100644 --- a/soc/arm/nxp_kinetis/kl2x/Kconfig.series +++ b/soc/arm/nxp_kinetis/kl2x/Kconfig.series @@ -9,6 +9,7 @@ config SOC_SERIES_KINETIS_KL2X select CPU_CORTEX_M0PLUS select SOC_FAMILY_KINETIS select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select CLOCK_CONTROL select PLATFORM_SPECIFIC_INIT help diff --git a/soc/arm/nxp_kinetis/kwx/Kconfig.series b/soc/arm/nxp_kinetis/kwx/Kconfig.series index 4b00dd997a9..36ba7b54c21 100644 --- a/soc/arm/nxp_kinetis/kwx/Kconfig.series +++ b/soc/arm/nxp_kinetis/kwx/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_KINETIS_KWX select ARM select SOC_FAMILY_KINETIS select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select CLOCK_CONTROL select PLATFORM_SPECIFIC_INIT help diff --git a/soc/arm/nxp_lpc/lpc11u6x/soc.h b/soc/arm/nxp_lpc/lpc11u6x/soc.h index fd7ffbd5400..ec0abb4faf1 100644 --- a/soc/arm/nxp_lpc/lpc11u6x/soc.h +++ b/soc/arm/nxp_lpc/lpc11u6x/soc.h @@ -19,6 +19,7 @@ #ifndef _ASMLANGUAGE #include +#include #endif /* !_ASMLANGUAGE */ diff --git a/soc/arm/nxp_lpc/lpc51u68/Kconfig.series b/soc/arm/nxp_lpc/lpc51u68/Kconfig.series index 6995de0917a..8b1a9dd18b1 100644 --- a/soc/arm/nxp_lpc/lpc51u68/Kconfig.series +++ b/soc/arm/nxp_lpc/lpc51u68/Kconfig.series @@ -13,6 +13,7 @@ config SOC_SERIES_LPC51U68 select HAS_MCUX_SCTIMER select SOC_FAMILY_LPC select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select PLATFORM_SPECIFIC_INIT help Enable support for LPC LPC51U68 MCU Series diff --git a/soc/arm/nxp_lpc/lpc51u68/soc.h b/soc/arm/nxp_lpc/lpc51u68/soc.h index 45355fb148e..9135c3fed71 100644 --- a/soc/arm/nxp_lpc/lpc51u68/soc.h +++ b/soc/arm/nxp_lpc/lpc51u68/soc.h @@ -10,6 +10,8 @@ #ifndef _ASMLANGUAGE #include +#include + #endif /* !_ASMLANGUAGE*/ #define IOCON_PIO_DIGITAL_EN 0x80u diff --git a/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc index 099dc832d5b..e71bc8f451e 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc54xxx/Kconfig.soc @@ -12,6 +12,7 @@ config SOC_LPC54114_M4 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select PLATFORM_SPECIFIC_INIT select CLOCK_CONTROL select HAS_MCUX_IAP_LEGACY diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index c0341a8e9c5..a80374f2d81 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -35,6 +35,7 @@ config SOC_LPC55S16 config SOC_LPC55S28 bool "SOC_LPC55S28 M33" select CPU_CORTEX_M33 + select CPU_HAS_ARM_SAU select CPU_HAS_ARM_MPU select CPU_HAS_FPU select ARMV8_M_DSP diff --git a/soc/arm/nxp_s32/s32k3/soc.h b/soc/arm/nxp_s32/s32k3/soc.h index bbc53e18023..9e273ac6816 100644 --- a/soc/arm/nxp_s32/s32k3/soc.h +++ b/soc/arm/nxp_s32/s32k3/soc.h @@ -8,6 +8,7 @@ #define _NXP_S32_S32K_SOC_H_ #include +#include #if defined(CONFIG_CMSIS_RTOS_V2) /* diff --git a/soc/arm/quicklogic_eos_s3/Kconfig.soc b/soc/arm/quicklogic_eos_s3/Kconfig.soc index cb5fd170870..e555933430b 100644 --- a/soc/arm/quicklogic_eos_s3/Kconfig.soc +++ b/soc/arm/quicklogic_eos_s3/Kconfig.soc @@ -7,4 +7,5 @@ config SOC_EOS_S3 select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_SYSTICK select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select EOS_S3_HAL diff --git a/soc/arm/renesas_ra/common/ra_common_soc.h b/soc/arm/renesas_ra/common/ra_common_soc.h index 60559793743..f76c4c26fc0 100644 --- a/soc/arm/renesas_ra/common/ra_common_soc.h +++ b/soc/arm/renesas_ra/common/ra_common_soc.h @@ -11,6 +11,8 @@ extern "C" { #endif +#include + #ifdef __cplusplus } #endif diff --git a/soc/arm/renesas_smartbond/da1469x/Kconfig.series b/soc/arm/renesas_smartbond/da1469x/Kconfig.series index a3a9e569460..c3672a9ecaf 100644 --- a/soc/arm/renesas_smartbond/da1469x/Kconfig.series +++ b/soc/arm/renesas_smartbond/da1469x/Kconfig.series @@ -8,6 +8,7 @@ config SOC_SERIES_DA1469X select CPU_HAS_FPU select CPU_HAS_ARM_MPU select CPU_CORTEX_M_HAS_SYSTICK + select ARMV8_M_DSP select SOC_FAMILY_SMARTBOND select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select CLOCK_CONTROL diff --git a/soc/arm/rpi_pico/rp2/soc.h b/soc/arm/rpi_pico/rp2/soc.h index b38d2edf461..0eef4cf92a2 100644 --- a/soc/arm/rpi_pico/rp2/soc.h +++ b/soc/arm/rpi_pico/rp2/soc.h @@ -12,8 +12,6 @@ #ifndef _RPI_PICO_RP2040_SOC_H_ #define _RPI_PICO_RP2040_SOC_H_ - -#define __VTOR_PRESENT CONFIG_CPU_CORTEX_M_HAS_VTOR -#define __MPU_PRESENT CONFIG_CPU_HAS_ARM_MPU +#include #endif /* _RPI_PICO_RP2040_SOC_H_ */ diff --git a/soc/arm/silabs_exx32/efm32hg/Kconfig.series b/soc/arm/silabs_exx32/efm32hg/Kconfig.series index 33793b5386d..d17c24fbcdb 100644 --- a/soc/arm/silabs_exx32/efm32hg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32hg/Kconfig.series @@ -9,6 +9,7 @@ config SOC_SERIES_EFM32HG select CPU_CORTEX_M0PLUS select SOC_FAMILY_EXX32 select CPU_CORTEX_M_HAS_SYSTICK + select CPU_CORTEX_M_HAS_VTOR select HAS_SILABS_GECKO select SOC_GECKO_CMU select SOC_GECKO_GPIO diff --git a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series index 146493469e8..731658d29e3 100644 --- a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_EFR32MG21 select ARMV8_M_DSP select CPU_HAS_FPU select CPU_HAS_ARM_MPU + select CPU_HAS_ARM_SAU select SOC_FAMILY_EXX32 select SOC_GECKO_HAS_RADIO select SOC_GECKO_SERIES2 diff --git a/soc/arm/st_stm32/stm32mp1/Kconfig.series b/soc/arm/st_stm32/stm32mp1/Kconfig.series index 0c6580e84cc..c1576a7ee17 100644 --- a/soc/arm/st_stm32/stm32mp1/Kconfig.series +++ b/soc/arm/st_stm32/stm32mp1/Kconfig.series @@ -11,6 +11,7 @@ config SOC_SERIES_STM32MP1X select SOC_FAMILY_STM32 select HAS_STM32CUBE select CPU_HAS_ARM_MPU + select CPU_HAS_FPU select OPENAMP_RSC_TABLE if RAM_CONSOLE help Enable support for STM32MP1 MPU series diff --git a/soc/arm/ti_k3/am62x_m4/soc.h b/soc/arm/ti_k3/am62x_m4/soc.h index 01ff4b07080..2fd6537b984 100644 --- a/soc/arm/ti_k3/am62x_m4/soc.h +++ b/soc/arm/ti_k3/am62x_m4/soc.h @@ -7,6 +7,8 @@ #ifndef __SOC_H_ #define __SOC_H_ +#include + #include #endif /* __SOC_H */ diff --git a/soc/arm/ti_lm3s6965/soc.h b/soc/arm/ti_lm3s6965/soc.h index bef939013ba..3c353b1a79b 100644 --- a/soc/arm/ti_lm3s6965/soc.h +++ b/soc/arm/ti_lm3s6965/soc.h @@ -15,6 +15,7 @@ #ifndef _BOARD__H_ #define _BOARD__H_ +#include #include /* default system clock */ diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h b/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h index a1d3504b986..fdc9214732c 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/soc.h @@ -7,6 +7,8 @@ #ifndef TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ #define TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ +#include + /* CMSIS required values */ typedef enum { Reset_IRQn = -15, @@ -27,4 +29,6 @@ typedef enum { #define __Vendor_SysTickConfig 0 #define __FPU_PRESENT 1 +#include + #endif /* TI_SIMPLELINK_CC13X2_CC26X2_SOC_H_ */ diff --git a/soc/arm/ti_simplelink/cc32xx/soc.h b/soc/arm/ti_simplelink/cc32xx/soc.h index 9c841e0e4b0..e18dfce626a 100644 --- a/soc/arm/ti_simplelink/cc32xx/soc.h +++ b/soc/arm/ti_simplelink/cc32xx/soc.h @@ -7,6 +7,8 @@ #ifndef TI_SIMPLELINK_CC32XX_SOC_H_ #define TI_SIMPLELINK_CC32XX_SOC_H_ +#include + #include #include @@ -38,4 +40,6 @@ typedef enum { #define __NVIC_PRIO_BITS NUM_IRQ_PRIO_BITS #define __Vendor_SysTickConfig 0 /* Default to standard SysTick */ +#include + #endif /* TI_SIMPLELINK_CC32XX_SOC_H_ */ diff --git a/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series b/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series index 6bb0043ff90..8af48672ed2 100644 --- a/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series +++ b/soc/arm/ti_simplelink/msp432p4xx/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_MSP432P4XX select DYNAMIC_INTERRUPTS select SOC_FAMILY_TISIMPLELINK select CPU_HAS_FPU + select CPU_HAS_ARM_MPU help Enable support for TI SimpleLink MSP432P4XX. diff --git a/soc/common/CMakeLists.txt b/soc/common/CMakeLists.txt new file mode 100644 index 00000000000..d9abad218cd --- /dev/null +++ b/soc/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_SOC_FAMILY_NRF nordic_nrf) diff --git a/soc/common/nordic_nrf/CMakeLists.txt b/soc/common/nordic_nrf/CMakeLists.txt new file mode 100644 index 00000000000..6f397a07fab --- /dev/null +++ b/soc/common/nordic_nrf/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/common/nordic_nrf/Kconfig.peripherals similarity index 69% rename from soc/arm/nordic_nrf/Kconfig.peripherals rename to soc/common/nordic_nrf/Kconfig.peripherals index 3aacc35a08a..a6b62428626 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/common/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)) @@ -63,14 +65,35 @@ config HAS_HW_NRF_EGU4 config HAS_HW_NRF_EGU5 def_bool $(dt_nodelabel_enabled_with_compat,egu5,$(DT_COMPAT_NORDIC_NRF_EGU)) +config HAS_HW_NRF_EGU020 + def_bool $(dt_nodelabel_enabled_with_compat,egu020,$(DT_COMPAT_NORDIC_NRF_EGU)) + config HAS_HW_NRF_GPIO0 def_bool $(dt_nodelabel_enabled_with_compat,gpio0,$(DT_COMPAT_NORDIC_NRF_GPIO)) config HAS_HW_NRF_GPIO1 def_bool $(dt_nodelabel_enabled_with_compat,gpio1,$(DT_COMPAT_NORDIC_NRF_GPIO)) -config HAS_HW_NRF_GPIOTE - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) +config HAS_HW_NRF_GPIOTE0 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote0,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE1 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote1,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE20 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote20,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE30 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote30,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE130 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote130,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GPIOTE131 + def_bool $(dt_nodelabel_enabled_with_compat,gpiote131,$(DT_COMPAT_NORDIC_NRF_GPIOTE)) + +config HAS_HW_NRF_GRTC + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_GRTC)) config HAS_HW_NRF_I2S0 def_bool $(dt_nodelabel_enabled_with_compat,i2s0,$(DT_COMPAT_NORDIC_NRF_I2S)) @@ -180,6 +203,12 @@ config HAS_HW_NRF_RTC1 config HAS_HW_NRF_RTC2 def_bool $(dt_nodelabel_enabled_with_compat,rtc2,$(DT_COMPAT_NORDIC_NRF_RTC)) +config HAS_HW_NRF_RTC130 + def_bool $(dt_nodelabel_enabled_with_compat,rtc130,$(DT_COMPAT_NORDIC_NRF_RTC)) + +config HAS_HW_NRF_RTC131 + def_bool $(dt_nodelabel_enabled_with_compat,rtc131,$(DT_COMPAT_NORDIC_NRF_RTC)) + config HAS_HW_NRF_SAADC def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_SAADC)) @@ -303,6 +332,66 @@ config HAS_HW_NRF_TIMER3 config HAS_HW_NRF_TIMER4 def_bool $(dt_nodelabel_enabled_with_compat,timer4,$(DT_COMPAT_NORDIC_NRF_TIMER)) +config HAS_HW_NRF_TIMER00 + def_bool $(dt_nodelabel_enabled_with_compat,timer00,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER10 + def_bool $(dt_nodelabel_enabled_with_compat,timer10,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER20 + def_bool $(dt_nodelabel_enabled_with_compat,timer20,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER21 + def_bool $(dt_nodelabel_enabled_with_compat,timer21,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER22 + def_bool $(dt_nodelabel_enabled_with_compat,timer22,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER23 + def_bool $(dt_nodelabel_enabled_with_compat,timer23,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER24 + def_bool $(dt_nodelabel_enabled_with_compat,timer24,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER020 + def_bool $(dt_nodelabel_enabled_with_compat,timer020,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER021 + def_bool $(dt_nodelabel_enabled_with_compat,timer021,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER022 + def_bool $(dt_nodelabel_enabled_with_compat,timer022,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER120 + def_bool $(dt_nodelabel_enabled_with_compat,timer120,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER121 + def_bool $(dt_nodelabel_enabled_with_compat,timer121,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER130 + def_bool $(dt_nodelabel_enabled_with_compat,timer130,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER131 + def_bool $(dt_nodelabel_enabled_with_compat,timer131,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER132 + def_bool $(dt_nodelabel_enabled_with_compat,timer132,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER133 + def_bool $(dt_nodelabel_enabled_with_compat,timer133,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER134 + def_bool $(dt_nodelabel_enabled_with_compat,timer134,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER135 + def_bool $(dt_nodelabel_enabled_with_compat,timer135,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER136 + def_bool $(dt_nodelabel_enabled_with_compat,timer136,$(DT_COMPAT_NORDIC_NRF_TIMER)) + +config HAS_HW_NRF_TIMER137 + def_bool $(dt_nodelabel_enabled_with_compat,timer137,$(DT_COMPAT_NORDIC_NRF_TIMER)) + config HAS_HW_NRF_TWI0 def_bool $(dt_nodelabel_enabled_with_compat,i2c0,$(DT_COMPAT_NORDIC_NRF_TWI)) @@ -387,6 +476,48 @@ config HAS_HW_NRF_UARTE2 config HAS_HW_NRF_UARTE3 def_bool $(dt_nodelabel_enabled_with_compat,uart3,$(DT_COMPAT_NORDIC_NRF_UARTE)) +config HAS_HW_NRF_UARTE00 + def_bool $(dt_nodelabel_enabled_with_compat,uart00,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE20 + def_bool $(dt_nodelabel_enabled_with_compat,uart20,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE21 + def_bool $(dt_nodelabel_enabled_with_compat,uart21,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE22 + def_bool $(dt_nodelabel_enabled_with_compat,uart22,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE30 + def_bool $(dt_nodelabel_enabled_with_compat,uart30,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE120 + def_bool $(dt_nodelabel_enabled_with_compat,uart120,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE130 + def_bool $(dt_nodelabel_enabled_with_compat,uart130,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE131 + def_bool $(dt_nodelabel_enabled_with_compat,uart131,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE132 + def_bool $(dt_nodelabel_enabled_with_compat,uart132,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE133 + def_bool $(dt_nodelabel_enabled_with_compat,uart133,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE134 + def_bool $(dt_nodelabel_enabled_with_compat,uart134,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE135 + def_bool $(dt_nodelabel_enabled_with_compat,uart135,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE136 + def_bool $(dt_nodelabel_enabled_with_compat,uart136,$(DT_COMPAT_NORDIC_NRF_UARTE)) + +config HAS_HW_NRF_UARTE137 + def_bool $(dt_nodelabel_enabled_with_compat,uart137,$(DT_COMPAT_NORDIC_NRF_UARTE)) + config HAS_HW_NRF_USBD def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_USBD)) @@ -401,3 +532,18 @@ config HAS_HW_NRF_WDT0 config HAS_HW_NRF_WDT1 def_bool $(dt_nodelabel_enabled_with_compat,wdt1,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT30 + def_bool $(dt_nodelabel_enabled_with_compat,wdt30,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT31 + def_bool $(dt_nodelabel_enabled_with_compat,wdt31,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT130 + def_bool $(dt_nodelabel_enabled_with_compat,wdt130,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT131 + def_bool $(dt_nodelabel_enabled_with_compat,wdt131,$(DT_COMPAT_NORDIC_NRF_WDT)) + +config HAS_HW_NRF_WDT132 + def_bool $(dt_nodelabel_enabled_with_compat,wdt132,$(DT_COMPAT_NORDIC_NRF_WDT)) diff --git a/soc/arm/nordic_nrf/common/pinctrl_soc.h b/soc/common/nordic_nrf/pinctrl_soc.h similarity index 100% rename from soc/arm/nordic_nrf/common/pinctrl_soc.h rename to soc/common/nordic_nrf/pinctrl_soc.h diff --git a/soc/riscv/CMakeLists.txt b/soc/riscv/CMakeLists.txt index b826da926ca..79d115704b2 100644 --- a/soc/riscv/CMakeLists.txt +++ b/soc/riscv/CMakeLists.txt @@ -1,5 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 +add_subdirectory(common) + if(SOC_FAMILY) add_subdirectory(${SOC_FAMILY}) else() diff --git a/soc/riscv/andes_v5/CMakeLists.txt b/soc/riscv/andes_v5/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/andes_v5/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/andes_v5/Kconfig b/soc/riscv/andes_v5/Kconfig new file mode 100644 index 00000000000..f3c78ab7f81 --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_ANDES_V5 + bool + +if SOC_FAMILY_ANDES_V5 + +config SOC_FAMILY + string + default "andes_v5" + +source "soc/riscv/andes_v5/*/Kconfig.soc" + +endif # SOC_FAMILY_ANDES_V5 diff --git a/soc/riscv/andes_v5/Kconfig.defconfig b/soc/riscv/andes_v5/Kconfig.defconfig new file mode 100644 index 00000000000..6213f28d2cb --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/andes_v5/*/Kconfig.defconfig.series" diff --git a/soc/riscv/andes_v5/Kconfig.soc b/soc/riscv/andes_v5/Kconfig.soc new file mode 100644 index 00000000000..9efb4781934 --- /dev/null +++ b/soc/riscv/andes_v5/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/andes_v5/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt b/soc/riscv/andes_v5/ae350/CMakeLists.txt similarity index 82% rename from soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt rename to soc/riscv/andes_v5/ae350/CMakeLists.txt index 21268312347..b8eac026dfb 100644 --- a/soc/riscv/riscv-privileged/andes_v5/CMakeLists.txt +++ b/soc/riscv/andes_v5/ae350/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_include_directories(${CONFIG_SOC}) +zephyr_include_directories(.) zephyr_sources( start.S @@ -24,6 +24,6 @@ if(CONFIG_SOC_ANDES_V5_EXECIT) 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 "") +if(CONFIG_SOC_ANDES_AE350) + set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "") endif() diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 similarity index 88% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 rename to soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 index 5d652057a38..fee73684b71 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae350 +++ b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae350 @@ -1,7 +1,7 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_RISCV_ANDES_AE350 +if SOC_ANDES_AE350 config SOC default "ae350" @@ -25,4 +25,4 @@ config MP_MAX_NUM_CPUS default 1 range 1 8 -endif # SOC_RISCV_ANDES_AE350 +endif # SOC_ANDES_AE350 diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.series similarity index 76% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series rename to soc/riscv/andes_v5/ae350/Kconfig.defconfig.series index c6436807825..7b9bbc3eadb 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.series +++ b/soc/riscv/andes_v5/ae350/Kconfig.defconfig.series @@ -1,15 +1,15 @@ # Copyright (c) 2021 Andes Technology Corporation # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_ANDES_V5 +if SOC_SERIES_ANDES_AE350 # Kconfig picks the first default with a satisfied condition. # SoC defaults should be parsed before SoC Series defaults, because SoCs usually # overrides SoC Series values. -source "soc/riscv/riscv-privileged/andes_v5/Kconfig.defconfig.ae*" +source "soc/riscv/andes_v5/ae350/Kconfig.defconfig.ae*" config SOC_SERIES - default "andes_v5" + default "ae350" config SYS_CLOCK_HW_CYCLES_PER_SEC default 60000000 @@ -24,12 +24,6 @@ config RISCV_GENERIC_TOOLCHAIN config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -45,4 +39,4 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 64 -endif # SOC_SERIES_RISCV_ANDES_V5 +endif # SOC_SERIES_ANDES_AE350 diff --git a/soc/riscv/andes_v5/ae350/Kconfig.series b/soc/riscv/andes_v5/ae350/Kconfig.series new file mode 100644 index 00000000000..c2e9b40bfb7 --- /dev/null +++ b/soc/riscv/andes_v5/ae350/Kconfig.series @@ -0,0 +1,11 @@ +# Copyright (c) 2021 Andes Technology Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_ANDES_AE350 + bool "Andes V5 AE350 SoC Series Implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_ANDES_V5 + help + Enable support for Andes V5 AE350 SoC Series diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.soc b/soc/riscv/andes_v5/ae350/Kconfig.soc similarity index 95% rename from soc/riscv/riscv-privileged/andes_v5/Kconfig.soc rename to soc/riscv/andes_v5/ae350/Kconfig.soc index 19f215e2c5a..1731cc08f51 100644 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.soc +++ b/soc/riscv/andes_v5/ae350/Kconfig.soc @@ -3,9 +3,9 @@ choice prompt "Andes V5 SoC Selection" -depends on SOC_SERIES_RISCV_ANDES_V5 +depends on SOC_SERIES_ANDES_AE350 -config SOC_RISCV_ANDES_AE350 +config SOC_ANDES_AE350 bool "Andes AE350 SoC implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR @@ -18,7 +18,7 @@ config SOC_RISCV_ANDES_AE350 endchoice -if SOC_SERIES_RISCV_ANDES_V5 +if SOC_SERIES_ANDES_AE350 choice prompt "Base CPU ISA options" @@ -121,4 +121,4 @@ config SOC_ANDES_V5_IOCP between cache and external non-caching master, such as DMA controller. -endif # SOC_SERIES_RISCV_ANDES_V5 +endif # SOC_SERIES_ANDES_AE350 diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/execit.ld b/soc/riscv/andes_v5/ae350/common_linker/execit.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/execit.ld rename to soc/riscv/andes_v5/ae350/common_linker/execit.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/init.ld b/soc/riscv/andes_v5/ae350/common_linker/init.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/init.ld rename to soc/riscv/andes_v5/ae350/common_linker/init.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/common_linker/ram_start_nonzero.ld b/soc/riscv/andes_v5/ae350/common_linker/ram_start_nonzero.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/common_linker/ram_start_nonzero.ld rename to soc/riscv/andes_v5/ae350/common_linker/ram_start_nonzero.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/l2_cache.c b/soc/riscv/andes_v5/ae350/l2_cache.c similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/l2_cache.c rename to soc/riscv/andes_v5/ae350/l2_cache.c diff --git a/soc/riscv/riscv-privileged/andes_v5/ae350/linker.ld b/soc/riscv/andes_v5/ae350/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/ae350/linker.ld rename to soc/riscv/andes_v5/ae350/linker.ld diff --git a/soc/riscv/riscv-privileged/andes_v5/pma.c b/soc/riscv/andes_v5/ae350/pma.c similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/pma.c rename to soc/riscv/andes_v5/ae350/pma.c diff --git a/soc/riscv/riscv-privileged/andes_v5/ae350/soc.h b/soc/riscv/andes_v5/ae350/soc.h similarity index 93% rename from soc/riscv/riscv-privileged/andes_v5/ae350/soc.h rename to soc/riscv/andes_v5/ae350/soc.h index 95ea7486fd3..fd3a9e63c0d 100644 --- a/soc/riscv/riscv-privileged/andes_v5/ae350/soc.h +++ b/soc/riscv/andes_v5/ae350/soc.h @@ -11,8 +11,6 @@ #ifndef __RISCV_ANDES_AE350_SOC_H_ #define __RISCV_ANDES_AE350_SOC_H_ -#include - /* Include CSRs available for Andes V5 SoCs */ #include "soc_v5.h" diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_context.h b/soc/riscv/andes_v5/ae350/soc_context.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_context.h rename to soc/riscv/andes_v5/ae350/soc_context.h diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_irq.S b/soc/riscv/andes_v5/ae350/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_irq.S rename to soc/riscv/andes_v5/ae350/soc_irq.S diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_offsets.h b/soc/riscv/andes_v5/ae350/soc_offsets.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_offsets.h rename to soc/riscv/andes_v5/ae350/soc_offsets.h diff --git a/soc/riscv/riscv-privileged/andes_v5/soc_v5.h b/soc/riscv/andes_v5/ae350/soc_v5.h similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/soc_v5.h rename to soc/riscv/andes_v5/ae350/soc_v5.h diff --git a/soc/riscv/riscv-privileged/andes_v5/start.S b/soc/riscv/andes_v5/ae350/start.S similarity index 100% rename from soc/riscv/riscv-privileged/andes_v5/start.S rename to soc/riscv/andes_v5/ae350/start.S diff --git a/soc/riscv/common/CMakeLists.txt b/soc/riscv/common/CMakeLists.txt new file mode 100644 index 00000000000..91ef5c975b9 --- /dev/null +++ b/soc/riscv/common/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory_ifdef(CONFIG_RISCV_PRIVILEGED riscv-privileged) diff --git a/soc/riscv/common/Kconfig b/soc/riscv/common/Kconfig new file mode 100644 index 00000000000..91f2c5cf80a --- /dev/null +++ b/soc/riscv/common/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +source "soc/riscv/common/riscv-privileged/Kconfig" diff --git a/soc/riscv/riscv-privileged/common/CMakeLists.txt b/soc/riscv/common/riscv-privileged/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/common/CMakeLists.txt rename to soc/riscv/common/riscv-privileged/CMakeLists.txt diff --git a/soc/riscv/common/riscv-privileged/Kconfig b/soc/riscv/common/riscv-privileged/Kconfig new file mode 100644 index 00000000000..10c2e37712b --- /dev/null +++ b/soc/riscv/common/riscv-privileged/Kconfig @@ -0,0 +1,11 @@ +# Configuration options for riscv SOCs supporting the riscv privileged +# architecture specification + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config RISCV_VECTORED_MODE + bool "Should the SOC use vectored mode" + depends on RISCV_PRIVILEGED + help + Should the SOC use vectored mode. diff --git a/soc/riscv/riscv-privileged/common/soc_common_irq.c b/soc/riscv/common/riscv-privileged/soc_common_irq.c similarity index 100% rename from soc/riscv/riscv-privileged/common/soc_common_irq.c rename to soc/riscv/common/riscv-privileged/soc_common_irq.c diff --git a/soc/riscv/riscv-privileged/common/soc_irq.S b/soc/riscv/common/riscv-privileged/soc_irq.S similarity index 56% rename from soc/riscv/riscv-privileged/common/soc_irq.S rename to soc/riscv/common/riscv-privileged/soc_irq.S index 73fc24431d5..acf7e724aea 100644 --- a/soc/riscv/riscv-privileged/common/soc_irq.S +++ b/soc/riscv/common/riscv-privileged/soc_irq.S @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* * __soc_handle_irq is defined as .weak to allow re-implementation by @@ -32,30 +32,3 @@ SECTION_FUNC(exception.other, __soc_handle_irq) /* Return */ ret - -/* - * __soc_is_irq is defined as .weak to allow re-implementation by - * SOCs that do not truly follow the riscv privilege specification. - */ -WTEXT(__soc_is_irq) - -/* - * SOC-specific function to determine if the exception is the result of a - * an interrupt or an exception - * return 1 (interrupt) or 0 (exception) - * - */ -SECTION_FUNC(exception.other, __soc_is_irq) - /* Read mcause and check if interrupt bit is set */ - csrr t0, mcause - li t1, SOC_MCAUSE_IRQ_MASK - and t0, t0, t1 - - /* If interrupt bit is not set, return with 0 */ - addi a0, x0, 0 - beqz t0, not_interrupt - addi a0, a0, 1 - -not_interrupt: - /* return */ - ret diff --git a/soc/riscv/riscv-privileged/common/vector.S b/soc/riscv/common/riscv-privileged/vector.S similarity index 100% rename from soc/riscv/riscv-privileged/common/vector.S rename to soc/riscv/common/riscv-privileged/vector.S diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt b/soc/riscv/efinix_sapphire/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/efinix-sapphire/CMakeLists.txt rename to soc/riscv/efinix_sapphire/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series b/soc/riscv/efinix_sapphire/Kconfig.defconfig similarity index 58% rename from soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series rename to soc/riscv/efinix_sapphire/Kconfig.defconfig index 233428931a3..95a33b4ab82 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.defconfig.series +++ b/soc/riscv/efinix_sapphire/Kconfig.defconfig @@ -1,25 +1,18 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_EFINIX_SAPPHIRE +if SOC_EFINIX_SAPPHIRE -config SOC_SERIES - default "efinix-sapphire" +config SOC + default "efinix_sapphire" config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 -config RISCV_HAS_CPU_IDLE - bool - config RISCV_SOC_INTERRUPT_INIT bool default y -config RISCV_HAS_PLIC - bool - default y - config NUM_IRQS int default 36 @@ -27,4 +20,4 @@ config NUM_IRQS config 2ND_LVL_INTR_00_OFFSET default 11 -endif # SOC_SERIES_EFINIX_SAPPHIRE +endif # SOC_EFINIX_SAPPHIRE diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc b/soc/riscv/efinix_sapphire/Kconfig.soc similarity index 72% rename from soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc rename to soc/riscv/efinix_sapphire/Kconfig.soc index dba8491b8bd..4bad3b5cb79 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.soc +++ b/soc/riscv/efinix_sapphire/Kconfig.soc @@ -1,11 +1,7 @@ # Copyright (c) 2023 Efinix Inc. # SPDX-License-Identifier: Apache-2.0 -choice - prompt "Efinix SoC selection" - depends on SOC_SERIES_EFINIX_SAPPHIRE - -config SOC_RISCV32_EFINIX_SAPPHIRE +config SOC_EFINIX_SAPPHIRE bool "Efinix Sapphire VexRiscv system implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR @@ -14,5 +10,6 @@ config SOC_RISCV32_EFINIX_SAPPHIRE select RISCV_ISA_EXT_A select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/soc.h b/soc/riscv/efinix_sapphire/soc.h similarity index 93% rename from soc/riscv/riscv-privileged/efinix-sapphire/soc.h rename to soc/riscv/efinix_sapphire/soc.h index 1d566e2f293..5530af16729 100644 --- a/soc/riscv/riscv-privileged/efinix-sapphire/soc.h +++ b/soc/riscv/efinix_sapphire/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV32_EFINIX_SAPPHIRE_SOC_H_ #define __RISCV32_EFINIX_SAPPHIRE_SOC_H_ -#include "soc_common.h" #include #include diff --git a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt index e97f71751ef..d6772eacbfc 100644 --- a/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt +++ b/soc/riscv/espressif_esp32/esp32c3/CMakeLists.txt @@ -1,7 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_sources( - idle.c vectors.S soc_irq.S soc_irq.c diff --git a/soc/riscv/espressif_esp32/esp32c3/idle.c b/soc/riscv/espressif_esp32/esp32c3/idle.c deleted file mode 100644 index 1bfb2832187..00000000000 --- a/soc/riscv/espressif_esp32/esp32c3/idle.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -/** - * @brief Power save idle routine - * - * This function will be called by the kernel idle loop or possibly within - * an implementation of _pm_save_idle in the kernel when the - * '_pm_save_flag' variable is non-zero. - */ -void arch_cpu_idle(void) -{ - /* curiously it arrives here with the interrupts masked - * so umask it before wait for an event - */ - arch_irq_unlock(MSTATUS_IEN); - - /* Wait for interrupt */ - __asm__ volatile("wfi"); -} diff --git a/soc/riscv/espressif_esp32/esp32c3/soc.h b/soc/riscv/espressif_esp32/esp32c3/soc.h index a3709819abc..68fb6fdb1ce 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc.h +++ b/soc/riscv/espressif_esp32/esp32c3/soc.h @@ -16,20 +16,6 @@ #include "esp32c3/clk.h" #endif -/* IRQ numbers */ -#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ -#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */ -#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ - -/* ECALL Exception numbers */ -#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ -#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ - -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 31) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF - #ifndef _ASMLANGUAGE void __esp_platform_start(void); diff --git a/soc/riscv/espressif_esp32/esp32c3/soc_irq.S b/soc/riscv/espressif_esp32/esp32c3/soc_irq.S index c1ad164c153..6ce11ae6a81 100644 --- a/soc/riscv/espressif_esp32/esp32c3/soc_irq.S +++ b/soc/riscv/espressif_esp32/esp32c3/soc_irq.S @@ -7,15 +7,9 @@ #include /* Exports */ -GTEXT(__soc_is_irq) GTEXT(__soc_handle_irq) GTEXT(soc_intr_get_next_source) -SECTION_FUNC(exception.other, __soc_is_irq) - csrr a0, mcause - srli a0, a0, 31 - ret - SECTION_FUNC(exception.other, __soc_handle_irq) addi sp, sp,-4 sw ra, 0x00(sp) diff --git a/soc/riscv/gd_gd32/CMakeLists.txt b/soc/riscv/gd_gd32/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/gd_gd32/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/gd_gd32/Kconfig b/soc/riscv/gd_gd32/Kconfig new file mode 100644 index 00000000000..46f2dd0b1d6 --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_GD32 + bool + +if SOC_FAMILY_GD32 + +config SOC_FAMILY + string + default "gd_gd32" + +source "soc/riscv/gd_gd32/*/Kconfig.soc" + +endif # SOC_FAMILY_GIGADEVICE_GD32 diff --git a/soc/riscv/gd_gd32/Kconfig.defconfig b/soc/riscv/gd_gd32/Kconfig.defconfig new file mode 100644 index 00000000000..2be284db7ea --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/gd_gd32/*/Kconfig.defconfig.series" diff --git a/soc/riscv/gd_gd32/Kconfig.soc b/soc/riscv/gd_gd32/Kconfig.soc new file mode 100644 index 00000000000..09d7d5d627e --- /dev/null +++ b/soc/riscv/gd_gd32/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/gd_gd32/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt b/soc/riscv/gd_gd32/gd32vf103/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/CMakeLists.txt rename to soc/riscv/gd_gd32/gd32vf103/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 similarity index 79% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 index 1e93f2703b2..94af3ff773c 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103 +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103 @@ -14,21 +14,15 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC # The CPU frequency is set to the maximum value of 108MHz by default. default 27000000 -config RISCV_SOC_MCAUSE_EXCEPTION_MASK - default $(dt_node_int_prop_hex,/cpus/cpu@0,mcause-exception-mask) +config RISCV_MCAUSE_EXCEPTION_MASK + default 0xFFF config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y -config RISCV_HAS_PLIC - default n - config NUM_IRQS default 87 if NUCLEI_ECLIC default 16 if !NUCLEI_ECLIC diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series similarity index 72% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series index 061b53b2514..17ab7a87c39 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.series +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.series @@ -3,7 +3,7 @@ if SOC_SERIES_GD32VF103 -source "soc/riscv/riscv-privileged/gd32vf103/Kconfig.defconfig.gd32vf103*" +source "soc/riscv/gd_gd32/gd32vf103/Kconfig.defconfig.gd32vf103*" config SOC_SERIES default "gd32vf103" diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.series b/soc/riscv/gd_gd32/gd32vf103/Kconfig.series similarity index 90% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.series rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.series index 3922bf19bdd..e50567e0798 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.series +++ b/soc/riscv/gd_gd32/gd32vf103/Kconfig.series @@ -6,7 +6,7 @@ config SOC_SERIES_GD32VF103 bool "GigaDevice GD32VF103 series SoC implementation" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED select ATOMIC_OPERATIONS_C select INCLUDE_RESET_VECTOR select BUILD_OUTPUT_HEX @@ -15,6 +15,6 @@ config SOC_SERIES_GD32VF103 select GD32_HAS_IRC_40K select HAS_GD32_HAL select RISCV_HAS_CLIC - + select SOC_FAMILY_GD32 help Enable support for GigaDevice GD32VF1 series SoC diff --git a/soc/riscv/riscv-privileged/gd32vf103/Kconfig.soc b/soc/riscv/gd_gd32/gd32vf103/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/Kconfig.soc rename to soc/riscv/gd_gd32/gd32vf103/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/gd32vf103/entry.S b/soc/riscv/gd_gd32/gd32vf103/entry.S similarity index 97% rename from soc/riscv/riscv-privileged/gd32vf103/entry.S rename to soc/riscv/gd_gd32/gd32vf103/entry.S index 5f8af0d691f..41cc6cc686b 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/entry.S +++ b/soc/riscv/gd_gd32/gd32vf103/entry.S @@ -4,9 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "nuclei_csr.h" + #include #include -#include GTEXT(__nuclei_start) SECTION_FUNC(vectors, __nuclei_start) diff --git a/soc/riscv/riscv-privileged/gd32vf103/gd32_regs.h b/soc/riscv/gd_gd32/gd32vf103/gd32_regs.h similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/gd32_regs.h rename to soc/riscv/gd_gd32/gd32vf103/gd32_regs.h diff --git a/soc/riscv/riscv-privileged/common/nuclei/nuclei_csr.h b/soc/riscv/gd_gd32/gd32vf103/nuclei_csr.h similarity index 100% rename from soc/riscv/riscv-privileged/common/nuclei/nuclei_csr.h rename to soc/riscv/gd_gd32/gd32vf103/nuclei_csr.h diff --git a/soc/riscv/riscv-privileged/gd32vf103/pinctrl_soc.h b/soc/riscv/gd_gd32/gd32vf103/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/pinctrl_soc.h rename to soc/riscv/gd_gd32/gd32vf103/pinctrl_soc.h diff --git a/soc/riscv/riscv-privileged/gd32vf103/soc.c b/soc/riscv/gd_gd32/gd32vf103/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/gd32vf103/soc.c rename to soc/riscv/gd_gd32/gd32vf103/soc.c diff --git a/soc/riscv/riscv-privileged/gd32vf103/soc.h b/soc/riscv/gd_gd32/gd32vf103/soc.h similarity index 92% rename from soc/riscv/riscv-privileged/gd32vf103/soc.h rename to soc/riscv/gd_gd32/gd32vf103/soc.h index 14cdd6b733c..ad2add6fa80 100644 --- a/soc/riscv/riscv-privileged/gd32vf103/soc.h +++ b/soc/riscv/gd_gd32/gd32vf103/soc.h @@ -11,6 +11,4 @@ #ifndef RISCV_GD32VF103_SOC_H_ #define RISCV_GD32VF103_SOC_H_ -#include - #endif /* RISCV_GD32VF103_SOC_H */ diff --git a/soc/riscv/intel_niosv/CMakeLists.txt b/soc/riscv/intel_niosv/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/intel_niosv/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/intel_niosv/Kconfig b/soc/riscv/intel_niosv/Kconfig new file mode 100644 index 00000000000..b841d19c922 --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_INTEL_NIOSV + bool + +if SOC_FAMILY_INTEL_NIOSV + +config SOC_FAMILY + string + default "intel_niosv" + +source "soc/riscv/intel_niosv/*/Kconfig.soc" + +endif # SOC_FAMILY_INTEL_NIOSV diff --git a/soc/riscv/intel_niosv/Kconfig.defconfig b/soc/riscv/intel_niosv/Kconfig.defconfig new file mode 100644 index 00000000000..2afa0f7e0e6 --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/intel_niosv/*/Kconfig.defconfig.series" diff --git a/soc/riscv/intel_niosv/Kconfig.soc b/soc/riscv/intel_niosv/Kconfig.soc new file mode 100644 index 00000000000..8567429c61f --- /dev/null +++ b/soc/riscv/intel_niosv/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/intel_niosv/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/niosv/CMakeLists.txt b/soc/riscv/intel_niosv/niosv/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/niosv/CMakeLists.txt rename to soc/riscv/intel_niosv/niosv/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series b/soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series similarity index 86% rename from soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series rename to soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series index 532a67959d2..15e98314c89 100644 --- a/soc/riscv/riscv-privileged/niosv/Kconfig.defconfig.series +++ b/soc/riscv/intel_niosv/niosv/Kconfig.defconfig.series @@ -12,13 +12,10 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config NUM_IRQS # Platform interrupts IRQs index start from index 16 default 32 -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y config RISCV_SOC_INTERRUPT_INIT default y -endif # SOC_SERIES_NIOSV +endif # SOC_NIOSV diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.series b/soc/riscv/intel_niosv/niosv/Kconfig.series similarity index 77% rename from soc/riscv/riscv-privileged/niosv/Kconfig.series rename to soc/riscv/intel_niosv/niosv/Kconfig.series index 7de17cf2db0..9d7aa492692 100644 --- a/soc/riscv/riscv-privileged/niosv/Kconfig.series +++ b/soc/riscv/intel_niosv/niosv/Kconfig.series @@ -4,6 +4,7 @@ config SOC_SERIES_NIOSV bool "INTEL FPGA NIOSV" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select SOC_FAMILY_INTEL_NIOSV help Enable support for the INTEL FPGA NIOSV. diff --git a/soc/riscv/riscv-privileged/niosv/Kconfig.soc b/soc/riscv/intel_niosv/niosv/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/niosv/Kconfig.soc rename to soc/riscv/intel_niosv/niosv/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/niosv/linker.ld b/soc/riscv/intel_niosv/niosv/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/niosv/linker.ld rename to soc/riscv/intel_niosv/niosv/linker.ld diff --git a/soc/riscv/riscv-privileged/niosv/soc.h b/soc/riscv/intel_niosv/niosv/soc.h similarity index 90% rename from soc/riscv/riscv-privileged/niosv/soc.h rename to soc/riscv/intel_niosv/niosv/soc.h index 8c10fec4540..87458c91dff 100644 --- a/soc/riscv/riscv-privileged/niosv/soc.h +++ b/soc/riscv/intel_niosv/niosv/soc.h @@ -7,7 +7,6 @@ #ifndef RISCV_INTEL_FPGA_NIOSV_H #define RISCV_INTEL_FPGA_NIOSV_H -#include #include #endif /* RISCV_INTEL_FPGA_NIOSV_H */ diff --git a/soc/riscv/riscv-ite/CMakeLists.txt b/soc/riscv/ite_ec/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/CMakeLists.txt rename to soc/riscv/ite_ec/CMakeLists.txt diff --git a/soc/riscv/ite_ec/Kconfig b/soc/riscv/ite_ec/Kconfig new file mode 100644 index 00000000000..54628029a4e --- /dev/null +++ b/soc/riscv/ite_ec/Kconfig @@ -0,0 +1,17 @@ +# Copyright (c) 2020 ITE Corporation. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_ITE_EC + bool + help + ITE Embedded Controller SoC family + +if SOC_FAMILY_ITE_EC + +config SOC_FAMILY + string + default "ite_ec" + +source "soc/riscv/ite_ec/*/Kconfig.soc" + +endif # SOC_FAMILY_ITE_EC diff --git a/soc/riscv/riscv-ite/Kconfig.defconfig b/soc/riscv/ite_ec/Kconfig.defconfig similarity index 63% rename from soc/riscv/riscv-ite/Kconfig.defconfig rename to soc/riscv/ite_ec/Kconfig.defconfig index ae18beac098..8994f47abd9 100644 --- a/soc/riscv/riscv-ite/Kconfig.defconfig +++ b/soc/riscv/ite_ec/Kconfig.defconfig @@ -1,4 +1,4 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -source "soc/riscv/riscv-ite/*/Kconfig.defconfig.series" +source "soc/riscv/ite_ec/*/Kconfig.defconfig.series" diff --git a/soc/riscv/riscv-ite/Kconfig.soc b/soc/riscv/ite_ec/Kconfig.soc similarity index 68% rename from soc/riscv/riscv-ite/Kconfig.soc rename to soc/riscv/ite_ec/Kconfig.soc index 925edb1543c..13f951c0466 100644 --- a/soc/riscv/riscv-ite/Kconfig.soc +++ b/soc/riscv/ite_ec/Kconfig.soc @@ -1,4 +1,4 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -source "soc/riscv/riscv-ite/*/Kconfig.series" +source "soc/riscv/ite_ec/*/Kconfig.series" diff --git a/soc/riscv/riscv-ite/common/CMakeLists.txt b/soc/riscv/ite_ec/common/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/common/CMakeLists.txt rename to soc/riscv/ite_ec/common/CMakeLists.txt diff --git a/soc/riscv/riscv-ite/common/check_regs.c b/soc/riscv/ite_ec/common/check_regs.c similarity index 100% rename from soc/riscv/riscv-ite/common/check_regs.c rename to soc/riscv/ite_ec/common/check_regs.c diff --git a/soc/riscv/riscv-ite/common/chip_chipregs.h b/soc/riscv/ite_ec/common/chip_chipregs.h similarity index 100% rename from soc/riscv/riscv-ite/common/chip_chipregs.h rename to soc/riscv/ite_ec/common/chip_chipregs.h diff --git a/soc/riscv/riscv-ite/common/pinctrl_soc.h b/soc/riscv/ite_ec/common/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-ite/common/pinctrl_soc.h rename to soc/riscv/ite_ec/common/pinctrl_soc.h diff --git a/soc/riscv/riscv-ite/common/policy.c b/soc/riscv/ite_ec/common/policy.c similarity index 100% rename from soc/riscv/riscv-ite/common/policy.c rename to soc/riscv/ite_ec/common/policy.c diff --git a/soc/riscv/riscv-ite/common/power.c b/soc/riscv/ite_ec/common/power.c similarity index 100% rename from soc/riscv/riscv-ite/common/power.c rename to soc/riscv/ite_ec/common/power.c diff --git a/soc/riscv/riscv-ite/common/soc_common.h b/soc/riscv/ite_ec/common/soc_common.h similarity index 82% rename from soc/riscv/riscv-ite/common/soc_common.h rename to soc/riscv/ite_ec/common/soc_common.h index 5b981783164..b7e0cdd5e55 100644 --- a/soc/riscv/riscv-ite/common/soc_common.h +++ b/soc/riscv/ite_ec/common/soc_common.h @@ -14,17 +14,6 @@ #include "chip_chipregs.h" -/* SOC-specific MCAUSE bitfields */ - -/* Interrupt Mask. 1 (interrupt) or 0 (exception) */ -#define SOC_MCAUSE_IRQ_MASK BIT(31) - -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF - -/* Exception code of environment call from M-mode */ -#define SOC_MCAUSE_ECALL_EXP 11 - #ifndef _ASMLANGUAGE #ifdef CONFIG_HAS_ITE_INTC diff --git a/soc/riscv/riscv-ite/common/soc_common_irq.c b/soc/riscv/ite_ec/common/soc_common_irq.c similarity index 100% rename from soc/riscv/riscv-ite/common/soc_common_irq.c rename to soc/riscv/ite_ec/common/soc_common_irq.c diff --git a/soc/riscv/riscv-ite/common/soc_dt.h b/soc/riscv/ite_ec/common/soc_dt.h similarity index 100% rename from soc/riscv/riscv-ite/common/soc_dt.h rename to soc/riscv/ite_ec/common/soc_dt.h diff --git a/soc/riscv/riscv-ite/common/soc_espi.h b/soc/riscv/ite_ec/common/soc_espi.h similarity index 100% rename from soc/riscv/riscv-ite/common/soc_espi.h rename to soc/riscv/ite_ec/common/soc_espi.h diff --git a/soc/riscv/riscv-ite/common/soc_irq.S b/soc/riscv/ite_ec/common/soc_irq.S similarity index 59% rename from soc/riscv/riscv-ite/common/soc_irq.S rename to soc/riscv/ite_ec/common/soc_irq.S index a412ca6a796..ceb0f3afecb 100644 --- a/soc/riscv/riscv-ite/common/soc_irq.S +++ b/soc/riscv/ite_ec/common/soc_irq.S @@ -25,21 +25,3 @@ GTEXT(__soc_handle_irq) */ SECTION_FUNC(exception.other, __soc_handle_irq) j get_irq - -/* - * __soc_is_irq is defined as .weak to allow re-implementation by - * SOCs that does not truely follow the riscv privilege specification. - */ -WTEXT(__soc_is_irq) - -/* - * SOC-specific function to determine if the exception is the result of a - * an interrupt or an exception - * return 1 (interrupt) or 0 (exception) - * - */ -SECTION_FUNC(exception.other, __soc_is_irq) - /* Read mcause and check if interrupt bit (bit 31) is set */ - csrr a0, mcause - srli a0, a0, 31 - ret diff --git a/soc/riscv/riscv-ite/common/vector.S b/soc/riscv/ite_ec/common/vector.S similarity index 100% rename from soc/riscv/riscv-ite/common/vector.S rename to soc/riscv/ite_ec/common/vector.S diff --git a/soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt b/soc/riscv/ite_ec/it8xxx2/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/CMakeLists.txt rename to soc/riscv/ite_ec/it8xxx2/CMakeLists.txt diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202bx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202bx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202bx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202bx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202cx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202cx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81202cx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81202cx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302bx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302bx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302bx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302bx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302cx b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302cx similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it81302cx rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it81302cx diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82002aw similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82002aw rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82002aw diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82202ax b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82202ax similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82202ax rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82202ax diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82302ax b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82302ax similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it82302ax rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it82302ax diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series similarity index 83% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series rename to soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series index 4e6b7c18cca..0ed7358b631 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.series +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.series @@ -1,7 +1,7 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV32_IT8XXX2 +if SOC_SERIES_ITE_IT8XXX2 config SOC_SERIES default "it8xxx2" @@ -22,9 +22,6 @@ config UART_NS16550_WA_ISR_REENABLE_INTERRUPT default y depends on UART_NS16550 -config RISCV_HAS_CPU_IDLE - default y - config FLASH_INIT_PRIORITY default 0 @@ -57,6 +54,6 @@ config GEN_SW_ISR_TABLE config RISCV_SOC_INTERRUPT_INIT default y -source "soc/riscv/riscv-ite/it8xxx2/Kconfig.defconfig.it8*" +source "soc/riscv/ite_ec/it8xxx2/Kconfig.defconfig.it8*" -endif # SOC_SERIES_RISCV32_IT8XXX2 +endif # SOC_SERIES_ITE_IT8XXX2 diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series b/soc/riscv/ite_ec/it8xxx2/Kconfig.series similarity index 86% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.series rename to soc/riscv/ite_ec/it8xxx2/Kconfig.series index ebed0fcd120..265bf855f12 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.series @@ -1,13 +1,13 @@ # Copyright (c) 2020 ITE Corporation. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV32_IT8XXX2 +config SOC_SERIES_ITE_IT8XXX2 bool "ITE IT8XXX2 implementation" #depends on RISCV # RV32IAFC is an uncommon configuration which is not supported by # default in most toolchains, causing link-time errors. select CPU_HAS_FPU if "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "zephyr" || RISCV_ISA_EXT_M - select SOC_FAMILY_RISCV_ITE + select SOC_FAMILY_ITE_EC select HAS_PM help Enable support for ITE IT8XXX2 diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc b/soc/riscv/ite_ec/it8xxx2/Kconfig.soc similarity index 99% rename from soc/riscv/riscv-ite/it8xxx2/Kconfig.soc rename to soc/riscv/ite_ec/it8xxx2/Kconfig.soc index 38525449f89..800a2a9dafd 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.soc +++ b/soc/riscv/ite_ec/it8xxx2/Kconfig.soc @@ -3,7 +3,7 @@ choice prompt "ITE IT8XXX2 system implementation" -depends on SOC_SERIES_RISCV32_IT8XXX2 +depends on SOC_SERIES_ITE_IT8XXX2 config SOC_IT8XXX2 bool "ITE IT8XXX2 system implementation" diff --git a/soc/riscv/riscv-ite/it8xxx2/__arithmetic.S b/soc/riscv/ite_ec/it8xxx2/__arithmetic.S similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/__arithmetic.S rename to soc/riscv/ite_ec/it8xxx2/__arithmetic.S diff --git a/soc/riscv/riscv-ite/it8xxx2/ilm.c b/soc/riscv/ite_ec/it8xxx2/ilm.c similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/ilm.c rename to soc/riscv/ite_ec/it8xxx2/ilm.c diff --git a/soc/riscv/riscv-ite/it8xxx2/ilm.h b/soc/riscv/ite_ec/it8xxx2/ilm.h similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/ilm.h rename to soc/riscv/ite_ec/it8xxx2/ilm.h diff --git a/soc/riscv/riscv-ite/it8xxx2/linker.ld b/soc/riscv/ite_ec/it8xxx2/linker.ld similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/linker.ld rename to soc/riscv/ite_ec/it8xxx2/linker.ld diff --git a/soc/riscv/riscv-ite/it8xxx2/soc.c b/soc/riscv/ite_ec/it8xxx2/soc.c similarity index 100% rename from soc/riscv/riscv-ite/it8xxx2/soc.c rename to soc/riscv/ite_ec/it8xxx2/soc.c diff --git a/soc/riscv/riscv-ite/it8xxx2/soc.h b/soc/riscv/ite_ec/it8xxx2/soc.h similarity index 94% rename from soc/riscv/riscv-ite/it8xxx2/soc.h rename to soc/riscv/ite_ec/it8xxx2/soc.h index bc790768369..ea9d30d11fc 100644 --- a/soc/riscv/riscv-ite/it8xxx2/soc.h +++ b/soc/riscv/ite_ec/it8xxx2/soc.h @@ -25,8 +25,4 @@ COND_CODE_1(DT_NODE_EXISTS(DT_INST(1, ite_it8xxx2_usbpd)), (2), (1)) */ #define SOC_USBPD_ITE_ACTIVE_PORT_COUNT DT_NUM_INST_STATUS_OKAY(ite_it8xxx2_usbpd) -#ifndef _ASMLANGUAGE -void soc_interrupt_init(void); -#endif - #endif /* __RISCV_ITE_SOC_H_ */ diff --git a/soc/riscv/litex-vexriscv/CMakeLists.txt b/soc/riscv/litex_vexriscv/CMakeLists.txt similarity index 73% rename from soc/riscv/litex-vexriscv/CMakeLists.txt rename to soc/riscv/litex_vexriscv/CMakeLists.txt index 9d100ea0e2a..98386f6b57a 100644 --- a/soc/riscv/litex-vexriscv/CMakeLists.txt +++ b/soc/riscv/litex_vexriscv/CMakeLists.txt @@ -5,8 +5,8 @@ # zephyr_sources( - ../riscv-privileged/common/soc_irq.S - ../riscv-privileged/common/vector.S + ../common/riscv-privileged/soc_irq.S + ../common/riscv-privileged/vector.S ) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/litex-vexriscv/Kconfig.defconfig b/soc/riscv/litex_vexriscv/Kconfig.defconfig similarity index 74% rename from soc/riscv/litex-vexriscv/Kconfig.defconfig rename to soc/riscv/litex_vexriscv/Kconfig.defconfig index 9447948b567..0088420459f 100644 --- a/soc/riscv/litex-vexriscv/Kconfig.defconfig +++ b/soc/riscv/litex_vexriscv/Kconfig.defconfig @@ -4,17 +4,11 @@ if SOC_RISCV32_LITEX_VEXRISCV config SOC - default "litex-vexriscv" + default "litex_vexriscv" config SYS_CLOCK_HW_CYCLES_PER_SEC default 100000000 -config RISCV_HAS_CPU_IDLE - bool - -config RISCV_HAS_PLIC - bool - config NUM_IRQS default 12 diff --git a/soc/riscv/litex-vexriscv/Kconfig.soc b/soc/riscv/litex_vexriscv/Kconfig.soc similarity index 100% rename from soc/riscv/litex-vexriscv/Kconfig.soc rename to soc/riscv/litex_vexriscv/Kconfig.soc diff --git a/soc/riscv/litex-vexriscv/soc.h b/soc/riscv/litex_vexriscv/soc.h similarity index 98% rename from soc/riscv/litex-vexriscv/soc.h rename to soc/riscv/litex_vexriscv/soc.h index b738deec771..4334be4ec1c 100644 --- a/soc/riscv/litex-vexriscv/soc.h +++ b/soc/riscv/litex_vexriscv/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV32_LITEX_VEXRISCV_SOC_H_ #define __RISCV32_LITEX_VEXRISCV_SOC_H_ -#include "../riscv-privileged/common/soc_common.h" #include #include diff --git a/soc/riscv/microchip_miv/CMakeLists.txt b/soc/riscv/microchip_miv/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/microchip_miv/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/microchip_miv/Kconfig b/soc/riscv/microchip_miv/Kconfig new file mode 100644 index 00000000000..46616636aa1 --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_MIV + bool + +if SOC_FAMILY_MICROCHIP_MIV + +config SOC_FAMILY + string + default "microchip_miv" + +source "soc/riscv/microchip_miv/*/Kconfig.soc" + +endif # SOC_FAMILY_MICROCHIP_MIV diff --git a/soc/riscv/microchip_miv/Kconfig.defconfig b/soc/riscv/microchip_miv/Kconfig.defconfig new file mode 100644 index 00000000000..2fe508bddba --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/microchip_miv/*/Kconfig.defconfig.series" diff --git a/soc/riscv/microchip_miv/Kconfig.soc b/soc/riscv/microchip_miv/Kconfig.soc new file mode 100644 index 00000000000..8677f1ba448 --- /dev/null +++ b/soc/riscv/microchip_miv/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/microchip_miv/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/miv/CMakeLists.txt b/soc/riscv/microchip_miv/miv/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/miv/CMakeLists.txt rename to soc/riscv/microchip_miv/miv/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series b/soc/riscv/microchip_miv/miv/Kconfig.defconfig.series similarity index 73% rename from soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series rename to soc/riscv/microchip_miv/miv/Kconfig.defconfig.series index 81b224ed397..35f4365b02b 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.defconfig.series +++ b/soc/riscv/microchip_miv/miv/Kconfig.defconfig.series @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV32_MIV +if SOC_SERIES_MIV config SOC_SERIES default "miv" @@ -11,12 +11,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -32,4 +26,4 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 42 -endif # SOC_SERIES_RISCV32_MIV +endif # SOC_SERIES_MIV diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.series b/soc/riscv/microchip_miv/miv/Kconfig.series similarity index 67% rename from soc/riscv/riscv-privileged/miv/Kconfig.series rename to soc/riscv/microchip_miv/miv/Kconfig.series index 00a6f129f9f..9f348619624 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.series +++ b/soc/riscv/microchip_miv/miv/Kconfig.series @@ -3,9 +3,11 @@ # Copyright (c) 2018 Antmicro # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV32_MIV +config SOC_SERIES_MIV bool "Microchip Mi-V implementation" + select SOC_FAMILY_MICROCHIP_MIV select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Microchip Mi-V diff --git a/soc/riscv/riscv-privileged/miv/Kconfig.soc b/soc/riscv/microchip_miv/miv/Kconfig.soc similarity index 88% rename from soc/riscv/riscv-privileged/miv/Kconfig.soc rename to soc/riscv/microchip_miv/miv/Kconfig.soc index 189abb6879c..0a48c2e0524 100644 --- a/soc/riscv/riscv-privileged/miv/Kconfig.soc +++ b/soc/riscv/microchip_miv/miv/Kconfig.soc @@ -5,9 +5,9 @@ choice prompt "Microchip Mi-V system implementation" - depends on SOC_SERIES_RISCV32_MIV + depends on SOC_SERIES_MIV -config SOC_RISCV32_MIV +config SOC_MIV bool "Microchip Mi-V system implementation" select ATOMIC_OPERATIONS_BUILTIN select INCLUDE_RESET_VECTOR diff --git a/soc/riscv/riscv-privileged/miv/soc.h b/soc/riscv/microchip_miv/miv/soc.h similarity index 89% rename from soc/riscv/riscv-privileged/miv/soc.h rename to soc/riscv/microchip_miv/miv/soc.h index 1608c9e6773..c5827ceed21 100644 --- a/soc/riscv/riscv-privileged/miv/soc.h +++ b/soc/riscv/microchip_miv/miv/soc.h @@ -4,8 +4,6 @@ #ifndef __RISCV32_MIV_SOC_H_ #define __RISCV32_MIV_SOC_H_ -#include - /* UART Configuration */ #define MIV_UART_0_LINECFG 0x1 diff --git a/soc/riscv/riscv-privileged/mpfs/CMakeLists.txt b/soc/riscv/microchip_miv/polarfire/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/mpfs/CMakeLists.txt rename to soc/riscv/microchip_miv/polarfire/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series b/soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series similarity index 78% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series rename to soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series index fb9f6d2d3af..5a3f113c13e 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.defconfig.series +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.defconfig.series @@ -1,10 +1,10 @@ # Copyright (c) 2020-2021 Microchip Technology Inc # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV64_MIV +if SOC_SERIES_POLARFIRE config SOC_SERIES - default "mpfs" + default "polarfire" # MPFS should be configured so that the mtimer clock is 1MHz independent of the CPU clock... @@ -14,12 +14,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -38,4 +32,4 @@ config NUM_IRQS # config NO_OPTIMIZATIONS # default y -endif # SOC_SERIES_RISCV64_MIV +endif # SOC_SERIES_POLARFIRE diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.series b/soc/riscv/microchip_miv/polarfire/Kconfig.series similarity index 66% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.series rename to soc/riscv/microchip_miv/polarfire/Kconfig.series index ca37731f192..59ec4dbdd7a 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.series +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.series @@ -3,9 +3,11 @@ # Copyright (c) 2018 Antmicro # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV64_MIV +config SOC_SERIES_POLARFIRE bool "Microchip RV64 implementation" + select SOC_FAMILY_MICROCHIP_MIV select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Microchip RISCV 64bit diff --git a/soc/riscv/riscv-privileged/mpfs/Kconfig.soc b/soc/riscv/microchip_miv/polarfire/Kconfig.soc similarity index 89% rename from soc/riscv/riscv-privileged/mpfs/Kconfig.soc rename to soc/riscv/microchip_miv/polarfire/Kconfig.soc index 7f20dc703c2..101e8b4d029 100644 --- a/soc/riscv/riscv-privileged/mpfs/Kconfig.soc +++ b/soc/riscv/microchip_miv/polarfire/Kconfig.soc @@ -5,9 +5,9 @@ choice prompt "Microchip Polarfire SOC implementation" - depends on SOC_SERIES_RISCV64_MIV + depends on SOC_SERIES_POLARFIRE -config SOC_MPFS +config SOC_POLARFIRE bool "Microchip MPFS system implementation" select ATOMIC_OPERATIONS_BUILTIN select RISCV_GP @@ -25,6 +25,6 @@ config SOC_MPFS endchoice config MPFS_HAL - depends on SOC_MPFS + depends on SOC_POLARFIRE bool "Microchip Polarfire SOC hardware abstracton layer" select HAS_MPFS_HAL diff --git a/soc/riscv/riscv-privileged/mpfs/soc.h b/soc/riscv/microchip_miv/polarfire/soc.h similarity index 77% rename from soc/riscv/riscv-privileged/mpfs/soc.h rename to soc/riscv/microchip_miv/polarfire/soc.h index d6a7d2d2e37..3bcb9569c6e 100644 --- a/soc/riscv/riscv-privileged/mpfs/soc.h +++ b/soc/riscv/microchip_miv/polarfire/soc.h @@ -6,10 +6,6 @@ #ifndef __RISCV64_MPFS_SOC_H_ #define __RISCV64_MPFS_SOC_H_ -#include #include - -#define RISCV_MSIP_BASE 0x02000000 - #endif /* __RISCV64_MPFS_SOC_H_ */ diff --git a/soc/riscv/riscv-privileged/neorv32/CMakeLists.txt b/soc/riscv/neorv32/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/CMakeLists.txt rename to soc/riscv/neorv32/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series b/soc/riscv/neorv32/Kconfig.defconfig similarity index 81% rename from soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series rename to soc/riscv/neorv32/Kconfig.defconfig index 11bd7ef7d33..bc37ea74727 100644 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.defconfig.series +++ b/soc/riscv/neorv32/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_NEORV32 +if SOC_NEORV32 -config SOC_SERIES +config SOC default "neorv32" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,9 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config NUM_IRQS default 32 -config RISCV_HAS_CPU_IDLE - default y - config RISCV_GP default y @@ -29,4 +26,4 @@ config ENTROPY_INIT_PRIORITY default 55 depends on ENTROPY_GENERATOR -endif # SOC_SERIES_NEORV32 +endif # SOC_NEORV32 diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.series b/soc/riscv/neorv32/Kconfig.soc similarity index 55% rename from soc/riscv/riscv-privileged/neorv32/Kconfig.series rename to soc/riscv/neorv32/Kconfig.soc index 98c7f34024d..3155d1b7c31 100644 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.series +++ b/soc/riscv/neorv32/Kconfig.soc @@ -1,7 +1,7 @@ # Copyright (c) 2021 Henrik Brix Andersen # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_NEORV32 +config SOC_NEORV32 bool "NEORV32 Processor" select RISCV select RISCV_ISA_RV32I @@ -9,7 +9,7 @@ config SOC_SERIES_NEORV32 select RISCV_ISA_EXT_A select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED help Enable support for the NEORV32 Processor (SoC). @@ -24,3 +24,27 @@ config SOC_SERIES_NEORV32 - E (Embedded, only 16 integer registers) - Zbb (Basic Bit Manipulation) - Zfinx (Floating Point in Integer Registers) + +if SOC_NEORV32 + +config SOC_NEORV32_V1_8_6 + bool "v1.8.6" + # NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO + select ATOMIC_OPERATIONS_C + +config SOC_NEORV32_VERSION + hex + default 0x01080600 if SOC_NEORV32_V1_8_6 + help + The targeted NEORV32 version as BCD-coded number. The format is + identical to that of the NEORV32 Machine implementation ID (mimpid) + register. + +config SOC_NEORV32_ISA_C + bool "RISC-V ISA Extension \"C\"" + select RISCV_ISA_EXT_C + help + Enable this if the NEORV32 CPU implementation supports the RISC-V ISA + "C" extension (Compressed Instructions). + +endif # SOC_NEORV32 diff --git a/soc/riscv/riscv-privileged/neorv32/linker.ld b/soc/riscv/neorv32/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/linker.ld rename to soc/riscv/neorv32/linker.ld diff --git a/soc/riscv/riscv-privileged/neorv32/reset.S b/soc/riscv/neorv32/reset.S similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/reset.S rename to soc/riscv/neorv32/reset.S diff --git a/soc/riscv/riscv-privileged/neorv32/soc.c b/soc/riscv/neorv32/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/soc.c rename to soc/riscv/neorv32/soc.c diff --git a/soc/riscv/riscv-privileged/neorv32/soc.h b/soc/riscv/neorv32/soc.h similarity index 98% rename from soc/riscv/riscv-privileged/neorv32/soc.h rename to soc/riscv/neorv32/soc.h index a1e721923a4..a97daa0fc15 100644 --- a/soc/riscv/riscv-privileged/neorv32/soc.h +++ b/soc/riscv/neorv32/soc.h @@ -7,8 +7,6 @@ #ifndef RISCV_NEORV32_SOC_H #define RISCV_NEORV32_SOC_H -#include - /* System information (SYSINFO) register offsets */ #define NEORV32_SYSINFO_CLK 0x00U #define NEORV32_SYSINFO_CPU 0x04U diff --git a/soc/riscv/riscv-privileged/neorv32/soc_irq.S b/soc/riscv/neorv32/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/neorv32/soc_irq.S rename to soc/riscv/neorv32/soc_irq.S diff --git a/soc/riscv/riscv-privileged/CMakeLists.txt b/soc/riscv/nordic_nrf/CMakeLists.txt similarity index 69% rename from soc/riscv/riscv-privileged/CMakeLists.txt rename to soc/riscv/nordic_nrf/CMakeLists.txt index c5f97039eb7..6a5b10545ff 100644 --- a/soc/riscv/riscv-privileged/CMakeLists.txt +++ b/soc/riscv/nordic_nrf/CMakeLists.txt @@ -1,3 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor # SPDX-License-Identifier: Apache-2.0 add_subdirectory(common) diff --git a/soc/riscv/nordic_nrf/Kconfig b/soc/riscv/nordic_nrf/Kconfig new file mode 100644 index 00000000000..a39db4671d5 --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_NRF + bool + +if SOC_FAMILY_NRF + +config SOC_FAMILY + string + default "nordic_nrf" + +source "soc/riscv/nordic_nrf/common/Kconfig" + +source "soc/common/nordic_nrf/Kconfig.peripherals" +source "soc/riscv/nordic_nrf/*/Kconfig.soc" + +endif # SOC_FAMILY_NRF diff --git a/soc/riscv/nordic_nrf/Kconfig.defconfig b/soc/riscv/nordic_nrf/Kconfig.defconfig new file mode 100644 index 00000000000..cc3ec954985 --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig.defconfig @@ -0,0 +1,16 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_FAMILY_NRF + +source "soc/riscv/nordic_nrf/*/Kconfig.defconfig.series" +source "soc/riscv/nordic_nrf/common/Kconfig.defconfig" + +config BUILD_OUTPUT_HEX + default y + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 1000000 if NRF_GRTC_TIMER + default 32768 if NRF_RTC_TIMER + +endif # SOC_FAMILY_NRF diff --git a/soc/riscv/nordic_nrf/Kconfig.soc b/soc/riscv/nordic_nrf/Kconfig.soc new file mode 100644 index 00000000000..593d6f91769 --- /dev/null +++ b/soc/riscv/nordic_nrf/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/nordic_nrf/*/Kconfig.series" diff --git a/soc/riscv/nordic_nrf/common/CMakeLists.txt b/soc/riscv/nordic_nrf/common/CMakeLists.txt new file mode 100644 index 00000000000..806a295ea22 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) diff --git a/soc/riscv/nordic_nrf/common/Kconfig b/soc/riscv/nordic_nrf/common/Kconfig new file mode 100644 index 00000000000..610689ecc6d --- /dev/null +++ b/soc/riscv/nordic_nrf/common/Kconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/nordic_nrf/common/vpr/Kconfig" diff --git a/soc/riscv/nordic_nrf/common/Kconfig.defconfig b/soc/riscv/nordic_nrf/common/Kconfig.defconfig new file mode 100644 index 00000000000..9beb943edb8 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/Kconfig.defconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if RISCV_CORE_NORDIC_VPR + +source "soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig" + +endif # RISCV_CORE_NORDIC_VPR diff --git a/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt b/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt new file mode 100644 index 00000000000..e0331bb8e0b --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) + +zephyr_library() +zephyr_library_sources(soc_irq.S soc_irq.c vector.S) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/nordic_nrf/common/vpr/Kconfig b/soc/riscv/nordic_nrf/common/vpr/Kconfig new file mode 100644 index 00000000000..3750716a713 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/Kconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config RISCV_CORE_NORDIC_VPR + bool "RISC-V Nordic VPR core" + default y + depends on DT_HAS_NORDIC_VPR_ENABLED + depends on RISCV + select ATOMIC_OPERATIONS_C + select RISCV_ISA_RV32E + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select RISCV_SOC_HAS_ISR_STACKING + select RISCV_SOC_CONTEXT_SAVE + select HAS_FLASH_LOAD_OFFSET if XIP + help + Enable support for the RISC-V Nordic VPR core. diff --git a/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig b/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig new file mode 100644 index 00000000000..f0014455b3a --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/Kconfig.defconfig @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CPU_PATH := $(dt_nodelabel_path,cpu) +CPU_ID := $(dt_node_reg_addr_int,$(CPU_PATH)) + +config RV_BOOT_HART + default $(CPU_ID) + +config RISCV_MCAUSE_EXCEPTION_MASK + default 0xFFF + +config RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET + default 16 + +config GEN_IRQ_VECTOR_TABLE + default y + +choice IRQ_VECTOR_TABLE_TYPE + default IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS +endchoice + +config ARCH_SW_ISR_TABLE_ALIGN + default 64 + +config RISCV_ALWAYS_SWITCH_THROUGH_ECALL + default y if MULTITHREADING diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_context.h b/soc/riscv/nordic_nrf/common/vpr/soc_context.h new file mode 100644 index 00000000000..8cd0d1e5094 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_context.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ + +#define SOC_ESF_MEMBERS unsigned long minttresh +#define SOC_ESF_INIT 0 + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_CONTEXT_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_irq.S b/soc/riscv/nordic_nrf/common/vpr/soc_irq.S new file mode 100644 index 00000000000..0e9db48d9b4 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_irq.S @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* Exports */ +GTEXT(__soc_handle_irq) +GTEXT(__soc_save_context) +GTEXT(__soc_restore_context) + +/* + * No need to clear anything, pending bit is cleared by HW. + */ +SECTION_FUNC(exception.other, __soc_handle_irq) + ret + +SECTION_FUNC(exception.other, __soc_save_context) + csrr t0, 0x347 + sw t0, __soc_esf_t_minttresh_OFFSET(a0) + + ret + +SECTION_FUNC(exception.other, __soc_restore_context) + lw t0, __soc_esf_t_minttresh_OFFSET(a0) + csrw 0x347, t0 + + ret diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_irq.c b/soc/riscv/nordic_nrf/common/vpr/soc_irq.c new file mode 100644 index 00000000000..88655f6efa0 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_irq.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void arch_irq_enable(unsigned int irq) +{ + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, irq, true); +} + +void arch_irq_disable(unsigned int irq) +{ + nrf_vpr_clic_int_enable_set(NRF_VPRCLIC, irq, false); +} + +void arch_irq_priority_set(unsigned int irq, unsigned int prio) +{ + nrf_vpr_clic_int_priority_set(NRF_VPRCLIC, irq, prio); +} + +int arch_irq_is_enabled(unsigned int irq) +{ + return nrf_vpr_clic_int_enable_check(NRF_VPRCLIC, irq); +} diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h b/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h new file mode 100644 index 00000000000..d5b139111d0 --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_isr_stacking.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ + +#include + +#if !defined(_ASMLANGUAGE) + +#include + +#define VPR_CPU DT_INST(0, nordic_vpr) + +#if DT_PROP(VPR_CPU, nordic_bus_width) == 64 + +#define SOC_ISR_STACKING_ESF_DECLARE \ + struct __esf { \ + unsigned long s0; \ + unsigned long mstatus; \ + unsigned long tp; \ + struct soc_esf soc_context; \ + \ + unsigned long t2; \ + unsigned long ra; \ + unsigned long t0; \ + unsigned long t1; \ + unsigned long a4; \ + unsigned long a5; \ + unsigned long a2; \ + unsigned long a3; \ + unsigned long a0; \ + unsigned long a1; \ + unsigned long mepc; \ + unsigned long _mcause; \ + } __aligned(16); + +#else /* DT_PROP(VPR_CPU, nordic_bus_width) == 32 */ + +#define SOC_ISR_STACKING_ESF_DECLARE \ + struct __esf { \ + unsigned long s0; \ + unsigned long mstatus; \ + unsigned long tp; \ + struct soc_esf soc_context; \ + \ + unsigned long ra; \ + unsigned long t2; \ + unsigned long t1; \ + unsigned long t0; \ + unsigned long a5; \ + unsigned long a4; \ + unsigned long a3; \ + unsigned long a2; \ + unsigned long a1; \ + unsigned long a0; \ + unsigned long mepc; \ + unsigned long _mcause; \ + } __aligned(16); + +#endif /* DT_PROP(VPR_CPU, nordic_bus_width) == 64 */ + +#else /* _ASMLANGUAGE */ + +/* + * Size of the HW managed part of the ESF: + * sizeof(_mcause) + sizeof(_mepc) + */ +#define ESF_HW_SIZEOF (0x8) + +/* + * Size of the SW managed part of the ESF in case of exception + */ +#define ESF_SW_EXC_SIZEOF (__z_arch_esf_t_SIZEOF - ESF_HW_SIZEOF) + +/* + * Size of the SW managed part of the ESF in case of interrupt + * sizeof(__padding) + ... + sizeof(soc_context) + */ +#define ESF_SW_IRQ_SIZEOF (0x10) + +#define SOC_ISR_SW_STACKING \ + csrw mscratch, t0; \ + \ + csrr t0, mcause; \ + srli t0, t0, RISCV_MCAUSE_IRQ_POS; \ + bnez t0, stacking_is_interrupt; \ + \ + csrrw t0, mscratch, zero; \ + \ + addi sp, sp, -ESF_SW_EXC_SIZEOF; \ + DO_CALLER_SAVED(sr); \ + j stacking_keep_going; \ + \ +stacking_is_interrupt: \ + addi sp, sp, -ESF_SW_IRQ_SIZEOF; \ + \ +stacking_keep_going: + +#define SOC_ISR_SW_UNSTACKING \ + csrr t0, mcause; \ + srli t0, t0, RISCV_MCAUSE_IRQ_POS; \ + bnez t0, unstacking_is_interrupt; \ + \ + DO_CALLER_SAVED(lr); \ + addi sp, sp, ESF_SW_EXC_SIZEOF; \ + j unstacking_keep_going; \ + \ +unstacking_is_interrupt: \ + addi sp, sp, ESF_SW_IRQ_SIZEOF; \ + \ +unstacking_keep_going: + +#endif /* _ASMLANGUAGE */ + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_ISR_STACKING_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h b/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h new file mode 100644 index 00000000000..92d91044e1a --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/soc_offsets.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ +#define SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ + +#define GEN_SOC_OFFSET_SYMS() GEN_OFFSET_SYM(soc_esf_t, minttresh) + +#endif /* SOC_RISCV_NORDIC_NRF_COMMON_VPR_SOC_OFFSETS_H_ */ diff --git a/soc/riscv/nordic_nrf/common/vpr/vector.S b/soc/riscv/nordic_nrf/common/vpr/vector.S new file mode 100644 index 00000000000..b8c6d97170c --- /dev/null +++ b/soc/riscv/nordic_nrf/common/vpr/vector.S @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Imports */ +GTEXT(__initialize) + +/* Exports */ +GTEXT(__start) + +SECTION_FUNC(vectors, __start) + /* Set mtvec.base (mtvec.mode is RO, no need to mask it). */ + la t0, _isr_wrapper + csrw mtvec, t0 + + /* Set mtvt. */ + la t0, _irq_vector_table + csrw 0x307, t0 + + /* Enable mstatus.mie */ + li t0, 0x1888 + csrw mstatus, t0 + + /* Call into Zephyr initialization. */ + tail __initialize diff --git a/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt b/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt new file mode 100644 index 00000000000..5b37b3a54d8 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +# Ensure that image size aligns with 16 bytes so that MRAMC finalizes all writes +# for the image correctly +zephyr_linker_sources(SECTIONS SORT_KEY zzz_place_align_at_end align.ld) diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr new file mode 100644 index 00000000000..a36d24c72ae --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.nrf54h20_enga_cpuppr @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_NRF54H20_ENGA_CPUPPR + +config SOC + default "nrf54h20_enga_cpuppr" + +config NUM_IRQS + default 496 + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +endif # SOC_NRF54H20_ENGA_CPUPPR diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series new file mode 100644 index 00000000000..0f827fbe96b --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.defconfig.series @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_NRF54HX + +rsource "Kconfig.defconfig.nrf54h*" + +config SOC_SERIES + default "nrf54h" + +DT_CHOSEN_Z_SRAM = zephyr,sram +DT_CHOSEN_Z_CODE = zephyr,code-partition + +config BUILD_OUTPUT_ADJUST_LMA + depends on !XIP + default "$(dt_chosen_partition_addr_hex,$(DT_CHOSEN_Z_CODE)) - \ + $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM))" + +endif # SOC_SERIES_NRF54HX diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.series b/soc/riscv/nordic_nrf/nrf54h/Kconfig.series new file mode 100644 index 00000000000..acb85b5623a --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.series @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_NRF54HX + bool "Nordic Semiconductor nRF54H series MCU" + select SOC_FAMILY_NRF + select HAS_NRFX + select HAS_NORDIC_DRIVERS + help + Enable support for nRF54H MCU series diff --git a/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc b/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc new file mode 100644 index 00000000000..17a6dd667c6 --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/Kconfig.soc @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_NRF54H20 + bool "nRF54H20" + depends on SOC_SERIES_NRF54HX + +if SOC_NRF54H20 + +choice + prompt "nRF54Hx MCU Selection" + +config SOC_NRF54H20_ENGA_CPUPPR + bool "nRF54H20 ENGA CPUPPR" + select RISCV + +endchoice + +endif # SOC_NRF54H20 diff --git a/soc/riscv/nordic_nrf/nrf54h/align.ld b/soc/riscv/nordic_nrf/nrf54h/align.ld new file mode 100644 index 00000000000..0905aa7f7bc --- /dev/null +++ b/soc/riscv/nordic_nrf/nrf54h/align.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA. + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.align16,,) +{ + . = (ALIGN(16) > 0 ? ALIGN(16) : 16) - 1; + BYTE(0); +} GROUP_LINK_IN(ROMABLE_REGION) diff --git a/soc/riscv/openisa_rv32m1/Kconfig.defconfig b/soc/riscv/openisa_rv32m1/Kconfig.defconfig index 3976c9940c5..52d652a061e 100644 --- a/soc/riscv/openisa_rv32m1/Kconfig.defconfig +++ b/soc/riscv/openisa_rv32m1/Kconfig.defconfig @@ -33,6 +33,9 @@ config RISCV_SOC_OFFSETS config RISCV_SOC_INTERRUPT_INIT default y +config RISCV_MCAUSE_EXCEPTION_MASK + default 0x1F + # We need to disable the watchdog out of reset, as it's enabled by # default. Use the WDOG_INIT hook for doing that. config WDOG_INIT diff --git a/soc/riscv/openisa_rv32m1/soc.h b/soc/riscv/openisa_rv32m1/soc.h index 1b2643d0b66..75011d36283 100644 --- a/soc/riscv/openisa_rv32m1/soc.h +++ b/soc/riscv/openisa_rv32m1/soc.h @@ -94,8 +94,6 @@ static inline uint32_t rv32m1_intmux_line(unsigned int irq) return ((irq >> 8) & 0xff) - 1; } -void soc_interrupt_init(void); - #endif /* !_ASMLANGUAGE */ #if defined(CONFIG_SOC_OPENISA_RV32M1_RI5CY) diff --git a/soc/riscv/openisa_rv32m1/soc_irq.S b/soc/riscv/openisa_rv32m1/soc_irq.S index 23222ea2c70..d3059d2bd28 100644 --- a/soc/riscv/openisa_rv32m1/soc_irq.S +++ b/soc/riscv/openisa_rv32m1/soc_irq.S @@ -10,22 +10,12 @@ #include /* Exports */ -GTEXT(__soc_is_irq) GTEXT(__soc_handle_irq) #ifdef CONFIG_RISCV_SOC_CONTEXT_SAVE GTEXT(__soc_save_context) GTEXT(__soc_restore_context) #endif -/* - * Whether we're in an IRQ is bog-standard RISC-V on this SoC: - * yes if the top mcause bit is set, otherwise no. - */ -SECTION_FUNC(exception.other, __soc_is_irq) - csrr a0, mcause - srli a0, a0, 31 - ret - /* * With a0 == irq_num, this is equivalent to: * diff --git a/soc/riscv/openisa_rv32m1/soc_ri5cy.h b/soc/riscv/openisa_rv32m1/soc_ri5cy.h index 27ebcbe6f35..d9158935e08 100644 --- a/soc/riscv/openisa_rv32m1/soc_ri5cy.h +++ b/soc/riscv/openisa_rv32m1/soc_ri5cy.h @@ -40,21 +40,4 @@ #define RI5CY_PRIVLV 0xC10 #define RI5CY_MHARTID 0xF14 -/* - * Map from SoC-specific configuration to generic Zephyr macros. - * - * These are expected by the code in arch/, and must be provided for - * the kernel to work (or even build at all). - * - * Some of these may also apply to ZERO-RISCY; needs investigation. - */ - -/* - * Exception code mask. Use of the bottom five bits is a subset of - * what the standard allocates (which is XLEN-1 bits). - */ -#define SOC_MCAUSE_EXP_MASK 0x1F - -/* The ecall exception number. This is a standard value. */ -#define SOC_MCAUSE_ECALL_EXP 11 #endif /* SOC_RISCV32_OPENISA_RV32M1_SOC_RI5CY_H_ */ diff --git a/soc/riscv/openisa_rv32m1/soc_zero_riscy.h b/soc/riscv/openisa_rv32m1/soc_zero_riscy.h index d5fa48297f7..43cd144823a 100644 --- a/soc/riscv/openisa_rv32m1/soc_zero_riscy.h +++ b/soc/riscv/openisa_rv32m1/soc_zero_riscy.h @@ -28,22 +28,4 @@ #define ZERO_RISCY_PCMR 0x7A1U #define ZERO_RISCY_MHARTID 0xF14U -/* - * Map from SoC-specific configuration to generic Zephyr macros. - * - * These are expected by the code in arch/, and must be provided for - * the kernel to work (or even build at all). - * - * Some of these may also apply to ZERO-RISCY; needs investigation. - */ - -/* - * Exception code mask. Use of the bottom five bits is a subset of - * what the standard allocates (which is XLEN-1 bits). - */ -#define SOC_MCAUSE_EXP_MASK 0x1F - -/* The ecall exception number. This is a standard value. */ -#define SOC_MCAUSE_ECALL_EXP 11 - #endif /* SOC_RISCV32_OPENISA_RV32M1_SOC_ZERO_RISCY_H_ */ diff --git a/soc/riscv/riscv-privileged/opentitan/CMakeLists.txt b/soc/riscv/opentitan/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/CMakeLists.txt rename to soc/riscv/opentitan/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series b/soc/riscv/opentitan/Kconfig.defconfig similarity index 68% rename from soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series rename to soc/riscv/opentitan/Kconfig.defconfig index c9e7f8396a0..19a72fc70bd 100644 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.defconfig.series +++ b/soc/riscv/opentitan/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2023 Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_OPENTITAN +if SOC_OPENTITAN -config SOC_SERIES +config SOC default "opentitan" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -30,4 +24,4 @@ config 2ND_LVL_INTR_00_OFFSET config NUM_IRQS default 217 -endif # SOC_SERIES_RISCV_OPENTITAN +endif # SOC_OPENTITAN diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.soc b/soc/riscv/opentitan/Kconfig.soc similarity index 64% rename from soc/riscv/riscv-privileged/opentitan/Kconfig.soc rename to soc/riscv/opentitan/Kconfig.soc index 098b1844e52..c76cfe013b1 100644 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.soc +++ b/soc/riscv/opentitan/Kconfig.soc @@ -1,11 +1,7 @@ # Copyright (c) 2023 Rivos Inc. # SPDX-License-Identifier: Apache-2.0 -choice - prompt "OpenTitan implementation" - depends on SOC_SERIES_RISCV_OPENTITAN - -config SOC_RISCV_OPENTITAN +config SOC_OPENTITAN bool "OpenTitan implementation" select ATOMIC_OPERATIONS_C select INCLUDE_RESET_VECTOR @@ -18,5 +14,9 @@ config SOC_RISCV_OPENTITAN select RISCV_ISA_EXT_ZBB select RISCV_ISA_EXT_ZBC select RISCV_ISA_EXT_ZBS - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + # OpenTitan Ibex core mtvec mode is read-only / forced to vectored mode. + select RISCV_VECTORED_MODE + select GEN_IRQ_VECTOR_TABLE diff --git a/soc/riscv/riscv-privileged/opentitan/rom_header.S b/soc/riscv/opentitan/rom_header.S similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/rom_header.S rename to soc/riscv/opentitan/rom_header.S diff --git a/soc/riscv/riscv-privileged/opentitan/rom_header.ld b/soc/riscv/opentitan/rom_header.ld similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/rom_header.ld rename to soc/riscv/opentitan/rom_header.ld diff --git a/soc/riscv/riscv-privileged/opentitan/soc.c b/soc/riscv/opentitan/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/opentitan/soc.c rename to soc/riscv/opentitan/soc.c diff --git a/soc/riscv/riscv-privileged/opentitan/soc.h b/soc/riscv/opentitan/soc.h similarity index 97% rename from soc/riscv/riscv-privileged/opentitan/soc.h rename to soc/riscv/opentitan/soc.h index 13bb5c43b54..c7f75beb877 100644 --- a/soc/riscv/riscv-privileged/opentitan/soc.h +++ b/soc/riscv/opentitan/soc.h @@ -7,7 +7,6 @@ #ifndef __RISCV_OPENTITAN_SOC_H_ #define __RISCV_OPENTITAN_SOC_H_ -#include #include /* OpenTitan power management regs. */ diff --git a/soc/riscv/renode_virt/CMakeLists.txt b/soc/riscv/renode_virt/CMakeLists.txt new file mode 100644 index 00000000000..56d36b84ec8 --- /dev/null +++ b/soc/riscv/renode_virt/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2023 Meta +# 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/renode_virt/Kconfig.defconfig b/soc/riscv/renode_virt/Kconfig.defconfig new file mode 100644 index 00000000000..fab59719595 --- /dev/null +++ b/soc/riscv/renode_virt/Kconfig.defconfig @@ -0,0 +1,42 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +if SOC_RISCV32_VIRTUAL_RENODE + +config SOC + default "renode_virt" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 4000000 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 1ST_LEVEL_INTERRUPT_BITS + default 4 + +config NUM_2ND_LEVEL_AGGREGATORS + default 2 + +config 2ND_LEVEL_INTERRUPT_BITS + default 11 + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config 2ND_LVL_INTR_01_OFFSET + default 4 + +config MAX_IRQ_PER_AGGREGATOR + default 1023 + +config NUM_IRQS + default 2058 + +endif # SOC_RISCV32_VIRTUAL_RENODE diff --git a/soc/riscv/renode_virt/Kconfig.soc b/soc/riscv/renode_virt/Kconfig.soc new file mode 100644 index 00000000000..ba42c40c28d --- /dev/null +++ b/soc/riscv/renode_virt/Kconfig.soc @@ -0,0 +1,16 @@ +# Copyright (c) 2023 Meta +# SPDX-License-Identifier: Apache-2.0 + +config SOC_RISCV32_VIRTUAL_RENODE + bool "Renode RISCV32 Virtual system implementation" + select RISCV + select RISCV_PRIVILEGED + select ATOMIC_OPERATIONS_BUILTIN + select INCLUDE_RESET_VECTOR + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + select RISCV_HAS_PLIC diff --git a/soc/riscv/renode_virt/soc.h b/soc/riscv/renode_virt/soc.h new file mode 100644 index 00000000000..3edef49c88c --- /dev/null +++ b/soc/riscv/renode_virt/soc.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2023 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RISCV32_RENODE_SOC_H_ +#define __RISCV32_RENODE_SOC_H_ + +#endif /* __RISCV32_RENODE_SOC_H_ */ diff --git a/soc/riscv/riscv-ite/Kconfig b/soc/riscv/riscv-ite/Kconfig deleted file mode 100644 index f25c53d1ffb..00000000000 --- a/soc/riscv/riscv-ite/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2020 ITE Corporation. All Rights Reserved. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_FAMILY_RISCV_ITE - bool - help - omit prompt to signify a "hidden" option - -config SOC_FAMILY - string - default "riscv-ite" - depends on SOC_FAMILY_RISCV_ITE - -source "soc/riscv/riscv-ite/*/Kconfig.soc" diff --git a/soc/riscv/riscv-privileged/Kconfig b/soc/riscv/riscv-privileged/Kconfig deleted file mode 100644 index abbeeac242b..00000000000 --- a/soc/riscv/riscv-privileged/Kconfig +++ /dev/null @@ -1,38 +0,0 @@ -# Configuration options for riscv SOCs supporting the riscv privileged -# architecture specification - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -config SOC_FAMILY_RISCV_PRIVILEGE - bool - select DEPRECATED - -config SOC_FAMILY_RISCV_PRIVILEGED - bool - select ARCH_HAS_RAMFUNC_SUPPORT if XIP - -config SOC_FAMILY - string - default "riscv-privileged" - depends on SOC_FAMILY_RISCV_PRIVILEGED - -config RISCV_HAS_PLIC - bool "Does the SOC provide support for a Platform Level Interrupt Controller (PLIC)" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Does the SOC provide support for a Platform Level Interrupt Controller (PLIC). - -config RISCV_HAS_CLIC - bool "Does the SOC provide support for a Core-Local Interrupt Controller (CLIC)" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Does the SOC provide support for a Core-Local Interrupt Controller (CLIC). - -config RISCV_VECTORED_MODE - bool "Should the SOC use vectored mode" - depends on SOC_FAMILY_RISCV_PRIVILEGED - help - Should the SOC use vectored mode. - -source "soc/riscv/riscv-privileged/*/Kconfig.soc" diff --git a/soc/riscv/riscv-privileged/Kconfig.defconfig b/soc/riscv/riscv-privileged/Kconfig.defconfig deleted file mode 100644 index 6793d72a385..00000000000 --- a/soc/riscv/riscv-privileged/Kconfig.defconfig +++ /dev/null @@ -1,6 +0,0 @@ -# riscv SOC family supporting the riscv privileged architecture spec - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -source "soc/riscv/riscv-privileged/*/Kconfig.defconfig.series" diff --git a/soc/riscv/riscv-privileged/Kconfig.soc b/soc/riscv/riscv-privileged/Kconfig.soc deleted file mode 100644 index 14d141223e0..00000000000 --- a/soc/riscv/riscv-privileged/Kconfig.soc +++ /dev/null @@ -1,6 +0,0 @@ -# riscv SOC series supporting the riscv privileged architecture spec - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -source "soc/riscv/riscv-privileged/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/andes_v5/Kconfig.series b/soc/riscv/riscv-privileged/andes_v5/Kconfig.series deleted file mode 100644 index 9a99711b04c..00000000000 --- a/soc/riscv/riscv-privileged/andes_v5/Kconfig.series +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2021 Andes Technology Corporation -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_ANDES_V5 - bool "Andes V5 SoC Series Implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for Andes V5 SoC Series diff --git a/soc/riscv/riscv-privileged/common/idle.c b/soc/riscv/riscv-privileged/common/idle.c deleted file mode 100644 index e61ce72b280..00000000000 --- a/soc/riscv/riscv-privileged/common/idle.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * Contributors: 2018 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include - -static ALWAYS_INLINE void riscv_idle(unsigned int key) -{ - sys_trace_idle(); - /* unlock interrupts */ - irq_unlock(key); - - /* Wait for interrupt */ - __asm__ volatile("wfi"); -} - -/** - * @brief Power save idle routine - * - * This function will be called by the kernel idle loop or possibly within - * an implementation of _pm_save_idle in the kernel when the - * '_pm_save_flag' variable is non-zero. - */ -void arch_cpu_idle(void) -{ - riscv_idle(MSTATUS_IEN); -} - -/** - * @brief Atomically re-enable interrupts and enter low power mode - * - * INTERNAL - * The requirements for arch_cpu_atomic_idle() are as follows: - * 1) The enablement of interrupts and entering a low-power mode needs to be - * atomic, i.e. there should be no period of time where interrupts are - * enabled before the processor enters a low-power mode. See the comments - * in k_lifo_get(), for example, of the race condition that - * occurs if this requirement is not met. - * - * 2) After waking up from the low-power mode, the interrupt lockout state - * must be restored as indicated in the 'imask' input parameter. - */ -void arch_cpu_atomic_idle(unsigned int key) -{ - riscv_idle(key); -} diff --git a/soc/riscv/riscv-privileged/common/soc_common.h b/soc/riscv/riscv-privileged/common/soc_common.h deleted file mode 100644 index 79f458924c6..00000000000 --- a/soc/riscv/riscv-privileged/common/soc_common.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file configuration macros for riscv SOCs supporting the riscv - * privileged architecture specification - */ - -#ifndef __SOC_COMMON_H_ -#define __SOC_COMMON_H_ - -/* IRQ numbers */ -#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ -#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ - -/* ECALL Exception numbers */ -#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ -#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ - -/* SOC-specific MCAUSE bitfields */ -#ifdef CONFIG_64BIT -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 63) -#else -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 31) -#endif - -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK CONFIG_RISCV_SOC_MCAUSE_EXCEPTION_MASK - -#ifndef _ASMLANGUAGE - -#include -#include - -#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) -void soc_interrupt_init(void); -#endif - -#endif /* !_ASMLANGUAGE */ - -#endif /* __SOC_COMMON_H_ */ diff --git a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series b/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series deleted file mode 100644 index 8505cf1318a..00000000000 --- a/soc/riscv/riscv-privileged/efinix-sapphire/Kconfig.series +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2023 Efinix Inc. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_EFINIX_SAPPHIRE - bool "Efinix Sapphire SOC implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for Efinix Sapphire SOC implementation diff --git a/soc/riscv/riscv-privileged/neorv32/Kconfig.soc b/soc/riscv/riscv-privileged/neorv32/Kconfig.soc deleted file mode 100644 index 93c9da8cc3d..00000000000 --- a/soc/riscv/riscv-privileged/neorv32/Kconfig.soc +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2021 Henrik Brix Andersen -# SPDX-License-Identifier: Apache-2.0 - -choice - prompt "NEORV32 Version" - depends on SOC_SERIES_NEORV32 - -config SOC_NEORV32_V1_8_6 - bool "v1.8.6" - # NEORV32 RISC-V ISA A extension implements only LR/SC, not AMO - select ATOMIC_OPERATIONS_C - -endchoice - -if SOC_SERIES_NEORV32 - -config SOC_NEORV32_VERSION - hex - default 0x01080600 if SOC_NEORV32_V1_8_6 - help - The targeted NEORV32 version as BCD-coded number. The format is - identical to that of the NEORV32 Machine implementation ID (mimpid) - register. - -config SOC_NEORV32_ISA_C - bool "RISC-V ISA Extension \"C\"" - select RISCV_ISA_EXT_C - help - Enable this if the NEORV32 CPU implementation supports the RISC-V ISA - "C" extension (Compressed Instructions). - -endif # SOC_SERIES_NEORV32 diff --git a/soc/riscv/riscv-privileged/opentitan/Kconfig.series b/soc/riscv/riscv-privileged/opentitan/Kconfig.series deleted file mode 100644 index f8bbc2840fe..00000000000 --- a/soc/riscv/riscv-privileged/opentitan/Kconfig.series +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2023 Rivos Inc. -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_OPENTITAN - bool "OpenTitan implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - # OpenTitan Ibex core mtvec mode is read-only / forced to vectored mode. - select RISCV_VECTORED_MODE - select GEN_IRQ_VECTOR_TABLE - help - Enable support for OpenTitan diff --git a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt b/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt deleted file mode 100644 index ff4cc56d739..00000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -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/Kconfig.series b/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.series deleted file mode 100644 index 523f6a4ffe9..00000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.series +++ /dev/null @@ -1,11 +0,0 @@ -# RISCV_SIFIVE_FREEDOM SOC implementation - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_SIFIVE_FREEDOM - bool "SiFive Freedom SOC implementation" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED - help - Enable support for SiFive Freedom SOC diff --git a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc b/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc deleted file mode 100644 index 7840f8a09ba..00000000000 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.soc +++ /dev/null @@ -1,44 +0,0 @@ -# RISCV_SIFIVE_FREEDOM SOC configuration options - -# Copyright (c) 2017 Jean-Paul Etienne -# SPDX-License-Identifier: Apache-2.0 - -choice - prompt "SiFive Freedom SOC implementation" - depends on SOC_SERIES_RISCV_SIFIVE_FREEDOM - -config SOC_RISCV_SIFIVE_FREEDOM - bool "SiFive Freedom SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select RISCV_ISA_RV32I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -config SOC_RISCV_SIFIVE_FU540 - bool "SiFive Freedom U540 SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select 64BIT - select RISCV_ISA_RV64I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -config SOC_RISCV_SIFIVE_FU740 - bool "SiFive Freedom U740 SOC implementation" - select ATOMIC_OPERATIONS_C - select INCLUDE_RESET_VECTOR - select 64BIT - select RISCV_ISA_RV64I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -endchoice diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc b/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc deleted file mode 100644 index 3f4f96c332e..00000000000 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.soc +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2021 Telink Semiconductor -# SPDX-License-Identifier: Apache-2.0 - -choice -prompt "CPU Architecture of SoC" -depends on SOC_SERIES_RISCV_TELINK_B91 - -config B91_CPU_RISCV32 - bool "RISCV32 CPU Architecture" - select RISCV_ISA_RV32I - select RISCV_ISA_EXT_M - select RISCV_ISA_EXT_A - select RISCV_ISA_EXT_C - select RISCV_ISA_EXT_ZICSR - select RISCV_ISA_EXT_ZIFENCEI - -endchoice - -config TELINK_B91_HWDSP - bool "Support Hardware DSP" - select RISCV_SOC_CONTEXT_SAVE - depends on SOC_SERIES_RISCV_TELINK_B91 - -config TELINK_B91_PFT_ARCH - bool "Support performance throttling" - default y - select RISCV_SOC_CONTEXT_SAVE - depends on SOC_SERIES_RISCV_TELINK_B91 - -choice -prompt "Telink B91 SoC implementation" -depends on SOC_SERIES_RISCV_TELINK_B91 - -config SOC_RISCV_TELINK_B91 - bool "Telink B91 SoC implementation" - select ATOMIC_OPERATIONS_BUILTIN - select CPU_HAS_FPU - select INCLUDE_RESET_VECTOR - -endchoice diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.series b/soc/riscv/riscv-privileged/virt/Kconfig.series deleted file mode 100644 index e9846764f6b..00000000000 --- a/soc/riscv/riscv-privileged/virt/Kconfig.series +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 Cobham Gaisler AB -# SPDX-License-Identifier: Apache-2.0 - -config SOC_SERIES_RISCV_VIRT - bool "QEMU RISC-V VirtIO Board" - select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED diff --git a/soc/riscv/sifive_freedom/CMakeLists.txt b/soc/riscv/sifive_freedom/CMakeLists.txt new file mode 100644 index 00000000000..6a5b10545ff --- /dev/null +++ b/soc/riscv/sifive_freedom/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(common) +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/sifive_freedom/Kconfig b/soc/riscv/sifive_freedom/Kconfig new file mode 100644 index 00000000000..0fed11158af --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_SIFIVE_FREEDOM + bool + +if SOC_FAMILY_SIFIVE_FREEDOM + +config SOC_FAMILY + string + default "sifive_freedom" + +source "soc/riscv/sifive_freedom/*/Kconfig.soc" + +endif # SOC_FAMILY_SIFIVE_FREEDOM diff --git a/soc/riscv/sifive_freedom/Kconfig.defconfig b/soc/riscv/sifive_freedom/Kconfig.defconfig new file mode 100644 index 00000000000..5adf8fc437e --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/sifive_freedom/*/Kconfig.defconfig.series" diff --git a/soc/riscv/sifive_freedom/Kconfig.soc b/soc/riscv/sifive_freedom/Kconfig.soc new file mode 100644 index 00000000000..54274defd91 --- /dev/null +++ b/soc/riscv/sifive_freedom/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/sifive_freedom/*/Kconfig.series" diff --git a/soc/riscv/sifive_freedom/common/CMakeLists.txt b/soc/riscv/sifive_freedom/common/CMakeLists.txt new file mode 100644 index 00000000000..f75aec6b311 --- /dev/null +++ b/soc/riscv/sifive_freedom/common/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_include_directories(.) diff --git a/soc/riscv/riscv-privileged/sifive-freedom/pinctrl_soc.h b/soc/riscv/sifive_freedom/common/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/pinctrl_soc.h rename to soc/riscv/sifive_freedom/common/pinctrl_soc.h diff --git a/soc/riscv/sifive_freedom/e300/CMakeLists.txt b/soc/riscv/sifive_freedom/e300/CMakeLists.txt new file mode 100644 index 00000000000..baf01a6b047 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 new file mode 100644 index 00000000000..cb0131f1427 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e340 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "e340" if SOC_SIFIVE_FREEDOM_E340 diff --git a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series similarity index 61% rename from soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series rename to soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series index 0c3cd541773..eaa43e68e70 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/Kconfig.defconfig.series +++ b/soc/riscv/sifive_freedom/e300/Kconfig.defconfig.series @@ -1,9 +1,10 @@ +# Copyright (c) 2017 Jean-Paul Etienne # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_SIFIVE_FREEDOM +if SOC_SERIES_SIFIVE_FREEDOM_E300 config SOC_SERIES - default "sifive-freedom" + default "e300" config SYS_CLOCK_HW_CYCLES_PER_SEC default 32768 @@ -11,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -32,4 +27,6 @@ config MAX_IRQ_PER_AGGREGATOR config NUM_IRQS default 64 -endif # SOC_SERIES_RISCV_SIFIVE_FREEDOM +source "soc/riscv/sifive_freedom/e300/Kconfig.defconfig.e*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_E300 diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.series b/soc/riscv/sifive_freedom/e300/Kconfig.series new file mode 100644 index 00000000000..81634da000d --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_E300 + bool "SiFive Freedom E300 SOC implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom FE300 SOC diff --git a/soc/riscv/sifive_freedom/e300/Kconfig.soc b/soc/riscv/sifive_freedom/e300/Kconfig.soc new file mode 100644 index 00000000000..e53b84c0890 --- /dev/null +++ b/soc/riscv/sifive_freedom/e300/Kconfig.soc @@ -0,0 +1,20 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_E300 + +config SOC_SIFIVE_FREEDOM_E340 + bool "SiFive Freedom SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select RISCV_ISA_RV32I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c b/soc/riscv/sifive_freedom/e300/clock.c similarity index 98% rename from soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c rename to soc/riscv/sifive_freedom/e300/clock.c index 0b642f3e8b2..8fde8121db9 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fe310_clock.c +++ b/soc/riscv/sifive_freedom/e300/clock.c @@ -7,7 +7,7 @@ #include #include -#include "fe310_prci.h" +#include "prci.h" #define CORECLK_HZ (DT_PROP(DT_NODELABEL(coreclk), clock_frequency)) BUILD_ASSERT(DT_PROP(DT_NODELABEL(tlclk), clock_div) == 1, diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fe310_prci.h b/soc/riscv/sifive_freedom/e300/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fe310_prci.h rename to soc/riscv/sifive_freedom/e300/prci.h diff --git a/soc/riscv/riscv-privileged/sifive-freedom/soc.h b/soc/riscv/sifive_freedom/e300/soc.h similarity index 51% rename from soc/riscv/riscv-privileged/sifive-freedom/soc.h rename to soc/riscv/sifive_freedom/e300/soc.h index 958891a9d6a..3c29efb2a71 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/soc.h +++ b/soc/riscv/sifive_freedom/e300/soc.h @@ -8,30 +8,15 @@ * @file SoC configuration macros for the SiFive Freedom processor */ -#ifndef __RISCV_SIFIVE_FREEDOM_SOC_H_ -#define __RISCV_SIFIVE_FREEDOM_SOC_H_ +#ifndef __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ -#include - -#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM) /* PINMUX MAX PINS */ #define SIFIVE_PINMUX_PINS 32 /* Clock controller. */ #define PRCI_BASE_ADDR 0x10008000 -#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU540) || defined(CONFIG_SOC_RISCV_SIFIVE_FU740) - -/* Clock controller. */ -#define PRCI_BASE_ADDR 0x10000000 - -/* PINMUX MAX PINS */ -#define SIFIVE_PINMUX_PINS 16 - -#endif - -#if defined(CONFIG_SOC_RISCV_SIFIVE_FREEDOM) || defined(CONFIG_SOC_RISCV_SIFIVE_FU540) - /* * On FE310 and FU540, peripherals such as SPI, UART, I2C and PWM are clocked * by TLCLK, which is derived from CORECLK. @@ -42,12 +27,4 @@ #define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ (SIFIVE_TLCLK_BASE_FREQUENCY / SIFIVE_TLCLK_DIVIDER) -#elif defined(CONFIG_SOC_RISCV_SIFIVE_FU740) - -/* On FU740, peripherals are clocked by PCLK. */ -#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ - DT_PROP(DT_NODELABEL(pclk), clock_frequency) - -#endif - -#endif /* __RISCV_SIFIVE_FREEDOM_SOC_H_ */ +#endif /* __RISCV_SIFIVE_FREEDOM_FE300_SOC_H_ */ diff --git a/soc/riscv/sifive_freedom/u500/CMakeLists.txt b/soc/riscv/sifive_freedom/u500/CMakeLists.txt new file mode 100644 index 00000000000..baf01a6b047 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series new file mode 100644 index 00000000000..d306b60252a --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.series @@ -0,0 +1,32 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SIFIVE_FREEDOM_U500 + +config SOC_SERIES + default "u500" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config MAX_IRQ_PER_AGGREGATOR + default 52 + +config NUM_IRQS + default 64 + +source "soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_U500 diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 new file mode 100644 index 00000000000..f559f5914b3 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.defconfig.u540 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "u540" if SOC_SIFIVE_FREEDOM_U540 diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.series b/soc/riscv/sifive_freedom/u500/Kconfig.series new file mode 100644 index 00000000000..7335a1a5293 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_U500 + bool "SiFive Freedom U500 SOC implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom U500 SOC diff --git a/soc/riscv/sifive_freedom/u500/Kconfig.soc b/soc/riscv/sifive_freedom/u500/Kconfig.soc new file mode 100644 index 00000000000..0a88ccf8cc1 --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/Kconfig.soc @@ -0,0 +1,22 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_U500 + +config SOC_SIFIVE_FREEDOM_U540 + bool "SiFive Freedom U540 SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select 64BIT + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c b/soc/riscv/sifive_freedom/u500/clock.c similarity index 97% rename from soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c rename to soc/riscv/sifive_freedom/u500/clock.c index bc68a502f59..87929892f77 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fu540_clock.c +++ b/soc/riscv/sifive_freedom/u500/clock.c @@ -7,7 +7,7 @@ #include #include #include -#include "fu540_prci.h" +#include "prci.h" BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), "Unsupported CORECLK frequency"); diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu540_prci.h b/soc/riscv/sifive_freedom/u500/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fu540_prci.h rename to soc/riscv/sifive_freedom/u500/prci.h diff --git a/soc/riscv/sifive_freedom/u500/soc.h b/soc/riscv/sifive_freedom/u500/soc.h new file mode 100644 index 00000000000..1e18850787b --- /dev/null +++ b/soc/riscv/sifive_freedom/u500/soc.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the SiFive Freedom processor + */ + +#ifndef __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ + +/* Clock controller. */ +#define PRCI_BASE_ADDR 0x10000000 + +/* PINMUX MAX PINS */ +#define SIFIVE_PINMUX_PINS 16 + +/* + * On FE310 and FU540, peripherals such as SPI, UART, I2C and PWM are clocked + * by TLCLK, which is derived from CORECLK. + */ +#define SIFIVE_TLCLK_BASE_FREQUENCY \ + DT_PROP_BY_PHANDLE_IDX(DT_NODELABEL(tlclk), clocks, 0, clock_frequency) +#define SIFIVE_TLCLK_DIVIDER DT_PROP(DT_NODELABEL(tlclk), clock_div) +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + (SIFIVE_TLCLK_BASE_FREQUENCY / SIFIVE_TLCLK_DIVIDER) + +#endif /* __RISCV_SIFIVE_FREEDOM_U500_SOC_H_ */ diff --git a/soc/riscv/sifive_freedom/u700/CMakeLists.txt b/soc/riscv/sifive_freedom/u700/CMakeLists.txt new file mode 100644 index 00000000000..baf01a6b047 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(clock.c) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/riscv/common/linker.ld CACHE INTERNAL "") diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series new file mode 100644 index 00000000000..a0e730d608f --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.series @@ -0,0 +1,32 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_SIFIVE_FREEDOM_U700 + +config SOC_SERIES + default "u700" + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default 32768 + +config RISCV_SOC_INTERRUPT_INIT + default y + +config RISCV_GP + default y + +config 2ND_LVL_ISR_TBL_OFFSET + default 12 + +config 2ND_LVL_INTR_00_OFFSET + default 11 + +config MAX_IRQ_PER_AGGREGATOR + default 52 + +config NUM_IRQS + default 64 + +source "soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u*" + +endif # SOC_SERIES_SIFIVE_FREEDOM_U700 diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 new file mode 100644 index 00000000000..ca935f772eb --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.defconfig.u740 @@ -0,0 +1,5 @@ +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "u740" if SOC_SIFIVE_FREEDOM_U740 diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.series b/soc/riscv/sifive_freedom/u700/Kconfig.series new file mode 100644 index 00000000000..04bdc1fb9b2 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.series @@ -0,0 +1,13 @@ +# RISCV_SIFIVE_FREEDOM SOC implementation + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_SIFIVE_FREEDOM_U700 + bool "SiFive Freedom SOC U700 implementation" + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC + select SOC_FAMILY_SIFIVE_FREEDOM + help + Enable support for SiFive Freedom U700 SOC diff --git a/soc/riscv/sifive_freedom/u700/Kconfig.soc b/soc/riscv/sifive_freedom/u700/Kconfig.soc new file mode 100644 index 00000000000..1eec9b4bb17 --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/Kconfig.soc @@ -0,0 +1,22 @@ +# RISCV_SIFIVE_FREEDOM SOC configuration options + +# Copyright (c) 2017 Jean-Paul Etienne +# SPDX-License-Identifier: Apache-2.0 + +choice + prompt "SiFive Freedom SOC implementation" + depends on SOC_SERIES_SIFIVE_FREEDOM_U700 + +config SOC_SIFIVE_FREEDOM_U740 + bool "SiFive Freedom U740 SOC implementation" + select ATOMIC_OPERATIONS_C + select INCLUDE_RESET_VECTOR + select 64BIT + select RISCV_ISA_RV64I + select RISCV_ISA_EXT_M + select RISCV_ISA_EXT_A + select RISCV_ISA_EXT_C + select RISCV_ISA_EXT_ZICSR + select RISCV_ISA_EXT_ZIFENCEI + +endchoice diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c b/soc/riscv/sifive_freedom/u700/clock.c similarity index 99% rename from soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c rename to soc/riscv/sifive_freedom/u700/clock.c index e6bbee93689..5c3fa567343 100644 --- a/soc/riscv/riscv-privileged/sifive-freedom/fu740_clock.c +++ b/soc/riscv/sifive_freedom/u700/clock.c @@ -8,7 +8,7 @@ #include #include -#include "fu740_prci.h" +#include "prci.h" BUILD_ASSERT(MHZ(1000) == DT_PROP(DT_NODELABEL(coreclk), clock_frequency), "Unsupported CORECLK frequency"); diff --git a/soc/riscv/riscv-privileged/sifive-freedom/fu740_prci.h b/soc/riscv/sifive_freedom/u700/prci.h similarity index 100% rename from soc/riscv/riscv-privileged/sifive-freedom/fu740_prci.h rename to soc/riscv/sifive_freedom/u700/prci.h diff --git a/soc/riscv/sifive_freedom/u700/soc.h b/soc/riscv/sifive_freedom/u700/soc.h new file mode 100644 index 00000000000..2f15ba3b1cb --- /dev/null +++ b/soc/riscv/sifive_freedom/u700/soc.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017 Jean-Paul Etienne + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC configuration macros for the SiFive Freedom processor + */ + +#ifndef __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ +#define __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ + +/* Clock controller. */ +#define PRCI_BASE_ADDR 0x10000000 + +/* PINMUX MAX PINS */ +#define SIFIVE_PINMUX_PINS 16 + +/* On FU740, peripherals are clocked by PCLK. */ +#define SIFIVE_PERIPHERAL_CLOCK_FREQUENCY \ + DT_PROP(DT_NODELABEL(pclk), clock_frequency) + +#endif /* __RISCV_SIFIVE_FREEDOM_U700_SOC_H_ */ diff --git a/soc/riscv/starfive_jh71xx/CMakeLists.txt b/soc/riscv/starfive_jh71xx/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/starfive_jh71xx/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/starfive_jh71xx/Kconfig b/soc/riscv/starfive_jh71xx/Kconfig new file mode 100644 index 00000000000..65694c07eff --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_STARFIVE_JH71XX + bool + +if SOC_FAMILY_STARFIVE_JH71XX + +config SOC_FAMILY + string + default "starfive_jh71xx" + +source "soc/riscv/starfive_jh71xx/*/Kconfig.soc" + +endif # SOC_FAMILY_STARFIVE_JH71XX diff --git a/soc/riscv/starfive_jh71xx/Kconfig.defconfig b/soc/riscv/starfive_jh71xx/Kconfig.defconfig new file mode 100644 index 00000000000..b399e38b340 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/starfive_jh71xx/*/Kconfig.defconfig.series" diff --git a/soc/riscv/starfive_jh71xx/Kconfig.soc b/soc/riscv/starfive_jh71xx/Kconfig.soc new file mode 100644 index 00000000000..1ff54faa970 --- /dev/null +++ b/soc/riscv/starfive_jh71xx/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/starfive_jh71xx/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt b/soc/riscv/starfive_jh71xx/jh71xx/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/starfive_jh71xx/CMakeLists.txt rename to soc/riscv/starfive_jh71xx/jh71xx/CMakeLists.txt diff --git a/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 new file mode 100644 index 00000000000..6f38d61dd4e --- /dev/null +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh7100 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "jh7100" if SOC_JH7100 diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series similarity index 80% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series index c488c614b7d..0f058cb6c25 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.defconfig.series +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.series @@ -4,7 +4,7 @@ if SOC_SERIES_STARFIVE_JH71XX config SOC_SERIES - default "starfive_jh71xx" + default "jh71xx" config SYS_CLOCK_HW_CYCLES_PER_SEC default 6250000 @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y @@ -30,4 +24,6 @@ config 2ND_LVL_INTR_00_OFFSET config NUM_IRQS default 139 +source "soc/riscv/starfive_jh71xx/jh71xx/Kconfig.defconfig.jh71*" + endif diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series similarity index 83% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series index b360f78b77b..f392a5d1f97 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.series +++ b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.series @@ -4,6 +4,7 @@ config SOC_SERIES_STARFIVE_JH71XX bool "Starfive JH71XX series" select RISCV - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC help Enable support for Starfive JH71XX SoC Series. diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.soc b/soc/riscv/starfive_jh71xx/jh71xx/Kconfig.soc similarity index 100% rename from soc/riscv/riscv-privileged/starfive_jh71xx/Kconfig.soc rename to soc/riscv/starfive_jh71xx/jh71xx/Kconfig.soc diff --git a/soc/riscv/riscv-privileged/starfive_jh71xx/soc.h b/soc/riscv/starfive_jh71xx/jh71xx/soc.h similarity index 86% rename from soc/riscv/riscv-privileged/starfive_jh71xx/soc.h rename to soc/riscv/starfive_jh71xx/jh71xx/soc.h index 796f07201d9..df3559c96e3 100644 --- a/soc/riscv/riscv-privileged/starfive_jh71xx/soc.h +++ b/soc/riscv/starfive_jh71xx/jh71xx/soc.h @@ -7,6 +7,4 @@ #ifndef __RISCV_VIRT_SOC_H_ #define __RISCV_VIRT_SOC_H_ -#include - #endif diff --git a/soc/riscv/telink_tlsr/CMakeLists.txt b/soc/riscv/telink_tlsr/CMakeLists.txt new file mode 100644 index 00000000000..69b2926358e --- /dev/null +++ b/soc/riscv/telink_tlsr/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory(${SOC_SERIES}) diff --git a/soc/riscv/telink_tlsr/Kconfig b/soc/riscv/telink_tlsr/Kconfig new file mode 100644 index 00000000000..144751311ba --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_TELINK_TLSR + bool + +if SOC_FAMILY_TELINK_TLSR + +config SOC_FAMILY + string + default "telink_tlsr" + +source "soc/riscv/telink_tlsr/*/Kconfig.soc" + +endif # SOC_FAMILY_TELINK_TLSR diff --git a/soc/riscv/telink_tlsr/Kconfig.defconfig b/soc/riscv/telink_tlsr/Kconfig.defconfig new file mode 100644 index 00000000000..04a888381fa --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig.defconfig @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/telink_tlsr/*/Kconfig.defconfig.series" diff --git a/soc/riscv/telink_tlsr/Kconfig.soc b/soc/riscv/telink_tlsr/Kconfig.soc new file mode 100644 index 00000000000..db09c69d1f4 --- /dev/null +++ b/soc/riscv/telink_tlsr/Kconfig.soc @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "soc/riscv/telink_tlsr/*/Kconfig.series" diff --git a/soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt b/soc/riscv/telink_tlsr/tlsr951x/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/CMakeLists.txt rename to soc/riscv/telink_tlsr/tlsr951x/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series similarity index 77% rename from soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series rename to soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series index 986b6240750..2b72ad9960c 100644 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.defconfig.series +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.series @@ -1,11 +1,11 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_TELINK_B91 +if SOC_SERIES_TELINK_TLSR951X config SOC_SERIES string - default "telink_b91" + default "tlsr951x" config SYS_CLOCK_HW_CYCLES_PER_SEC int @@ -15,14 +15,6 @@ config RISCV_SOC_INTERRUPT_INIT bool default y -config RISCV_HAS_CPU_IDLE - bool - default y - -config RISCV_HAS_PLIC - bool - default y - config RISCV_GP bool default y @@ -56,4 +48,6 @@ config 2ND_LVL_INTR_00_OFFSET config HAS_FLASH_LOAD_OFFSET default y if BOOTLOADER_MCUBOOT -endif # SOC_SERIES_RISCV_TELINK_B91 +source "soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr*" + +endif # SOC_SERIES_TELINK_TLSR951X diff --git a/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 new file mode 100644 index 00000000000..4ffdebdaf6b --- /dev/null +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.defconfig.tlsr9518 @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config SOC + default "tlsr9518" if SOC_TELINK_TLSR9518 diff --git a/soc/riscv/riscv-privileged/telink_b91/Kconfig.series b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.series similarity index 52% rename from soc/riscv/riscv-privileged/telink_b91/Kconfig.series rename to soc/riscv/telink_tlsr/tlsr951x/Kconfig.series index a966dfe447b..5d5fc3226e5 100644 --- a/soc/riscv/riscv-privileged/telink_b91/Kconfig.series +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.series @@ -1,8 +1,8 @@ # Copyright (c) 2021 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 -config SOC_SERIES_RISCV_TELINK_B91 - bool "Telink B91 SoC Implementation" +config SOC_SERIES_TELINK_TLSR951X + bool "Telink TLSR951X" select RISCV select RISCV_ISA_RV32I select RISCV_ISA_EXT_M @@ -10,7 +10,12 @@ config SOC_SERIES_RISCV_TELINK_B91 select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR select RISCV_ISA_EXT_ZIFENCEI - select SOC_FAMILY_RISCV_PRIVILEGED + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC select HAS_TELINK_DRIVERS + select ATOMIC_OPERATIONS_BUILTIN + select CPU_HAS_FPU + select INCLUDE_RESET_VECTOR + select SOC_FAMILY_TELINK_TLSR help - Enable support for Telink B91 SoC + Enable support for Telink TLSR951X diff --git a/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc new file mode 100644 index 00000000000..2abc12cc58c --- /dev/null +++ b/soc/riscv/telink_tlsr/tlsr951x/Kconfig.soc @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Telink Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_TELINK_TLSR951X + +choice + prompt "Telink TLSR951X SoC implementation" + +config SOC_TELINK_TLSR9518 + bool "Telink TLSR9518" + +endchoice + +config TELINK_B91_HWDSP + bool "Support Hardware DSP" + select RISCV_SOC_CONTEXT_SAVE + +config TELINK_B91_PFT_ARCH + bool "Support performance throttling" + default y + select RISCV_SOC_CONTEXT_SAVE + +endif # SOC_SERIES_TELINK_TLSR951X diff --git a/soc/riscv/riscv-privileged/telink_b91/init.ld b/soc/riscv/telink_tlsr/tlsr951x/init.ld similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/init.ld rename to soc/riscv/telink_tlsr/tlsr951x/init.ld diff --git a/soc/riscv/riscv-privileged/telink_b91/linker.ld b/soc/riscv/telink_tlsr/tlsr951x/linker.ld similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/linker.ld rename to soc/riscv/telink_tlsr/tlsr951x/linker.ld diff --git a/soc/riscv/riscv-privileged/telink_b91/pinctrl_soc.h b/soc/riscv/telink_tlsr/tlsr951x/pinctrl_soc.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/pinctrl_soc.h rename to soc/riscv/telink_tlsr/tlsr951x/pinctrl_soc.h diff --git a/soc/riscv/riscv-privileged/telink_b91/soc.c b/soc/riscv/telink_tlsr/tlsr951x/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc.c rename to soc/riscv/telink_tlsr/tlsr951x/soc.c diff --git a/soc/riscv/riscv-privileged/telink_b91/soc.h b/soc/riscv/telink_tlsr/tlsr951x/soc.h similarity index 88% rename from soc/riscv/riscv-privileged/telink_b91/soc.h rename to soc/riscv/telink_tlsr/tlsr951x/soc.h index a46b4c620c7..6acfd63dd02 100644 --- a/soc/riscv/riscv-privileged/telink_b91/soc.h +++ b/soc/riscv/telink_tlsr/tlsr951x/soc.h @@ -7,6 +7,4 @@ #ifndef RISCV_TELINK_B91_SOC_H #define RISCV_TELINK_B91_SOC_H -#include - #endif /* RISCV_TELINK_B91_SOC_H */ diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_context.h b/soc/riscv/telink_tlsr/tlsr951x/soc_context.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_context.h rename to soc/riscv/telink_tlsr/tlsr951x/soc_context.h diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_irq.S b/soc/riscv/telink_tlsr/tlsr951x/soc_irq.S similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_irq.S rename to soc/riscv/telink_tlsr/tlsr951x/soc_irq.S diff --git a/soc/riscv/riscv-privileged/telink_b91/soc_offsets.h b/soc/riscv/telink_tlsr/tlsr951x/soc_offsets.h similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/soc_offsets.h rename to soc/riscv/telink_tlsr/tlsr951x/soc_offsets.h diff --git a/soc/riscv/riscv-privileged/telink_b91/start.S b/soc/riscv/telink_tlsr/tlsr951x/start.S similarity index 100% rename from soc/riscv/riscv-privileged/telink_b91/start.S rename to soc/riscv/telink_tlsr/tlsr951x/start.S diff --git a/soc/riscv/riscv-privileged/virt/CMakeLists.txt b/soc/riscv/virt/CMakeLists.txt similarity index 100% rename from soc/riscv/riscv-privileged/virt/CMakeLists.txt rename to soc/riscv/virt/CMakeLists.txt diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series b/soc/riscv/virt/Kconfig.defconfig similarity index 78% rename from soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series rename to soc/riscv/virt/Kconfig.defconfig index 231d4519d67..bed5ff8bec7 100644 --- a/soc/riscv/riscv-privileged/virt/Kconfig.defconfig.series +++ b/soc/riscv/virt/Kconfig.defconfig @@ -1,9 +1,9 @@ # Copyright (c) 2020 Cobham Gaisler AB # SPDX-License-Identifier: Apache-2.0 -if SOC_SERIES_RISCV_VIRT +if SOC_RISCV_VIRT -config SOC_SERIES +config SOC default "virt" config SYS_CLOCK_HW_CYCLES_PER_SEC @@ -12,12 +12,6 @@ config SYS_CLOCK_HW_CYCLES_PER_SEC config RISCV_SOC_INTERRUPT_INIT default y -config RISCV_HAS_CPU_IDLE - default y - -config RISCV_HAS_PLIC - default y - config RISCV_GP default y diff --git a/soc/riscv/riscv-privileged/virt/Kconfig.soc b/soc/riscv/virt/Kconfig.soc similarity index 75% rename from soc/riscv/riscv-privileged/virt/Kconfig.soc rename to soc/riscv/virt/Kconfig.soc index 35a2853eb50..59e553a9d7b 100644 --- a/soc/riscv/riscv-privileged/virt/Kconfig.soc +++ b/soc/riscv/virt/Kconfig.soc @@ -1,10 +1,6 @@ # Copyright (c) 2020 Cobham Gaisler AB # SPDX-License-Identifier: Apache-2.0 -choice - prompt "QEMU RISC-V VirtIO Board" - depends on SOC_SERIES_RISCV_VIRT - config SOC_RISCV_VIRT bool "QEMU RISC-V VirtIO Board" select ATOMIC_OPERATIONS_BUILTIN @@ -12,5 +8,6 @@ config SOC_RISCV_VIRT select RISCV_ISA_EXT_M select RISCV_ISA_EXT_A select RISCV_ISA_EXT_C - -endchoice + select RISCV + select RISCV_PRIVILEGED + select RISCV_HAS_PLIC diff --git a/soc/riscv/riscv-privileged/virt/soc.c b/soc/riscv/virt/soc.c similarity index 100% rename from soc/riscv/riscv-privileged/virt/soc.c rename to soc/riscv/virt/soc.c diff --git a/soc/riscv/riscv-privileged/virt/soc.h b/soc/riscv/virt/soc.h similarity index 73% rename from soc/riscv/riscv-privileged/virt/soc.h rename to soc/riscv/virt/soc.h index 8fd5e2108ce..8aa4238010c 100644 --- a/soc/riscv/riscv-privileged/virt/soc.h +++ b/soc/riscv/virt/soc.h @@ -7,9 +7,6 @@ #ifndef __RISCV_VIRT_SOC_H_ #define __RISCV_VIRT_SOC_H_ -#include - #define SIFIVE_SYSCON_TEST 0x00100000 -#define RISCV_MSIP_BASE 0x02000000 #endif diff --git a/submanifests/optional.yaml b/submanifests/optional.yaml index 54b3d77c0cb..00b0408c454 100644 --- a/submanifests/optional.yaml +++ b/submanifests/optional.yaml @@ -28,7 +28,7 @@ manifest: groups: - optional - name: psa-arch-tests - revision: 6a17330e0dfb5f319730f974d5b05f7b7f04757b + revision: 2cadb02a72eacda7042505dcbdd492371e8ce024 path: modules/tee/tf-m/psa-arch-tests remote: upstream groups: @@ -40,7 +40,7 @@ manifest: groups: - optional - name: tf-m-tests - revision: a878426da78fbd1486dfc29d6c6b82be4ee79e72 + revision: 08a3158f0623a4205608a52d880b17ae394e31d2 path: modules/tee/tf-m/tf-m-tests remote: upstream groups: diff --git a/subsys/bluetooth/Kconfig b/subsys/bluetooth/Kconfig index e02901cd906..912846e4cda 100644 --- a/subsys/bluetooth/Kconfig +++ b/subsys/bluetooth/Kconfig @@ -175,6 +175,14 @@ config BT_SCA_UPDATE depends on !BT_CTLR || BT_CTLR_SCA_UPDATE_SUPPORT help Enable support for Bluetooth 5.1 Sleep Clock Accuracy Update Procedure + +config BT_TRANSMIT_POWER_CONTROL + bool "LE Power Control" + depends on !BT_CTLR || BT_CTLR_LE_POWER_CONTROL_SUPPORT + help + Enable support for LE Power Control Request feature that is defined in the + Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.31. + endif # BT_CONN rsource "Kconfig.iso" diff --git a/subsys/bluetooth/Kconfig.logging b/subsys/bluetooth/Kconfig.logging index ec95ddad10e..b6505f6e53a 100644 --- a/subsys/bluetooth/Kconfig.logging +++ b/subsys/bluetooth/Kconfig.logging @@ -469,56 +469,56 @@ config BT_MESH_DEBUG_NET select DEPRECATED help Use this option to enable Network layer debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_RPL bool "[DEPRECATED] Replay protection list debug" select DEPRECATED help Use this option to enable Replay protection list debug logs - for the Bluetooth mesh functionality. + for the Bluetooth Mesh functionality. config BT_MESH_DEBUG_TRANS bool "[DEPRECATED] Transport layer debug" select DEPRECATED help Use this option to enable Transport layer debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_BEACON bool "[DEPRECATED] Beacon debug" select DEPRECATED help Use this option to enable Beacon-related debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_CRYPTO bool "[DEPRECATED] Crypto debug" select DEPRECATED help Use this option to enable cryptographic debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_KEYS bool "[DEPRECATED] Key management debug" select DEPRECATED help Use this option to enable key management debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROV bool "[DEPRECATED] Provisioning debug" select DEPRECATED help Use this option to enable Provisioning debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROVISIONER bool "[DEPRECATED] Provisioner debug" select DEPRECATED help Use this option to enable Provisioner debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROV_DEVICE bool "[DEPRECATED] Provisioning device debug" @@ -532,7 +532,7 @@ config BT_MESH_DEBUG_ACCESS select DEPRECATED help Use this option to enable Access layer and device composition - related debug logs for Bluetooth mesh. + related debug logs for Bluetooth Mesh. config BT_MESH_DEBUG_MODEL bool "[DEPRECATED] Foundation model debug" @@ -546,21 +546,21 @@ config BT_MESH_DEBUG_ADV select DEPRECATED help Use this option to enable advertising debug logs for - the Bluetooth mesh functionality. + the Bluetooth Mesh functionality. config BT_MESH_DEBUG_LOW_POWER bool "[DEPRECATED] Low Power debug" select DEPRECATED help Use this option to enable Low Power debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_FRIEND bool "[DEPRECATED] Friend debug" select DEPRECATED help Use this option to enable Friend debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. config BT_MESH_DEBUG_PROXY bool "[DEPRECATED] Proxy debug" @@ -588,7 +588,7 @@ config BT_MESH_DEBUG_CFG select DEPRECATED help Use this option to enable node configuration debug logs for the - Bluetooth mesh functionality. + Bluetooth Mesh functionality. endmenu # [DEPRECATED] Mesh @@ -1002,7 +1002,7 @@ legacy-debug-sym = BT_MESH_DEBUG_PROVISIONER module-str = "Provisioner" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" -module = BT_MESH_PROV_DEVICE +module = BT_MESH_PROVISIONEE legacy-debug-sym = BT_MESH_DEBUG_PROV_DEVICE module-str = "Provisioning device" source "subsys/bluetooth/common/Kconfig.template.log_config_bt" diff --git a/subsys/bluetooth/audio/ascs.c b/subsys/bluetooth/audio/ascs.c index 116071d4c0f..4127b1a4ce4 100644 --- a/subsys/bluetooth/audio/ascs.c +++ b/subsys/bluetooth/audio/ascs.c @@ -766,7 +766,8 @@ static void ascs_iso_recv(struct bt_iso_chan *chan, * host as HCI ISO data packets, which we should just ignore */ if ((info->flags & BT_ISO_FLAGS_VALID) != 0) { - LOG_ERR("iso %p not bound with ep", chan); + LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep", + net_buf_frags_len(buf), chan); } return; @@ -944,7 +945,6 @@ static void ascs_iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan); if (iso->rx.ep == NULL && iso->tx.ep == NULL) { - LOG_ERR("iso %p not bound with ep", chan); return; } @@ -1820,11 +1820,7 @@ static int ase_stream_qos(struct bt_bap_stream *stream, struct bt_audio_codec_qo * we have the ISO <-> EP coupling completed (due to setting * the CIS ID in the QoS procedure). */ - if (ep->dir == BT_AUDIO_DIR_SINK) { - bt_audio_codec_cfg_to_iso_path(&ep->iso->rx.path, stream->codec_cfg); - } else { - bt_audio_codec_cfg_to_iso_path(&ep->iso->tx.path, stream->codec_cfg); - } + bt_bap_iso_configure_data_path(ep, stream->codec_cfg); ep->cig_id = cig_id; ep->cis_id = cis_id; diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 4d2134455b8..ceafaf6389c 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -764,7 +764,7 @@ static int bt_bap_broadcast_sink_setup_stream(struct bt_bap_broadcast_sink *sink bt_bap_iso_bind_ep(iso, ep); bt_audio_codec_qos_to_iso_qos(iso->chan.qos->rx, &sink->codec_qos); - bt_audio_codec_cfg_to_iso_path(iso->chan.qos->rx->path, codec_cfg); + bt_bap_iso_configure_data_path(ep, codec_cfg); bt_bap_iso_unref(iso); @@ -798,17 +798,6 @@ static void broadcast_sink_cleanup_streams(struct bt_bap_broadcast_sink *sink) static void broadcast_sink_cleanup(struct bt_bap_broadcast_sink *sink) { - if (atomic_test_bit(sink->flags, - BT_BAP_BROADCAST_SINK_FLAG_SRC_ID_VALID)) { - int err; - - err = bt_bap_scan_delegator_rem_src(sink->bass_src_id); - if (err != 0) { - /* This is likely due to the receive state been removed */ - LOG_DBG("Could not remove Receive State for sink %p: %d", sink, err); - } - } - if (sink->stream_count > 0U) { broadcast_sink_cleanup_streams(sink); } diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 8978e2816cb..2167366c7e1 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -86,7 +86,7 @@ static void broadcast_source_set_ep_state(struct bt_bap_ep *ep, uint8_t state) } break; case BT_BAP_EP_STATE_ENABLING: - if (state != BT_BAP_EP_STATE_STREAMING) { + if (state != BT_BAP_EP_STATE_STREAMING && state != BT_BAP_EP_STATE_QOS_CONFIGURED) { LOG_DBG("Invalid broadcast sync endpoint state transition"); return; } @@ -288,7 +288,7 @@ static int broadcast_source_setup_stream(uint8_t index, struct bt_bap_stream *st bt_bap_iso_bind_ep(iso, ep); 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); + bt_bap_iso_configure_data_path(ep, codec_cfg); #if defined(CONFIG_BT_ISO_TEST_PARAMS) iso->chan.qos->num_subevents = qos->num_subevents; #endif /* CONFIG_BT_ISO_TEST_PARAMS */ @@ -788,7 +788,7 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, 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; + bool stream_in_subgroup = false; param_stream = subgroup_param->params[i].stream; @@ -878,7 +878,7 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, 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); + bt_bap_iso_configure_data_path(stream->ep, codec_cfg); } } @@ -938,6 +938,7 @@ int bt_bap_broadcast_source_update_metadata(struct bt_bap_broadcast_source *sour SYS_SLIST_FOR_EACH_CONTAINER(&source->subgroups, subgroup, _node) { memset(subgroup->codec_cfg->meta, 0, sizeof(subgroup->codec_cfg->meta)); memcpy(subgroup->codec_cfg->meta, meta, meta_len); + subgroup->codec_cfg->meta_len = meta_len; } return 0; diff --git a/subsys/bluetooth/audio/bap_iso.c b/subsys/bluetooth/audio/bap_iso.c index cb68a8032f5..3fa2059ea94 100644 --- a/subsys/bluetooth/audio/bap_iso.c +++ b/subsys/bluetooth/audio/bap_iso.c @@ -129,19 +129,12 @@ void bt_bap_iso_init(struct bt_bap_iso *iso, struct bt_iso_chan_ops *ops) iso->chan.ops = ops; iso->chan.qos = &iso->qos; - /* Setup points for both Tx and Rx + /* Setup the QoS for both Tx and Rx * This is due to the limitation in the ISO API where pointers like - * the `qos->tx` shall be initialized before the CIS is connected if - * ever want to use it for TX, and ditto for RX. They cannot be - * initialized after the CIS has been connected + * the `qos->tx` shall be initialized before the CIS is created */ iso->chan.qos->rx = &iso->rx.qos; - iso->chan.qos->rx->path = &iso->rx.path; - iso->chan.qos->rx->path->cc = iso->rx.cc; - iso->chan.qos->tx = &iso->tx.qos; - iso->chan.qos->tx->path = &iso->tx.path; - iso->chan.qos->tx->path->cc = iso->tx.cc; } static struct bt_bap_iso_dir *bap_iso_get_iso_dir(bool unicast_client, struct bt_bap_iso *iso, @@ -164,6 +157,43 @@ static struct bt_bap_iso_dir *bap_iso_get_iso_dir(bool unicast_client, struct bt } } +void bt_bap_iso_configure_data_path(struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg) +{ + struct bt_bap_iso *bap_iso = ep->iso; + struct bt_iso_chan_qos *qos = bap_iso->chan.qos; + const bool is_unicast_client = + IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && bt_bap_ep_is_unicast_client(ep); + struct bt_bap_iso_dir *iso_dir = bap_iso_get_iso_dir(is_unicast_client, bap_iso, ep->dir); + struct bt_iso_chan_path *path = &iso_dir->path; + + /* Setup the data path objects */ + if (iso_dir == &bap_iso->rx) { + qos->rx->path = path; + } else { + qos->tx->path = path; + } + + /* Configure the data path to either use the controller for transcoding, or set the path to + * be transparant to indicate that the transcoding happens somewhere else + */ + path->pid = codec_cfg->path_id; + + if (codec_cfg->ctlr_transcode) { + path->format = codec_cfg->id; + path->cid = codec_cfg->cid; + path->vid = codec_cfg->vid; + path->delay = 0; + path->cc_len = codec_cfg->data_len; + path->cc = codec_cfg->data; + } else { + path->format = BT_HCI_CODING_FORMAT_TRANSPARENT; + path->cid = 0; + path->vid = 0; + path->delay = 0; + path->cc_len = 0; + path->cc = NULL; + } +} static bool is_unicast_client_ep(struct bt_bap_ep *ep) { return IS_ENABLED(CONFIG_BT_BAP_UNICAST_CLIENT) && bt_bap_ep_is_unicast_client(ep); diff --git a/subsys/bluetooth/audio/bap_iso.h b/subsys/bluetooth/audio/bap_iso.h index d3b27f3823a..4384182d697 100644 --- a/subsys/bluetooth/audio/bap_iso.h +++ b/subsys/bluetooth/audio/bap_iso.h @@ -41,6 +41,7 @@ void bt_bap_iso_foreach(bt_bap_iso_func_t func, void *user_data); struct bt_bap_iso *bt_bap_iso_find(bt_bap_iso_func_t func, void *user_data); void bt_bap_iso_init(struct bt_bap_iso *iso, struct bt_iso_chan_ops *ops); void bt_bap_iso_bind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep); +void bt_bap_iso_configure_data_path(struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg); void bt_bap_iso_unbind_ep(struct bt_bap_iso *iso, struct bt_bap_ep *ep); struct bt_bap_ep *bt_bap_iso_get_ep(bool unicast_client, struct bt_bap_iso *iso, enum bt_audio_dir dir); diff --git a/subsys/bluetooth/audio/bap_scan_delegator.c b/subsys/bluetooth/audio/bap_scan_delegator.c index 3cef96bd1b8..41f77391a68 100644 --- a/subsys/bluetooth/audio/bap_scan_delegator.c +++ b/subsys/bluetooth/audio/bap_scan_delegator.c @@ -863,8 +863,9 @@ static int scan_delegator_rem_src(struct bt_conn *conn, state = &internal_state->state; - if (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ || - state->pa_sync_state == BT_BAP_PA_STATE_SYNCED) { + /* If conn == NULL then it's a local operation and we do not need to ask the application */ + if (conn != NULL && (state->pa_sync_state == BT_BAP_PA_STATE_INFO_REQ || + state->pa_sync_state == BT_BAP_PA_STATE_SYNCED)) { int err; /* Terminate PA sync */ diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 23e5bb8564b..fd38a90371c 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -31,18 +31,6 @@ LOG_MODULE_REGISTER(bt_bap_stream, CONFIG_BT_BAP_STREAM_LOG_LEVEL); -void bt_audio_codec_cfg_to_iso_path(struct bt_iso_chan_path *path, - struct bt_audio_codec_cfg *codec_cfg) -{ - path->pid = codec_cfg->path_id; - path->format = codec_cfg->id; - path->cid = codec_cfg->cid; - path->vid = codec_cfg->vid; - path->delay = 0; /* TODO: Add to bt_audio_codec_cfg? Use presentation delay? */ - path->cc_len = codec_cfg->data_len; - path->cc = codec_cfg->data; -} - #if defined(CONFIG_BT_BAP_UNICAST_CLIENT) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || \ defined(CONFIG_BT_BAP_BROADCAST_SINK) void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, @@ -257,6 +245,7 @@ static bool bt_bap_stream_can_send(const struct bt_bap_stream *stream) int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts) { + int ret; struct bt_bap_ep *ep; if (stream == NULL || stream->ep == NULL) { @@ -277,6 +266,12 @@ int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, return -EBADMSG; } + ret = bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream), + buf, seq_num, ts); + if (ret) { + return ret; + } + #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) { @@ -289,8 +284,7 @@ int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, /* TODO: Add checks for broadcast sink */ - return bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream), - buf, seq_num, ts); + return ret; } int bt_bap_stream_get_tx_sync(struct bt_bap_stream *stream, struct bt_iso_tx_info *info) diff --git a/subsys/bluetooth/audio/bap_stream.h b/subsys/bluetooth/audio/bap_stream.h index 67e8c0470df..d16cf2cfcc9 100644 --- a/subsys/bluetooth/audio/bap_stream.h +++ b/subsys/bluetooth/audio/bap_stream.h @@ -17,8 +17,6 @@ void bt_bap_stream_reset(struct bt_bap_stream *stream); void bt_bap_stream_attach(struct bt_conn *conn, struct bt_bap_stream *stream, struct bt_bap_ep *ep, struct bt_audio_codec_cfg *codec_cfg); -void bt_audio_codec_cfg_to_iso_path(struct bt_iso_chan_path *path, - struct bt_audio_codec_cfg *codec_cfg); void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, const struct bt_audio_codec_qos *codec_qos); diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 933db93ec72..7cbde2464c2 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -231,7 +231,8 @@ static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, * host as HCI ISO data packets, which we should just ignore */ if ((info->flags & BT_ISO_FLAGS_VALID) != 0) { - LOG_ERR("iso %p not bound with ep", chan); + LOG_DBG("Valid ISO packet of len %zu received for iso %p not bound with ep", + net_buf_frags_len(buf), chan); } return; @@ -774,17 +775,8 @@ static void unicast_client_ep_qos_state(struct bt_bap_ep *ep, struct net_buf_sim * we have the ISO <-> EP coupling completed (due to setting * the CIS ID in the QoS procedure). */ - if (ep->dir == BT_AUDIO_DIR_SOURCE) { - /* If the endpoint is a source, then we need to - * configure our RX parameters - */ - bt_audio_codec_cfg_to_iso_path(&ep->iso->rx.path, stream->codec_cfg); - } else { - /* If the endpoint is a sink, then we need to - * configure our TX parameters - */ - bt_audio_codec_cfg_to_iso_path(&ep->iso->tx.path, stream->codec_cfg); - } + + bt_bap_iso_configure_data_path(ep, stream->codec_cfg); } /* Notify upper layer */ @@ -1024,6 +1016,8 @@ static void unicast_client_ep_set_status(struct bt_bap_ep *ep, struct net_buf_si case BT_BAP_EP_STATE_CODEC_CONFIGURED: /* or 0x02 (QoS Configured) */ case BT_BAP_EP_STATE_QOS_CONFIGURED: + /* or 0x04 (Streaming) if there is a disconnect */ + case BT_BAP_EP_STATE_STREAMING: /* or 0x05 (Disabling) */ case BT_BAP_EP_STATE_DISABLING: break; @@ -2061,6 +2055,7 @@ static void unicast_client_reset(struct bt_bap_ep *ep, uint8_t reason) static void unicast_client_ep_reset(struct bt_conn *conn, uint8_t reason) { + struct unicast_client *client; uint8_t index; LOG_DBG("conn %p", conn); @@ -2082,6 +2077,11 @@ static void unicast_client_ep_reset(struct bt_conn *conn, uint8_t reason) unicast_client_reset(ep, reason); } #endif /* CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT > 0 */ + + client = &uni_cli_insts[index]; + client->busy = false; + client->dir = 0U; + reset_att_buf(client); } static void bt_audio_codec_qos_to_cig_param(struct bt_iso_cig_param *cig_param, diff --git a/subsys/bluetooth/audio/cap_initiator.c b/subsys/bluetooth/audio/cap_initiator.c index 46b39afcb41..3b8ee2fc3f2 100644 --- a/subsys/bluetooth/audio/cap_initiator.c +++ b/subsys/bluetooth/audio/cap_initiator.c @@ -192,7 +192,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_param bap_create_param; + struct bt_bap_broadcast_source_param bap_create_param = {0}; CHECKIF(param == NULL) { LOG_DBG("param is NULL"); diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 38b1ef7d22b..3f5f2b56629 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -142,6 +142,8 @@ static bool parse_cb(struct bt_data *data, void *user_data) static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t *data, size_t data_len) { + size_t new_buf_len; + for (uint16_t i = 0U; i < buf->len;) { uint8_t *len = &buf->data[i++]; const uint8_t data_type = buf->data[i++]; @@ -162,8 +164,8 @@ static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t * 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; + old_next_data_start = value + value_len; + new_next_data_start = value + data_len; data_len_to_move = buf->len - (old_next_data_start - buf->data); } @@ -207,11 +209,12 @@ static int ltv_set_val(struct net_buf_simple *buf, uint8_t type, const uint8_t * } /* 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); + new_buf_len = buf->len + 1 /* len */ + sizeof(type) + data_len; + if (new_buf_len <= buf->size) { + net_buf_simple_add_u8(buf, data_len + sizeof(type)); /* len */ + net_buf_simple_add_u8(buf, type); /* type */ if (data_len > 0) { - net_buf_simple_add_mem(buf, data, data_len); + net_buf_simple_add_mem(buf, data, data_len); /* value */ } } else { LOG_DBG("Cannot fit data_len %zu in codec_cfg with len %u and size %u", data_len, diff --git a/subsys/bluetooth/common/Kconfig b/subsys/bluetooth/common/Kconfig index bf4aee75e48..2fdc98694b1 100644 --- a/subsys/bluetooth/common/Kconfig +++ b/subsys/bluetooth/common/Kconfig @@ -33,6 +33,7 @@ config BT_BUF_ACL_TX_SIZE config BT_BUF_ACL_TX_COUNT int "Number of outgoing ACL data buffers" default 7 if BT_HCI_RAW + default 4 if BT_MESH_GATT default 3 range 1 255 help @@ -242,7 +243,7 @@ config BT_HCI_MESH_EXT bool "Mesh HCI Command support" depends on BT_BROADCASTER && BT_OBSERVER && !BT_LL_SW_SPLIT help - Enable support for the Bluetooth mesh HCI Commands. + Enable support for the Bluetooth Mesh HCI Commands. config BT_WAIT_NOP bool "Wait for \"NOP\" Command Complete event during init" diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 742534beff3..a7b2c1a74f1 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -101,6 +101,9 @@ config BT_CTLR_READ_ISO_LINK_QUALITY_SUPPORT BT_CTLR_PERIPHERAL_ISO_SUPPORT bool +config BT_CTLR_LE_POWER_CONTROL_SUPPORT + bool + config BT_CTLR bool "Bluetooth Controller" help @@ -114,7 +117,8 @@ choice BT_LL_CHOICE Select the Bluetooth Link Layer to compile. config BT_LL_SW_SPLIT - bool "Software-based BLE Link Layer" + bool "Software-based BLE Link Layer [EXPERIMENTAL]" + select EXPERIMENTAL select ENTROPY_GENERATOR help Use Zephyr software BLE Link Layer ULL LLL split implementation. @@ -252,92 +256,126 @@ choice BT_CTLR_TX_PWR The value set here represents the actual default power level fed to the antenna. +config BT_CTLR_TX_PWR_PLUS_10 + bool "+10 dBm" + depends on SOC_SERIES_NRF54HX + +config BT_CTLR_TX_PWR_PLUS_9 + bool "+9 dBm" + depends on SOC_SERIES_NRF54HX + config BT_CTLR_TX_PWR_PLUS_8 bool "+8 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_7 bool "+7 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_6 bool "+6 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_5 bool "+5 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_4 bool "+4 dBm" - depends on SOC_SERIES_NRF51X || SOC_COMPATIBLE_NRF52X + depends on SOC_SERIES_NRF51X || SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_3 bool "+3 dBm" - depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X + depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_2 bool "+2 dBm" - depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF53X + depends on HAS_HW_NRF_RADIO_TX_PWR_HIGH || SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_PLUS_1 bool "+1 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_0 bool "0 dBm" config BT_CTLR_TX_PWR_MINUS_1 bool "-1 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_2 bool "-2 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_3 bool "-3 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_4 bool "-4 dBm" config BT_CTLR_TX_PWR_MINUS_5 bool "-5 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_6 bool "-6 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_7 bool "-7 dBm" - depends on SOC_SERIES_NRF53X + depends on SOC_SERIES_NRF53X || SOC_SERIES_NRF54LX config BT_CTLR_TX_PWR_MINUS_8 bool "-8 dBm" +config BT_CTLR_TX_PWR_MINUS_9 + bool "-9 dBm" + depends on SOC_SERIES_NRF54LX + +config BT_CTLR_TX_PWR_MINUS_10 + bool "-10 dBm" + depends on SOC_SERIES_NRF54LX + config BT_CTLR_TX_PWR_MINUS_12 bool "-12 dBm" +config BT_CTLR_TX_PWR_MINUS_14 + bool "-14 dBm" + depends on SOC_SERIES_NRF54LX + config BT_CTLR_TX_PWR_MINUS_16 bool "-16 dBm" config BT_CTLR_TX_PWR_MINUS_20 bool "-20 dBm" +config BT_CTLR_TX_PWR_MINUS_26 + bool "-26 dBm" + depends on SOC_SERIES_NRF54LX + config BT_CTLR_TX_PWR_MINUS_30 bool "-30 dBm" - depends on SOC_SERIES_NRF51X + depends on SOC_SERIES_NRF51X || SOC_SERIES_NRF54HX config BT_CTLR_TX_PWR_MINUS_40 bool "-40 dBm" - depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X + depends on SOC_COMPATIBLE_NRF52X || SOC_SERIES_NRF53X || SOC_SERIES_NRF54HX || SOC_SERIES_NRF54LX + +config BT_CTLR_TX_PWR_MINUS_46 + bool "-46 dBm" + depends on SOC_SERIES_NRF54LX + +config BT_CTLR_TX_PWR_MINUS_70 + bool "-70 dBm" + depends on SOC_SERIES_NRF54HX endchoice config BT_CTLR_TX_PWR_DBM int + default 10 if BT_CTLR_TX_PWR_PLUS_10 + default 9 if BT_CTLR_TX_PWR_PLUS_9 default 8 if BT_CTLR_TX_PWR_PLUS_8 default 7 if BT_CTLR_TX_PWR_PLUS_7 default 6 if BT_CTLR_TX_PWR_PLUS_6 @@ -355,11 +393,17 @@ config BT_CTLR_TX_PWR_DBM default -6 if BT_CTLR_TX_PWR_MINUS_6 default -7 if BT_CTLR_TX_PWR_MINUS_7 default -8 if BT_CTLR_TX_PWR_MINUS_8 + default -9 if BT_CTLR_TX_PWR_MINUS_9 + default -10 if BT_CTLR_TX_PWR_MINUS_10 default -12 if BT_CTLR_TX_PWR_MINUS_12 + default -14 if BT_CTLR_TX_PWR_MINUS_14 default -16 if BT_CTLR_TX_PWR_MINUS_16 default -20 if BT_CTLR_TX_PWR_MINUS_20 + default -26 if BT_CTLR_TX_PWR_MINUS_26 default -30 if BT_CTLR_TX_PWR_MINUS_30 default -40 if BT_CTLR_TX_PWR_MINUS_40 + default -46 if BT_CTLR_TX_PWR_MINUS_46 + default -70 if BT_CTLR_TX_PWR_MINUS_70 config BT_CTLR_TX_PWR_ANTENNA int "Set TX power (dBm)" @@ -484,6 +528,14 @@ config BT_CTLR_CONN_RSSI help Enable connection RSSI measurement. +config BT_CTLR_LE_POWER_CONTROL + bool "LE Power Control Request Feature" + depends on BT_CTLR_LE_POWER_CONTROL_SUPPORT + default y if BT_TRANSMIT_POWER_CONTROL + help + Enable support for LE Power Control Request feature that is defined in the + Bluetooth Core specification, Version 5.4 | Vol 6, Part B, Section 4.6.31. + endif # BT_CONN config BT_CTLR_FILTER_ACCEPT_LIST @@ -801,11 +853,14 @@ config BT_CTLR_SYNC_ISO_PDU_LEN_MAX endif # BT_CTLR_ADV_EXT config BT_CTLR_SET_HOST_FEATURE - bool "LE Set Host Feature Command [EXPERIMENTAL]" - select EXPERIMENTAL + bool "LE Set Host Feature Command" if !BT_LL_SW_SPLIT help Enables optional LE Set Host Feature Command +config BT_CTLR_SET_HOST_FEATURE + bool "LE Set Host Feature Command (Split Link Layer) [EXPERIMENTAL]" if BT_LL_SW_SPLIT + select EXPERIMENTAL if BT_LL_SW_SPLIT + config BT_CTLR_CENTRAL_ISO bool "LE Connected Isochronous Stream Central" if !BT_LL_SW_SPLIT depends on BT_CTLR_CENTRAL_ISO_SUPPORT && BT_CENTRAL diff --git a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h index bea7004f9c9..ecbe8968476 100644 --- a/subsys/bluetooth/controller/hci/nordic/hci_vendor.h +++ b/subsys/bluetooth/controller/hci/nordic/hci_vendor.h @@ -12,6 +12,10 @@ #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF52X #elif defined(CONFIG_SOC_COMPATIBLE_NRF53X) #define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF53X +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF54HX +#elif defined(CONFIG_SOC_SERIES_NRF54LX) +#define BT_HCI_VS_HW_VAR BT_HCI_VS_HW_VAR_NORDIC_NRF54LX #endif #else #define BT_HCI_VS_HW_PLAT 0 diff --git a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h index 2eb772f20cc..c3bb09fd1b3 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h +++ b/subsys/bluetooth/controller/ll_sw/nordic/hal/nrf5/radio/radio_nrf5_txp.h @@ -4,7 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -#if defined(CONFIG_BT_CTLR_TX_PWR_PLUS_8) +#if defined(CONFIG_BT_CTLR_TX_PWR_PLUS_10) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Pos10dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_PLUS_9) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Pos9dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_PLUS_8) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Pos8dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_PLUS_7) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Pos7dBm @@ -38,14 +42,26 @@ #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg7dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_8) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg8dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_9) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg9dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_10) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg10dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_12) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg12dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_14) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg14dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_16) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg16dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_20) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg20dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_26) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg26dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_30) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg30dBm #elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_40) #define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg40dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_46) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg46dBm +#elif defined(CONFIG_BT_CTLR_TX_PWR_MINUS_70) +#define RADIO_TXP_DEFAULT RADIO_TXPOWER_TXPOWER_Neg70dBm #endif diff --git a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c index db8f25a374c..cde5f5befc9 100644 --- a/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c +++ b/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c @@ -191,8 +191,13 @@ int lll_init(void) radio_nrf5_isr, IRQ_CONNECT_FLAGS); IRQ_CONNECT(RTC0_IRQn, CONFIG_BT_CTLR_ULL_HIGH_PRIO, rtc0_nrf5_isr, NULL, 0); +#if defined(CONFIG_BT_CTLR_ZLI) + IRQ_DIRECT_CONNECT(HAL_SWI_RADIO_IRQ, CONFIG_BT_CTLR_LLL_PRIO, + swi_lll_nrf5_isr, IRQ_CONNECT_FLAGS); +#else IRQ_CONNECT(HAL_SWI_RADIO_IRQ, CONFIG_BT_CTLR_LLL_PRIO, swi_lll_nrf5_isr, NULL, IRQ_CONNECT_FLAGS); +#endif #if defined(CONFIG_BT_CTLR_LOW_LAT) || \ (CONFIG_BT_CTLR_ULL_HIGH_PRIO != CONFIG_BT_CTLR_ULL_LOW_PRIO) IRQ_CONNECT(HAL_SWI_JOB_IRQ, CONFIG_BT_CTLR_ULL_LOW_PRIO, diff --git a/subsys/bluetooth/host/Kconfig.gatt b/subsys/bluetooth/host/Kconfig.gatt index 9209368f943..a2364bbe557 100644 --- a/subsys/bluetooth/host/Kconfig.gatt +++ b/subsys/bluetooth/host/Kconfig.gatt @@ -276,4 +276,13 @@ config DEVICE_NAME_GATT_WRITABLE_AUTHEN endif #BT_DEVICE_NAME_GATT_WRITABLE +config BT_GATT_AUTHORIZATION_CUSTOM + bool "Custom authorization of GATT operations [EXPERIMENTAL]" + select EXPERIMENTAL + help + This option allows the user to define application-specific + authorization logic for GATT operations that can be registered + with the bt_gatt_authorization_cb_register API. See the API + documentation for more details. + endmenu diff --git a/subsys/bluetooth/host/Kconfig.l2cap b/subsys/bluetooth/host/Kconfig.l2cap index acb948c425a..f8d602acd57 100644 --- a/subsys/bluetooth/host/Kconfig.l2cap +++ b/subsys/bluetooth/host/Kconfig.l2cap @@ -66,7 +66,7 @@ config BT_L2CAP_DYNAMIC_CHANNEL allowing the creation of dynamic L2CAP Channels. config BT_L2CAP_ECRED - bool "L2CAP Enhanced Credit Based Flow Control support" + bool "L2CAP Enhanced Credit Based Flow Control support [EXPERIMENTAL]" depends on BT_L2CAP_DYNAMIC_CHANNEL help This option enables support for LE Connection oriented Channels with diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 7134e6fa89a..7a312d5e05c 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -2064,7 +2064,7 @@ void bt_hci_le_per_adv_response_report(struct net_buf *buf) response = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response)); info.tx_power = response->tx_power; info.rssi = response->rssi; - info.cte_type = BIT(response->cte_type); + info.cte_type = bt_get_df_cte_type(response->cte_type); info.response_slot = response->response_slot; if (buf->len < response->data_length) { @@ -2185,11 +2185,10 @@ void bt_hci_le_adv_set_terminated(struct net_buf *buf) if (evt->status && IS_ENABLED(CONFIG_BT_PERIPHERAL) && atomic_test_bit(adv->flags, BT_ADV_CONNECTABLE)) { - /* Only set status for legacy advertising API. - * This will call connected callback for high duty cycle + /* This will call connected callback for high duty cycle * directed advertiser timeout. */ - le_adv_stop_free_conn(adv, adv == bt_dev.adv ? evt->status : 0); + le_adv_stop_free_conn(adv, evt->status); } if (IS_ENABLED(CONFIG_BT_CONN) && !evt->status) { diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 130b4ab0853..4e7e5b4880c 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -115,6 +115,11 @@ static uint16_t bt_att_mtu(struct bt_att_chan *chan) return MIN(chan->chan.rx.mtu, chan->chan.tx.mtu); } +/* Descriptor of application-specific authorization callbacks that are used + * with the CONFIG_BT_GATT_AUTHORIZATION_CUSTOM Kconfig enabled. + */ +const static struct bt_gatt_authorization_cb *authorization_cb; + /* ATT connection specific data */ struct bt_att { struct bt_conn *conn; @@ -1289,6 +1294,20 @@ struct read_type_data { typedef bool (*attr_read_cb)(struct net_buf *buf, ssize_t read, void *user_data); +static bool attr_read_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return true; + } + + if (!authorization_cb || !authorization_cb->read_operation_authorize) { + return true; + } + + return authorization_cb->read_operation_authorize(conn, attr); +} + static bool attr_read_type_cb(struct net_buf *frag, ssize_t read, void *user_data) { @@ -1398,6 +1417,12 @@ static uint8_t read_type_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* * If any attribute is founded in handle range it means that error * should be changed from pre-set: attr not found error to no error. @@ -1526,6 +1551,12 @@ static uint8_t read_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Read attribute value and store in the buffer */ ret = att_chan_read(chan, attr, data->buf, data->offset, NULL, NULL); if (ret < 0) { @@ -1693,6 +1724,12 @@ static uint8_t read_vl_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_read_authorize(conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* The Length Value Tuple List may be truncated within the first two * octets of a tuple due to the size limits of the current ATT_MTU. */ @@ -1940,6 +1977,20 @@ struct write_data { uint8_t err; }; +static bool attr_write_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return true; + } + + if (!authorization_cb || !authorization_cb->write_operation_authorize) { + return true; + } + + return authorization_cb->write_operation_authorize(conn, attr); +} + static uint8_t write_cb(const struct bt_gatt_attr *attr, uint16_t handle, void *user_data) { @@ -1956,6 +2007,12 @@ static uint8_t write_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_write_authorize(data->conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Set command flag if not a request */ if (!data->req) { flags |= BT_GATT_WRITE_FLAG_CMD; @@ -2069,6 +2126,12 @@ static uint8_t prep_write_cb(const struct bt_gatt_attr *attr, uint16_t handle, return BT_GATT_ITER_STOP; } + /* Check the attribute authorization logic */ + if (!attr_write_authorize(data->conn, attr)) { + data->err = BT_ATT_ERR_AUTHORIZATION; + return BT_GATT_ITER_STOP; + } + /* Check if attribute requires handler to accept the data */ if (!(attr->perm & BT_GATT_PERM_PREPARE_WRITE)) { goto append; @@ -2944,13 +3007,40 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len) struct net_buf *bt_att_create_rsp_pdu(struct bt_att_chan *chan, uint8_t op, size_t len) { - if (len + sizeof(op) > bt_att_mtu(chan)) { - LOG_WRN("ATT channel %p MTU too small for RSP (%u < %u)", - chan, bt_att_mtu(chan), len + sizeof(op)); + size_t headroom; + struct bt_att_hdr *hdr; + struct bt_att_tx_meta_data *data; + struct net_buf *buf; + + ARG_UNUSED(len); + + buf = bt_l2cap_create_pdu_timeout(NULL, 0, BT_ATT_TIMEOUT); + if (!buf) { + LOG_ERR("Unable to allocate buffer for op 0x%02x", op); return NULL; } - return bt_att_chan_create_pdu(chan, op, len); + headroom = BT_L2CAP_BUF_SIZE(0); + + if (bt_att_is_enhanced(chan)) { + headroom += BT_L2CAP_SDU_HDR_SIZE; + } + + net_buf_reserve(buf, headroom); + + data = tx_meta_data_alloc(BT_ATT_TIMEOUT); + if (!data) { + LOG_WRN("Unable to allocate ATT TX meta"); + net_buf_unref(buf); + return NULL; + } + data->att_chan = chan; + bt_att_tx_meta_data(buf) = data; + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->code = op; + + return buf; } static void att_reset(struct bt_att *att) @@ -3838,14 +3928,19 @@ int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req) __ASSERT_NO_MSG(conn); __ASSERT_NO_MSG(req); + k_sched_lock(); + att = att_get(conn); if (!att) { + k_sched_unlock(); return -ENOTCONN; } sys_slist_append(&att->reqs, &req->node); att_req_send_process(att); + k_sched_unlock(); + return 0; } @@ -3997,3 +4092,23 @@ bool bt_att_chan_opt_valid(struct bt_conn *conn, enum bt_att_chan_opt chan_opt) return true; } + +int bt_gatt_authorization_cb_register(const struct bt_gatt_authorization_cb *cb) +{ + if (!IS_ENABLED(CONFIG_BT_GATT_AUTHORIZATION_CUSTOM)) { + return -ENOSYS; + } + + if (!cb) { + authorization_cb = NULL; + return 0; + } + + if (authorization_cb) { + return -EALREADY; + } + + authorization_cb = cb; + + return 0; +} diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 1fd2f5fbc49..06a3e7553a2 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -2619,16 +2619,116 @@ static int bt_conn_get_tx_power_level(struct bt_conn *conn, uint8_t type, return 0; } +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void notify_tx_power_report(struct bt_conn *conn, + struct bt_conn_le_tx_power_report report) +{ + for (struct bt_conn_cb *cb = callback_list; cb; cb = cb->_next) { + if (cb->tx_power_report) { + cb->tx_power_report(conn, &report); + } + } + + STRUCT_SECTION_FOREACH(bt_conn_cb, cb) + { + if (cb->tx_power_report) { + cb->tx_power_report(conn, &report); + } + } +} + +int bt_conn_le_enhanced_get_tx_power_level(struct bt_conn *conn, + struct bt_conn_le_tx_power *tx_power) +{ + int err; + struct bt_hci_rp_le_read_tx_power_level *rp; + struct net_buf *rsp; + struct bt_hci_cp_le_read_tx_power_level *cp; + struct net_buf *buf; + + if (!tx_power->phy) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->phy = tx_power->phy; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_ENH_READ_TX_POWER_LEVEL, buf, &rsp); + if (err) { + return err; + } + + rp = (void *) rsp->data; + tx_power->phy = rp->phy; + tx_power->current_level = rp->current_tx_power_level; + tx_power->max_level = rp->max_tx_power_level; + net_buf_unref(rsp); + + return 0; +} + +int bt_conn_le_get_remote_tx_power_level(struct bt_conn *conn, + enum bt_conn_le_tx_power_phy phy) +{ + struct bt_hci_cp_le_read_tx_power_level *cp; + struct net_buf *buf; + + if (!phy) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->phy = phy; + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_REMOTE_TX_POWER_LEVEL, buf, NULL); +} + +int bt_conn_le_set_tx_power_report_enable(struct bt_conn *conn, + bool local_enable, + bool remote_enable) +{ + struct bt_hci_cp_le_set_tx_power_report_enable *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->local_enable = local_enable ? BT_HCI_LE_TX_POWER_REPORT_ENABLE : + BT_HCI_LE_TX_POWER_REPORT_DISABLE; + cp->remote_enable = remote_enable ? BT_HCI_LE_TX_POWER_REPORT_ENABLE : + BT_HCI_LE_TX_POWER_REPORT_DISABLE; + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_TX_POWER_REPORT_ENABLE, buf, NULL); +} +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + int bt_conn_le_get_tx_power_level(struct bt_conn *conn, struct bt_conn_le_tx_power *tx_power_level) { int err; if (tx_power_level->phy != 0) { - /* Extend the implementation when LE Enhanced Read Transmit - * Power Level HCI command is available for use. - */ - return -ENOTSUP; + if (IS_ENABLED(CONFIG_BT_TRANSMIT_POWER_CONTROL)) { + return bt_conn_le_enhanced_get_tx_power_level(conn, tx_power_level); + } else { + return -ENOTSUP; + } } err = bt_conn_get_tx_power_level(conn, BT_TX_POWER_LEVEL_CURRENT, diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 7741e259a61..a13adff704a 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -364,6 +364,9 @@ void notify_le_phy_updated(struct bt_conn *conn); bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); +void notify_tx_power_report(struct bt_conn *conn, + struct bt_conn_le_tx_power_report report); + #if defined(CONFIG_BT_SMP) /* If role specific LTK is present */ bool bt_conn_ltk_present(const struct bt_conn *conn); diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index de4fb637b49..9b72e5548bc 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -422,6 +422,22 @@ uint8_t bt_get_phy(uint8_t hci_phy) } } +int bt_get_df_cte_type(uint8_t hci_cte_type) +{ + switch (hci_cte_type) { + case BT_HCI_LE_AOA_CTE: + return BT_DF_CTE_TYPE_AOA; + case BT_HCI_LE_AOD_CTE_1US: + return BT_DF_CTE_TYPE_AOD_1US; + case BT_HCI_LE_AOD_CTE_2US: + return BT_DF_CTE_TYPE_AOD_2US; + case BT_HCI_LE_NO_CTE: + return BT_DF_CTE_TYPE_NONE; + default: + return BT_DF_CTE_TYPE_NONE; + } +} + #if defined(CONFIG_BT_CONN_TX) static void hci_num_completed_packets(struct net_buf *buf) { @@ -2399,6 +2415,33 @@ int bt_hci_register_vnd_evt_cb(bt_hci_vnd_evt_cb_t cb) } #endif /* CONFIG_BT_HCI_VS_EVT_USER */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void bt_hci_le_transmit_power_report(struct net_buf *buf) +{ + struct bt_hci_evt_le_transmit_power_report *evt; + struct bt_conn_le_tx_power_report report; + struct bt_conn *conn; + + evt = net_buf_pull_mem(buf, sizeof(*evt)); + conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE); + if (!conn) { + LOG_ERR("Unknown conn handle 0x%04X for transmit power report", + sys_le16_to_cpu(evt->handle)); + return; + } + + report.reason = evt->reason; + report.phy = evt->phy; + report.tx_power_level = evt->tx_power_level; + report.tx_power_level_flag = evt->tx_power_level_flag; + report.delta = evt->delta; + + notify_tx_power_report(conn, report); + + bt_conn_unref(conn); +} +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + static const struct event_handler vs_events[] = { #if defined(CONFIG_BT_DF_VS_CL_IQ_REPORT_16_BITS_IQ_SAMPLES) EVENT_HANDLER(BT_HCI_EVT_VS_LE_CONNECTIONLESS_IQ_REPORT, @@ -2544,6 +2587,10 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + EVENT_HANDLER(BT_HCI_EVT_LE_TRANSMIT_POWER_REPORT, bt_hci_le_transmit_power_report, + sizeof(struct bt_hci_evt_le_transmit_power_report)), +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ #if defined(CONFIG_BT_PER_ADV_SYNC_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2, sizeof(struct bt_hci_evt_le_per_advertising_report_v2)), @@ -3089,6 +3136,9 @@ static int le_set_event_mask(void) BT_FEAT_LE_PHY_CODED(bt_dev.le.features))) { mask |= BT_EVT_MASK_LE_PHY_UPDATE_COMPLETE; } + if (IS_ENABLED(CONFIG_BT_TRANSMIT_POWER_CONTROL)) { + mask |= BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING; + } } if (IS_ENABLED(CONFIG_BT_SMP) && @@ -3508,7 +3558,7 @@ static const char *vs_hw_platform(uint16_t platform) static const char *vs_hw_variant(uint16_t platform, uint16_t variant) { static const char * const nordic_str[] = { - "reserved", "nRF51x", "nRF52x", "nRF53x" + "reserved", "nRF51x", "nRF52x", "nRF53x", "nRF54Hx", "nRF54Lx" }; if (platform != BT_HCI_VS_HW_PLAT_NORDIC) { @@ -4276,7 +4326,7 @@ int bt_le_set_chan_map(uint8_t chan_map[5]) struct bt_hci_cp_le_set_host_chan_classif *cp; struct net_buf *buf; - if (!IS_ENABLED(CONFIG_BT_CENTRAL)) { + if (!(IS_ENABLED(CONFIG_BT_CENTRAL) || IS_ENABLED(CONFIG_BT_BROADCASTER))) { return -ENOTSUP; } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index ce4fc5a9b63..1a3c06414a0 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -434,7 +434,14 @@ int bt_le_set_data_len(struct bt_conn *conn, uint16_t tx_octets, uint16_t tx_tim int bt_le_set_phy(struct bt_conn *conn, uint8_t all_phys, uint8_t pref_tx_phy, uint8_t pref_rx_phy, uint8_t phy_opts); uint8_t bt_get_phy(uint8_t hci_phy); - +/** + * @brief Convert CTE type value from HCI format to @ref bt_df_cte_type format. + * + * @param hci_cte_type CTE type in an HCI format. + * + * @return CTE type (@ref bt_df_cte_type). + */ +int bt_get_df_cte_type(uint8_t hci_cte_type); int bt_le_scan_update(bool fast_scan); int bt_le_create_conn(const struct bt_conn *conn); diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index 42e9c877a9a..05b5cc2f613 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -233,9 +233,10 @@ static int hci_le_setup_iso_data_path(const struct bt_conn *iso, uint8_t dir, cp->codec_id.vs_codec_id = sys_cpu_to_le16(path->vid); sys_put_le24(path->delay, cp->controller_delay); cp->codec_config_len = path->cc_len; - cc = net_buf_add(buf, cp->codec_config_len); - memcpy(cc, path->cc, cp->codec_config_len); - + cc = net_buf_add(buf, path->cc_len); + if (path->cc_len) { + memcpy(cc, path->cc, path->cc_len); + } err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SETUP_ISO_PATH, buf, &rsp); if (err) { return err; @@ -1117,7 +1118,8 @@ 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) { + } else if (iso->role == BT_HCI_ROLE_PERIPHERAL || + evt->status != BT_HCI_ERR_OP_CANCELLED_BY_HOST) { iso->err = evt->status; bt_iso_disconnected(iso); } /* else we wait for disconnect event */ diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index e6fbe2144f8..b8faa1efcae 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -977,7 +977,9 @@ static void l2cap_chan_destroy(struct bt_l2cap_chan *chan) * In the case where we are in the context of executing the rtx_work * item, we don't sync as it will deadlock the workqueue. */ - if (k_current_get() != &le_chan->rtx_work.queue->thread) { + struct k_work_q *rtx_work_queue = le_chan->rtx_work.queue; + + if (rtx_work_queue == NULL || k_current_get() != &rtx_work_queue->thread) { k_work_cancel_delayable_sync(&le_chan->rtx_work, &le_chan->rtx_sync); } else { k_work_cancel_delayable(&le_chan->rtx_work); diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index e9a10ff8d72..3a33ff293c6 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -165,7 +165,9 @@ static void l2cap_br_chan_destroy(struct bt_l2cap_chan *chan) * In the case where we are in the context of executing the rtx_work * item, we don't sync as it will deadlock the workqueue. */ - if (k_current_get() != &br_chan->rtx_work.queue->thread) { + struct k_work_q *rtx_work_queue = br_chan->rtx_work.queue; + + if (rtx_work_queue == NULL || k_current_get() != &rtx_work_queue->thread) { k_work_cancel_delayable_sync(&br_chan->rtx_work, &br_chan->rtx_sync); } else { k_work_cancel_delayable(&br_chan->rtx_work); diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 168d7f6ead3..0b61305e2c3 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -825,7 +825,7 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) info.tx_power = evt->tx_power; info.rssi = evt->rssi; - info.cte_type = BIT(evt->cte_type); + info.cte_type = bt_get_df_cte_type(evt->cte_type); info.addr = &per_adv_sync->addr; info.sid = per_adv_sync->sid; diff --git a/subsys/bluetooth/mesh/CMakeLists.txt b/subsys/bluetooth/mesh/CMakeLists.txt index 10b142e87f5..c628fb6d9db 100644 --- a/subsys/bluetooth/mesh/CMakeLists.txt +++ b/subsys/bluetooth/mesh/CMakeLists.txt @@ -18,14 +18,9 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH cfg_srv.c health_srv.c va.c + transport.c ) -if (CONFIG_BT_MESH_V1d1) - zephyr_library_sources(transport.c) -else() - zephyr_library_sources(transport_legacy.c) -endif() - zephyr_library_sources_ifdef(CONFIG_BT_MESH_ADV_LEGACY adv_legacy.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_ADV_EXT adv_ext.c) @@ -40,7 +35,7 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_FRIEND friend.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROV prov.c) -zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROV_DEVICE prov_device.c) +zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROVISIONEE provisionee.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_PROVISIONER provisioner.c) @@ -122,6 +117,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_STATISTIC statistic.c) +zephyr_library_sources_ifdef(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG delayable_msg.c) + if (CONFIG_BT_MESH_USES_TINYCRYPT) zephyr_library_sources(crypto_tc.c) else() @@ -132,6 +129,6 @@ zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) if (CONFIG_BUILD_WITH_TFM) target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index de409e9c53c..ce845e995fd 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1,13 +1,13 @@ -# Bluetooth mesh configuration options +# Bluetooth Mesh configuration options # Copyright (c) 2017 Intel Corporation # SPDX-License-Identifier: Apache-2.0 menuconfig BT_MESH - bool "Bluetooth mesh support" + bool "Bluetooth Mesh support" depends on BT_OBSERVER && BT_BROADCASTER help - This option enables Bluetooth mesh support. The specific + This option enables Bluetooth Mesh support. The specific features that are available may depend on other features that have been enabled in the stack, such as GATT support. @@ -240,7 +240,7 @@ config BT_MESH_PB_GATT select BT_MESH_GATT_SERVER select BT_MESH_PROV select BT_MESH_PB_GATT_COMMON - select BT_MESH_PROV_DEVICE + select BT_MESH_PROVISIONEE help Enable this option to allow the device to be provisioned over GATT. @@ -268,7 +268,16 @@ config BT_MESH_PB_GATT_CLIENT endif # BT_CONN config BT_MESH_PROV_DEVICE - bool "Provisioning device role support" + bool "[DEPRECATED] Provisioning device role support" + select DEPRECATED + select BT_MESH_PROVISIONEE + help + Enable this option to allow the device to be provisioned into a mesh network. + The option is marked as deprecated and will be replaced by BT_MESH_PROVISIONEE + option. + +config BT_MESH_PROVISIONEE + bool "Provisionee role support" depends on BT_MESH_PB_ADV || BT_MESH_PB_GATT default y help @@ -276,10 +285,28 @@ config BT_MESH_PROV_DEVICE config BT_MESH_PROV_OOB_PUBLIC_KEY bool "OOB Public key support" - depends on BT_MESH_PROV_DEVICE + depends on BT_MESH_PROVISIONEE help Enable this option if public key is to be exchanged via Out of Band (OOB) technology. +config BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM + bool "Support CMAC AES128 for OOB authentication" + depends on BT_MESH_PROV + default y + help + Enable this option to support CMAC AES128 for OOB authentication. + +config BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM + bool "Support HMAC SHA256 for OOB authentication" + depends on BT_MESH_PROV + default y + help + Enable this option to support HMAC SHA256 for OOB authentication. + +config BT_MESH_OOB_AUTH_REQUIRED + bool "OOB authentication mandates to use HMAC SHA256" + depends on BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM + config BT_MESH_PROVISIONER bool "Provisioner support" depends on BT_MESH_CDB @@ -503,55 +530,125 @@ config BT_MESH_TX_SEG_MAX which leaves 56 bytes for application layer data using a 4-byte MIC and 52 bytes using an 8-byte MIC. -if !BT_MESH_V1d1 +config BT_MESH_SAR_TX_SEG_INT_STEP + hex "Interval between sending two consecutive segments" + range 0x00 0x0F + default 0x05 + help + This value controls the interval between sending two consecutive + segments in a segmented message. The interval is measured in + milliseconds and calculated using the following formula: + (CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP + 1) * 10 ms. -config BT_MESH_TX_SEG_RETRANS_COUNT - int "Transport message segment retransmit attempts" - default 4 - range 1 8 +config BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT + hex "Maximum number of retransmissions to unicast address" + range 0x00 0x0F + default 0x02 help - Maximum number of transport message segment retransmit attempts - for outgoing segment message. + This value controls the maximum number of retransmissions of a + segmented message to a unicast address before giving up the transfer. -config BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST - int "Transport message segment retransmit interval for unicast messages" - default 400 - range 200 500 +config BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT + hex "Maximum number of retransmissions without progress to a unicast address" + range 0x00 0x0F + default 0x02 help - Maximum time of retransmit segment message to unicast address. + This value defines the maximum number of retransmissions of a + segmented message to a unicast address that the stack will send if no + acknowledgment was received during timeout, or if an + acknowledgment with already confirmed segments was received. -config BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP - int "Transport message segment retransmit interval for group messages" - default 50 - range 20 200 +config BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP + hex "Retransmissions interval step of missing segments to unicast address" + range 0x00 0x0F + default 0x07 help - Maximum time of retransmit segment message to group address. + This value 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 and + calculated using the following formula: + (CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP + 1) * 25 ms. -config BT_MESH_SEG_ACK_BASE_TIMEOUT - int "SegAck transmission base timeout" - default 150 - range 150 400 +config BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC + hex "Retransmissions interval increment of missing segments to unicast address" + range 0x00 0x0F + default 0x01 + help + This value 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 and + calculated using the following formula: + (CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC + 1) * 25 ms. + +config BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT + hex "Total number of retransmissions to multicast address" + range 0x00 0x0F + default 0x02 + help + This value controls the total number of retransmissions of a segmented + message to a multicast address. + +config BT_MESH_SAR_TX_MULTICAST_RETRANS_INT + hex "Interval between retransmissions to multicast address" + range 0x00 0x0F + default 0x09 help - Defines a base timeout for the acknowledgment timer used to delay - transmission of the Segmented Acknowledgment message. + This value controls the interval between retransmissions of all + segments in a segmented message to a multicast address. The + interval is measured in milliseconds and calculated using the + following formula: + (CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT + 1) * 25 ms. -config BT_MESH_SEG_ACK_PER_HOP_TIMEOUT - int "SegAck transmission timeout per hop" - default 50 - range 50 250 +config BT_MESH_SAR_RX_SEG_THRESHOLD + hex "Acknowledgments retransmission threshold" + range 0x00 0x1F + default 0x03 help - Defines an additional per-hop timeout for the acknowledgment timer - used to delay transmission of the Segmented Acknowledgment message. + This value defines a threshold in number of segments of a segmented + message for acknowledgment retransmissions. 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 value of CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT. -config BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT - int "SegAck transmission timeout per segment not yet received" - default 0 - range 0 100 +config BT_MESH_SAR_RX_ACK_DELAY_INC + hex "Acknowledgment delay increment" + range 0x00 0x07 + default 0x01 + help + This value 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 + and calculated using the following formula: + CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC + 1.5. + +config BT_MESH_SAR_RX_SEG_INT_STEP + hex "Segments reception interval step" + range 0x00 0x0F + default 0x05 + help + This value defines the segments reception interval step used for + delaying the transmission of an acknowledgment message after + receiving a new segmnet. The interval is measured in milliseconds + and calculated using the following formula: + (CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP + 1) * 10 ms + +config BT_MESH_SAR_RX_DISCARD_TIMEOUT + hex "Discard timeout for reception of a segmented message" + range 0x00 0x0F + default 0x01 help - Defines an additional timeout for the acknowledgment timer for every - segment not yet received. + This value defines the time since the last successfully received + segment before giving up the reception of a segmented message. -endif # !BT_MESH_V1d1 +config BT_MESH_SAR_RX_ACK_RETRANS_COUNT + hex "Total number of acknowledgment message retransmission" + range 0x00 0x03 + default 0x00 + help + This value defines 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 + CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD value. endmenu # Transport SAR configuration @@ -598,7 +695,7 @@ config BT_MESH_ACCESS_LAYER_MSG help This option allows the application to directly access Bluetooth access layer messages without the need to - instantiate Bluetooth mesh models. + instantiate Bluetooth Mesh models. config BT_MESH_MODEL_VND_MSG_CID_FORCE bool "Force vendor model to use the corresponding CID field message" @@ -613,6 +710,38 @@ config BT_MESH_MODEL_EXTENSIONS Enable support for the model extension concept, allowing the Access layer to know about mesh model relationships. +config BT_MESH_COMP_PAGE_1 + bool "Support for Composition Data Page 1" + default y + help + Enable support for Composition Data Page 1. + +config BT_MESH_MODEL_EXTENSION_LIST_SIZE + int "Model extensions list size" + depends on BT_MESH_COMP_PAGE_1 + range 0 255 + default 0 if !BT_MESH_MODEL_EXTENSIONS + default 10 + help + This option specifies how many models relations can be saved. + Equals to the number of `bt_mesh_model_extend` and `bt_mesh_model_correspond` calls. + This information is used to construct 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_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_LABEL_NO_RECOVER bool "[DEPRECATED] Don't recover Label UUIDs from groups address subscription list" select DEPRECATED @@ -628,6 +757,61 @@ config BT_MESH_LABEL_NO_RECOVER unprovisioned before upgrading to the version with this option). The option is marked as deprecated to remove the recovery code eventually. +menuconfig BT_MESH_ACCESS_DELAYABLE_MSG + bool "Access layer tx delayable message" + default y + help + Enable following of the message transmitting recommendations, the Access layer + specification. The recommendations are optional. + However, they are strictly recommended if the device participates in the network with + intensive communication where the device receives a lot of requests that require responses. + +if BT_MESH_ACCESS_DELAYABLE_MSG + +config BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED + bool "The delayable message in the notification message context" + default y + help + Controls whether the delayable message feature is enabled by default in + the message context of the opcode notifications. This allows the server part of any + model to not bother about additional context configuration to enable the delayable message. + Note that if this is disabled then all foundation models stop using the delayable message + functionality. + +config BT_MESH_ACCESS_DELAYABLE_MSG_COUNT + int "Number of simultaneously delayed messages" + default 4 + help + The maximum number of messages the Access layer can manage to delay + at the same time. The number of messages can be handled only if the Access layer + has a sufficient amount of memory to store the model payload for them. + +config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE + int "Maximum delayable message storage chunk" + default 10 + help + Size of memory that Access layer uses to split model message to. It allocates + a sufficient number of these chunks from the pool to store the full model payload. + +config BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT + int "Maximum number of available chunks" + default 40 + help + The maximum number of available chunks the Access layer allocates to store model payload. + It is recommended to keep chunk size equal to the reasonable small value to prevent + unnecessary memory wasting. + +endif # BT_MESH_ACCESS_DELAYABLE_MSG + +config BT_MESH_DELAYABLE_PUBLICATION + bool "Delayable publication" + default y + help + When enabled, the periodic publications are randomly delayed by 20 to 50ms. Publications + triggered at the start of the stack or by the bt_mesh_model_publish() call are delayed by + 20 to 500ms. This option reduces the probability of collisions when multiple nodes publish + at the same time. + endmenu # Access layer menu "Models" @@ -666,973 +850,795 @@ config BT_MESH_HEALTH_CLI_TIMEOUT endif # BT_MESH_HEALTH_CLI -endmenu # Models - -menu "Proxy" - visible if BT_CONN - -menuconfig BT_MESH_GATT_PROXY - bool "GATT Proxy Service support" - select BT_MESH_GATT_SERVER - select BT_MESH_PROXY +menuconfig BT_MESH_BLOB_SRV + bool "Support for BLOB Transfer Server model" help - This option enables support for the Mesh GATT Proxy Service, - i.e. the ability to act as a proxy between a Mesh GATT Client - and a Mesh network. + Enable the Binary Large Object (BLOB) Transfer Server model. -if BT_MESH_GATT_PROXY +if BT_MESH_BLOB_SRV -config BT_MESH_GATT_PROXY_ENABLED - bool "GATT Proxy enabled" - depends on BT_MESH_GATT_PROXY - default y +config BT_MESH_BLOB_SRV_PULL_REQ_COUNT + int "Number of chunks to request for each pull" + default 4 + range 1 16 help - Controls whether the GATT Proxy feature is enabled by default. - Can be changed through runtime configuration. + In Pull mode (Pull BLOB Transfer Mode), the BLOB Transfer Server + requests a fixed number of chunks from the Client. Use this option to + control the chunk count in the request. If the BLOB Transfer Server + is instantiated on a Low Power node, the pull request count will be + trimmed to not overflow the Friend queue. -config BT_MESH_NODE_ID_TIMEOUT - int "Node Identity advertising timeout" - range 1 60 - default 60 +config BT_MESH_BLOB_SIZE_MAX + int "Largest BLOB size in bytes" + default 524288 + range 1 3257617792 help - This option determines for how long the local node advertises - using Node Identity. The given value is in seconds. The - specification limits this to 60 seconds, and implies that to - be the appropriate value as well, so just leaving this as the - default is the safest option. + The maximum object size a BLOB Transfer Server can receive. -config BT_MESH_PROXY_USE_DEVICE_NAME - bool "Include Bluetooth device name in scan response" +config BT_MESH_BLOB_BLOCK_SIZE_MIN + int "Minimum block size" + default 4096 + range 64 1048576 # 2^6 - 2^20 help - This option includes GAP device name in scan response when - the GATT Proxy feature is enabled. + Minimum acceptable block size in a BLOB transfer. The transfer block + size will be some number that is a power of two, and is between block + size min and block size max. If no such number exists, a compile + time warning will be issued. -config BT_MESH_PROXY_FILTER_SIZE - int "Maximum number of filter entries per Proxy Client" - default 16 - range 1 32767 +config BT_MESH_BLOB_BLOCK_SIZE_MAX + int "Maximum block size" + default 4096 + range BT_MESH_BLOB_BLOCK_SIZE_MIN 1048576 help - This option specifies how many Proxy Filter entries the local - node supports. This helps in reducing unwanted traffic getting sent to - the proxy client. This value is application specific and should be large - enough so that proxy client can communicate with several devices through - this proxy server node using the default accept list filter type. + Maximum acceptable block size in a BLOB transfer. The transfer block + size will be some number that is a power of two, and is between block + size min and block size max. If no such number exists, a compile + time warning will be issued. -endif # BT_MESH_GATT_PROXY - -config BT_MESH_PROXY_CLIENT - bool "Proxy client support" - select BT_GATT_CLIENT - select BT_MESH_GATT_CLIENT - depends on BT_CENTRAL +config BT_MESH_BLOB_REPORT_TIMEOUT + int "Partial Block Report interval in Pull mode" + default 10 + range 1 31 help - This option enables support for the Mesh GATT Proxy Client, - i.e. the ability to act as a proxy between a Mesh GATT Service - and a Mesh network. - -endmenu # Proxy + The timer value that Pull BLOB Transfer Server uses to report missed chunks. -choice BT_MESH_CRYPTO_LIB - prompt "Crypto library:" - default BT_MESH_USES_TFM_PSA if BUILD_WITH_TFM - default BT_MESH_USES_TINYCRYPT - help - Crypto library selection for mesh security. +endif # BT_MESH_BLOB_SRV -config BT_MESH_USES_TINYCRYPT - bool "TinyCrypt" - select TINYCRYPT - select TINYCRYPT_AES - select TINYCRYPT_AES_CMAC - select TINYCRYPT_ECC_DH - select TINYCRYPT_SHA256 - select TINYCRYPT_SHA256_HMAC - select BT_HOST_CCM +menuconfig BT_MESH_BLOB_CLI + bool "Support for BLOB Transfer Client model" help - Use TinyCrypt library to perform crypto operations. + Enable the Binary Large Object (BLOB) Transfer Client model. -config BT_MESH_USES_MBEDTLS_PSA - bool "mbed TLS PSA [EXPERIMENTAL]" - select EXPERIMENTAL - select MBEDTLS - select MBEDTLS_ZEPHYR_ENTROPY - select MBEDTLS_PSA_CRYPTO_C - select MBEDTLS_MAC_CMAC_ENABLED - select MBEDTLS_CIPHER_AES_ENABLED - select MBEDTLS_AES_ROM_TABLES - select MBEDTLS_CIPHER_CCM_ENABLED - select MBEDTLS_ECP_C - select MBEDTLS_ECDH_C - select MBEDTLS_ECDSA_C - select MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - select MBEDTLS_ECP_DP_SECP256R1_ENABLED - select MBEDTLS_PK_WRITE_C - help - Use mbed TLS library to perform crypto operations. Support of - mbed TLS and PSA is experimental and only BabbleSim tests were run. - Mbed TLS still does not support ITS (internal trust storage) based - on Zephyr's settings subsystem. - Not possible to use for embedded devices yet. +if BT_MESH_BLOB_CLI -config BT_MESH_USES_TFM_PSA - bool "Use TF-M PSA [EXPERIMENTAL]" - select EXPERIMENTAL - depends on BUILD_WITH_TFM +config BT_MESH_BLOB_CLI_BLOCK_RETRIES + int "Number of retries per block" + default 5 help - Use TF-M that implements PSA security framework. Support of TF-M is - experimental. It is only possible to use with platforms that TF-M supports. - For more platform details see TF-M documentation. + Controls the number of times the client will attempt to resend missing + chunks to the BLOB receivers for every block. -endchoice +endif -if BT_MESH_USES_MBEDTLS_PSA || BT_MESH_USES_TFM_PSA +menu "BLOB models common configuration" + visible if BT_MESH_BLOB_SRV || BT_MESH_BLOB_CLI -config BT_MESH_PSA_KEY_ID_USER_MIN_OFFSET - int "Offset of BLE Mesh key id range regarding PSA_KEY_ID_USER_MIN" - default 0 +config BT_MESH_BLOB_CHUNK_COUNT_MAX + int "Maximum chunk count per block" + default 256 + range 1 2992 help - The PSA specification mandates to set key identifiers for keys - with persistent lifetime. The users of the PSA API is responsible - (BLE Mesh is user of PSA API) to provide correct and unique identifiers. - The BLE Mesh identifier range should be between PSA_KEY_ID_USER_MIN and - PSA_KEY_ID_USER_MAX. BLE Mesh requires two ids for each subnetwork, two ids - for each application key, and two ids for the device key and device key candidate. - It should consider the Mesh Configuration Database instances if database enabled. + A BLOB transfer contains several blocks. Each block is made up of + several chunks. This option controls the maximum chunk count per + block. -endif # BT_MESH_USES_MBEDTLS_PSA || BT_MESH_USES_TFM_PSA +endmenu -config BT_MESH_BEACON_ENABLED - bool "Secure network beacon enabled" +config BT_MESH_BLOB_IO_FLASH + bool "BLOB flash stream" default y + depends on BT_MESH_BLOB_SRV || BT_MESH_BLOB_CLI + depends on FLASH_MAP help - Controls whether the Secure network beacon feature is enabled by - default. Can be changed through runtime configuration. + Enable the BLOB flash stream for reading and writing BLOBs directly to + and from flash. -menu "IV Index & Sequence number" +config BT_MESH_DFU_SRV + bool "Support for Firmware Update Server model" + depends on BT_MESH_BLOB_SRV + help + Enable the Firmware Update Server model. -config BT_MESH_IV_UPDATE_TEST - bool "Test the IV Update Procedure" +config BT_MESH_DFU_CLI + bool "Support for Firmware Update Client model" + depends on BT_MESH_BLOB_CLI help - This option removes the 96 hour limit of the IV Update - Procedure and lets the state be changed at any time. + Enable the Firmware Update Client model. -config BT_MESH_IV_UPDATE_SEQ_LIMIT - hex "Sequence number limit to start iv update" - default 0x800000 - range 0x000001 0xFFFFFE +menu "Firmware Update model configuration" + visible if BT_MESH_DFU_SRV || BT_MESH_DFU_CLI + +config BT_MESH_DFU_FWID_MAXLEN + int "DFU FWID max length" + default 16 + range 0 106 help - This option specifies the sequence number value to start iv update. + This value defines the maximum length of an image's firmware ID. -config BT_MESH_IVU_DIVIDER - int "Divider for IV Update state refresh timer" - default 4 - range 2 96 +config BT_MESH_DFU_METADATA_MAXLEN + int "DFU metadata max length" + default 32 + range 18 255 if BT_MESH_DFU_METADATA + range 0 255 help - When the IV Update state enters Normal operation or IV Update - in Progress, we need to keep track of how many hours has passed - in the state, since the specification requires us to remain in - the state at least for 96 hours (Update in Progress has an - additional upper limit of 144 hours). + This value defines the maximum length of an image's metadata. - In order to fulfill the above requirement, even if the node might - be powered off once in a while, we need to store persistently - how many hours the node has been in the state. This doesn't - necessarily need to happen every hour (thanks to the flexible - duration range). The exact cadence will depend a lot on the - ways that the node will be used and what kind of power source it - has. +config BT_MESH_DFU_METADATA + bool "Support for the default metadata format" + help + This option adds a set of functions that can be used to encode and decode a firmware + metadata using the format defined in the Bluetooth Mesh DFU subsystem. - Since there is no single optimal answer, this configuration - option allows specifying a divider, i.e. how many intervals - the 96 hour minimum gets split into. After each interval the - duration that the node has been in the current state gets - stored to flash. E.g. the default value of 4 means that the - state is saved every 24 hours (96 / 4). +config BT_MESH_DFU_URI_MAXLEN + int "DFU URI max length" + default 32 + range 0 255 + help + This value defines the maximum length of an image's URI, not including + a string terminator. -endmenu # IV Index & Sequence number +endmenu # Firmware Update model configuration -menuconfig BT_MESH_LOW_POWER - bool "Support for Low Power features" +menuconfig BT_MESH_DFU_SLOTS + bool "Firmware image slot manager" + default y if BT_MESH_DFU_CLI help - Enable this option to be able to act as a Low Power Node. + Enable the DFU image slot manager, for managing firmware distribution slots + for the Firmware Update Client model. -if BT_MESH_LOW_POWER +if BT_MESH_DFU_SLOTS -config BT_MESH_LPN_ESTABLISHMENT - bool "Perform Friendship establishment using low power" - default y +config BT_MESH_DFU_SLOT_CNT + int "Number of firmware image slots" + default 1 + range 1 32767 help - Perform the Friendship establishment using low power, with - the help of a reduced scan duty cycle. The downside of this - is that the node may miss out on messages intended for it - until it has successfully set up Friendship with a Friend - node. + This value defines the number of firmware slots the DFU image slot manager + can keep simultaneously. -config BT_MESH_LPN_AUTO - bool "Automatically start looking for Friend nodes once provisioned" - default y - help - Automatically enable LPN functionality once provisioned and start - looking for Friend nodes. If this option is disabled LPN mode - needs to be manually enabled by calling bt_mesh_lpn_set(true). +endif -config BT_MESH_LPN_AUTO_TIMEOUT - int "Time from last received message before going to LPN mode" - default 15 - range 0 3600 - depends on BT_MESH_LPN_AUTO +menuconfig BT_MESH_DFD_SRV + bool "Support for Firmware Distribution Server model" + depends on BT_MESH_BLOB_SRV + depends on BT_MESH_DFU_CLI help - Time in seconds from the last received message, that the node - will wait before starting to look for Friend nodes. + Enable the Firmware Distribution Server model. -config BT_MESH_LPN_RETRY_TIMEOUT - int "Retry timeout for Friend requests" - default 8 - range 1 3600 - help - Time in seconds between Friend Requests, if a previous Friend - Request did not receive any acceptable Friend Offers. +if BT_MESH_DFD_SRV -config BT_MESH_LPN_RSSI_FACTOR - int "RSSIFactor, used in the Friend Offer Delay calculation" - range 0 3 - default 0 +config BT_MESH_DFD_SRV_SLOT_MAX_SIZE + int "Largest DFU image that can be stored" + default BT_MESH_BLOB_SIZE_MAX + range 0 BT_MESH_BLOB_SIZE_MAX help - The contribution of the RSSI measured by the Friend node used - in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. + This value defines the largest DFU image a single slot can store. -config BT_MESH_LPN_RECV_WIN_FACTOR - int "ReceiveWindowFactor, used in the Friend Offer Delay calculation" - range 0 3 - default 0 +config BT_MESH_DFD_SRV_SLOT_SPACE + int "Total DFU image storage space" + default BT_MESH_DFD_SRV_SLOT_MAX_SIZE + range 0 4294967295 help - The contribution of the supported Receive Window used in - Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. + This value defines the total storage space dedicated to storing DFU + images on the Firmware Distribution Server. -config BT_MESH_LPN_MIN_QUEUE_SIZE - int "Minimum size of acceptable friend queue (MinQueueSizeLog)" - range 1 7 - default 1 +config BT_MESH_DFD_SRV_TARGETS_MAX + int "Maximum Target node count" + default 8 + range 1 65535 help - The MinQueueSizeLog field is defined as log_2(N), where N is - the minimum number of maximum size Lower Transport PDUs that - the Friend node can store in its Friend Queue. As an example, - MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128. + This value defines the maximum number of Target nodes the Firmware + Distribution Server can target simultaneously. -config BT_MESH_LPN_RECV_DELAY - int "Receive delay requested by the local node" - range 50 255 if BT_MESH_ADV_LEGACY - range 10 255 - default 100 +config BT_MESH_DFD_SRV_OOB_UPLOAD + bool "Support for DFU image OOB upload" help - The ReceiveDelay is the time between the Low Power node - sending a request and listening for a response. This delay - allows the Friend node time to prepare the response. The value - is in units of milliseconds. When BT_MESH_ADV_LEGACY is used, - the minimal value for the delay can not be less than 50ms due - to a limitation in the legacy advertiser implementation. + 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. -config BT_MESH_LPN_POLL_TIMEOUT - int "The value of the PollTimeout timer" - range 10 244735 - default 300 - help - PollTimeout timer is used to measure time between two - consecutive requests sent by the Low Power node. If no - requests are received by the Friend node before the - PollTimeout timer expires, then the friendship is considered - terminated. The value is in units of 100 milliseconds, so e.g. - a value of 300 means 30 seconds. +endif -config BT_MESH_LPN_INIT_POLL_TIMEOUT - int "The starting value of the PollTimeout timer" - range 10 BT_MESH_LPN_POLL_TIMEOUT - default BT_MESH_LPN_POLL_TIMEOUT +config BT_MESH_RPR_SRV + bool "Support for Remote Provisioning Server model" help - The initial value of the PollTimeout timer when Friendship - gets established for the first time. After this the timeout - will gradually grow toward the actual PollTimeout, doubling - in value for each iteration. The value is in units of 100 - milliseconds, so e.g. a value of 300 means 30 seconds. + The Remote Provisioning Server is the proxy for a provisioning + process, allowing provisioners to tunnel their provisioning + messages through the mesh to the Remote Provisioning Server, which + communicates directly with the unprovisioned node. -config BT_MESH_LPN_SCAN_LATENCY - int "Latency for enabling scanning" - range 0 50 - default 15 +config BT_MESH_RPR_CLI + bool "Support for Remote Provisioning Client model" + depends on BT_MESH_PROVISIONER help - Latency in milliseconds that it takes to enable scanning. This - is in practice how much time in advance before the Receive Window - that scanning is requested to be enabled. + The Remote Provisioning Client is instantiated on the provisioner + node, and allows provisioning of new devices through the mesh network + by tunnelling provisioning messages to a Remote Provisioning Server. -config BT_MESH_LPN_GROUPS - int "Number of groups the LPN can subscribe to" - range 0 16384 - default 8 - help - Maximum number of groups that the LPN can subscribe to. +menu "Remote Provisioning configuration" + visible if BT_MESH_RPR_SRV || BT_MESH_RPR_CLI -config BT_MESH_LPN_SUB_ALL_NODES_ADDR - bool "Automatically subscribe all nodes address" +config BT_MESH_RPR_AD_TYPES_MAX + int "Max AD types in extended scanning" + default 1 + range 1 16 help - Automatically subscribe all nodes address when friendship - established. - -endif # BT_MESH_LOW_POWER + During extended scanning, the Remote Provisioning Server can include + a set of AD types in the scan reports, collected from the + unprovisioned device's advertisement data. This option controls + the highest number of AD types a single server can scan for, and a + Client can request. -menuconfig BT_MESH_FRIEND - bool "Support for acting as a Friend Node" +config BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX + int "Max scannable unprovisioned devices for Remote Provisioning Server" + default 4 + range 4 255 help - Enable this option to be able to act as a Friend Node. - -if BT_MESH_FRIEND + Max number of unique unprovisioned devices a single Remote + Provisioning Server can hold. -config BT_MESH_FRIEND_ENABLED - bool "Friend feature enabled by default" - default y +config BT_MESH_RPR_SRV_AD_DATA_MAX + int "Max additional advertisement data to report" + default 31 + range 3 255 help - Controls whether the Friend feature is enabled by default when the - device boots up for the first time or unprovisioned. Can be changed - at runtime using bt_mesh_friend_set() function. + Buffer size for the additional advertisement data reported during + extended scanning. -config BT_MESH_FRIEND_RECV_WIN - int "Friend Receive Window" - range 1 255 - default 255 - help - Receive Window in milliseconds supported by the Friend node. +endmenu # Remote Provisioning configuration -config BT_MESH_FRIEND_QUEUE_SIZE - int "Minimum number of buffers supported per Friend Queue" - range 2 65536 - default 16 - help - Minimum number of buffers available to be stored for each - local Friend Queue. +config BT_MESH_SAR_CFG + bool -config BT_MESH_FRIEND_SUB_LIST_SIZE - int "Friend Subscription List Size" - range 0 1023 - default 3 +config BT_MESH_SAR_CFG_SRV + bool "Support for SAR Configuration Server model" + select BT_MESH_SAR_CFG help - Size of the Subscription List that can be supported by a - Friend node for a Low Power node. + Enable support for the SAR configuration server model. -config BT_MESH_FRIEND_LPN_COUNT - int "Number of supported LPN nodes" - range 1 1000 - default 2 +config BT_MESH_SAR_CFG_CLI + bool "Support for SAR Configuration Client Model" + select BT_MESH_SAR_CFG help - Number of Low Power Nodes the Friend can have a Friendship - with simultaneously. + Enable support for the SAR configuration client model. -config BT_MESH_FRIEND_SEG_RX - int "Number of incomplete segment lists per LPN" - range 1 1000 - default 1 +config BT_MESH_OP_AGG + bool + +config BT_MESH_OP_AGG_SRV + bool "Support for Opcode Aggregator Server Model" + select BT_MESH_OP_AGG help - Number of incomplete segment lists that we track for each LPN - that we are Friends for. In other words, this determines how - many elements we can simultaneously be receiving segmented - messages from when the messages are going into the Friend queue. + Enable support for the Opcode Aggregator Server model. -config BT_MESH_FRIEND_ADV_LATENCY - int "Latency for enabling advertising" - range 0 4 - default 0 +config BT_MESH_OP_AGG_CLI + bool "Support for Opcode Aggregator Client Model" + select BT_MESH_OP_AGG help - Latency in milliseconds between request for and start of Friend - advertising. Used to tune the ReceiveDelay, making Friend - start sending a message earlier thus compensating for the time between - pushing the message to the Bluetooth host and the actual advertising - start. + Enable support for the Opcode Aggregator Client model. -endif # BT_MESH_FRIEND +if BT_MESH_OP_AGG_CLI -menuconfig BT_MESH_V1d1 - bool "Bluetooth mesh v1.1 support" +config BT_MESH_OP_AGG_CLI_TIMEOUT + int "Opcodes Aggregator Client model timeout in milliseconds" + default 10000 help - This option enables Bluetooth mesh v1.1 support. Bluetooth mesh v1.1 - is backward compatible with v1.0.1. + This timeout controls how long Opcodes Aggregator Client waits + for a response message to arrive. This value can be changed at + runtime using @ref bt_mesh_op_agg_cli_timeout_set. -config BT_MESH_ECDH_P256_CMAC_AES128_AES_CCM - bool "Support CMAC AES128 for OOB authentication" if BT_MESH_V1d1 - depends on BT_MESH_PROV - default y +endif # BT_MESH_OP_AGG_CLI + +config BT_MESH_LARGE_COMP_DATA_SRV + bool "Support for Large Composition Data Server Model" help - Enable this option to support CMAC AES128 for OOB authentication. + Enable support for the Large Composition Data Server model. -if BT_MESH_V1d1 +if BT_MESH_LARGE_COMP_DATA_SRV -config BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM - bool "Support HMAC SHA256 for OOB authentication" - depends on BT_MESH_PROV - default y +config BT_MESH_MODELS_METADATA_PAGE_LEN + int "Maximum length of the Models Metadata Page" + default 150 help - Enable this option to support HMAC SHA256 for OOB authentication. + This value is the combined total metadata length for + all models on the device. -config BT_MESH_OOB_AUTH_REQUIRED - bool "OOB authentication mandates to use HMAC SHA256" - depends on BT_MESH_ECDH_P256_HMAC_SHA256_AES_CCM +endif # BT_MESH_LARGE_COMP_DATA_SRV -menuconfig BT_MESH_BLOB_SRV - bool "Support for BLOB Transfer Server model" +config BT_MESH_LARGE_COMP_DATA_CLI + bool "Support for Large Composition Data Client model" help - Enable the Binary Large Object (BLOB) Transfer Server model. + Enable support for the Large Composition Data Client model. -if BT_MESH_BLOB_SRV +if BT_MESH_PRIV_BEACONS -config BT_MESH_BLOB_SRV_PULL_REQ_COUNT - int "Number of chunks to request for each pull" - default 4 - range 1 16 +config BT_MESH_PRIV_BEACON_SRV + bool "Support for Private Beacon Server Model" help - In Pull mode (Pull BLOB Transfer Mode), the BLOB Transfer Server - requests a fixed number of chunks from the Client. Use this option to - control the chunk count in the request. If the BLOB Transfer Server - is instantiated on a Low Power node, the pull request count will be - trimmed to not overflow the Friend queue. + Enable support for the Private Beacon Server model. -config BT_MESH_BLOB_SIZE_MAX - int "Largest BLOB size in bytes" - default 524288 - range 1 3257617792 +config BT_MESH_PRIV_BEACON_CLI + bool "Support for Private Beacon Client Model" help - The maximum object size a BLOB Transfer Server can receive. + Enable support for the Private Beacon Client model. -config BT_MESH_BLOB_BLOCK_SIZE_MIN - int "Minimum block size" - default 4096 - range 64 1048576 # 2^6 - 2^20 - help - Minimum acceptable block size in a BLOB transfer. The transfer block - size will be some number that is a power of two, and is between block - size min and block size max. If no such number exists, a compile - time warning will be issued. +endif # BT_MESH_PRIV_BEACONS -config BT_MESH_BLOB_BLOCK_SIZE_MAX - int "Maximum block size" - default 4096 - range BT_MESH_BLOB_BLOCK_SIZE_MIN 1048576 +config BT_MESH_OD_PRIV_PROXY_CLI + bool "Support for On-Demand Private Proxy Client model" help - Maximum acceptable block size in a BLOB transfer. The transfer block - size will be some number that is a power of two, and is between block - size min and block size max. If no such number exists, a compile - time warning will be issued. + On-Demand Private Proxy Client allows to configure and check the state + of On-Demand Private Proxy Servers. The state determines if the peers will + advertise the Private Network Identity type after receiving a Solicitation PDU. -config BT_MESH_BLOB_REPORT_TIMEOUT - int "Partial Block Report interval in Pull mode" - default 10 - range 1 31 + +config BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT + int "Solicitation PDU RPL Configuration Client model timeout in milliseconds" + default 5000 + depends on BT_MESH_OD_PRIV_PROXY_CLI help - The timer value that Pull BLOB Transfer Server uses to report missed chunks. + This timeout controls how long the On-Demand Private Proxy Client waits + for a response message to arrive. This value can be changed at runtime + using @ref bt_mesh_od_priv_proxy_cli_timeout_set. -endif # BT_MESH_BLOB_SRV +config BT_MESH_OD_PRIV_PROXY_SRV + bool "Support for On-Demand Private Proxy Server model" + depends on BT_MESH_PRIV_BEACON_SRV + select BT_MESH_SOLICITATION + help + The On-Demand Private Proxy Server is used to support configuration of + advertising with Private Network Identity type of a node. + When enabled, the Solicitation PDU RPL Configuration Server model is also enabled. -menuconfig BT_MESH_BLOB_CLI - bool "Support for BLOB Transfer Client model" +config BT_MESH_PROXY_SRPL_SIZE + int "Size of solicitation replay protection list (SRPL)" + depends on BT_MESH_OD_PRIV_PROXY_SRV + default 10 + range 1 255 help - Enable the Binary Large Object (BLOB) Transfer Client model. + Size of SRPL. The list is used to determine if a received Solicitation PDU + is valid. It is valid when the SSRC field value of the received Solicitation PDU + is stored in the SRPL and the SSEQ field value is bigger than the corresponding + stored SSEQ value, or if the SSRC was not stored in the RPL and the SRPL still has + space for new entries. -if BT_MESH_BLOB_CLI +config BT_MESH_SOL_PDU_RPL_CLI + bool "Support for Solicitation PDU RPL Configuration Client model" + help + The Solicitation PDU RPL Configuration Client is used to support the + functionality of removing addresses from the solicitation replay + protection list (SRPL) of a node that supports the Solicitation + PDU RPL Configuration Server model. -config BT_MESH_BLOB_CLI_BLOCK_RETRIES - int "Number of retries per block" - default 5 +config BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT + int "Solicitation PDU RPL Configuration Client model timeout in milliseconds" + default 5000 + depends on BT_MESH_SOL_PDU_RPL_CLI help - Controls the number of times the client will attempt to resend missing - chunks to the BLOB receivers for every block. + This timeout controls how long Solicitation PDU RPL Configuration Client waits + for a response message to arrive. This value can be changed at runtime + using @ref bt_mesh_sol_pdu_rpl_cli_timeout_set. -endif +endmenu # Models -menu "BLOB models common configuration" - visible if BT_MESH_BLOB_SRV || BT_MESH_BLOB_CLI +menu "Proxy" + visible if BT_CONN -config BT_MESH_BLOB_CHUNK_COUNT_MAX - int "Maximum chunk count per block" - default 256 - range 1 2992 +menuconfig BT_MESH_GATT_PROXY + bool "GATT Proxy Service support" + select BT_MESH_GATT_SERVER + select BT_MESH_PROXY help - A BLOB transfer contains several blocks. Each block is made up of - several chunks. This option controls the maximum chunk count per - block. + This option enables support for the Mesh GATT Proxy Service, + i.e. the ability to act as a proxy between a Mesh GATT Client + and a Mesh network. -endmenu +if BT_MESH_GATT_PROXY -config BT_MESH_BLOB_IO_FLASH - bool "BLOB flash stream" +config BT_MESH_GATT_PROXY_ENABLED + bool "GATT Proxy enabled" + depends on BT_MESH_GATT_PROXY default y - depends on BT_MESH_BLOB_SRV || BT_MESH_BLOB_CLI - depends on FLASH_MAP help - Enable the BLOB flash stream for reading and writing BLOBs directly to - and from flash. + Controls whether the GATT Proxy feature is enabled by default. + Can be changed through runtime configuration. -config BT_MESH_DFU_SRV - bool "Support for Firmware Update Server model" - depends on BT_MESH_BLOB_SRV +config BT_MESH_NODE_ID_TIMEOUT + int "Node Identity advertising timeout" + range 1 60 + default 60 help - Enable the Firmware Update Server model. + This option determines for how long the local node advertises + using Node Identity. The given value is in seconds. The + specification limits this to 60 seconds, and implies that to + be the appropriate value as well, so just leaving this as the + default is the safest option. -config BT_MESH_DFU_CLI - bool "Support for Firmware Update Client model" - depends on BT_MESH_BLOB_CLI +config BT_MESH_PROXY_USE_DEVICE_NAME + bool "Include Bluetooth device name in scan response" help - Enable the Firmware Update Client model. - -menu "Firmware Update model configuration" - visible if BT_MESH_DFU_SRV || BT_MESH_DFU_CLI + This option includes GAP device name in scan response when + the GATT Proxy feature is enabled. -config BT_MESH_DFU_FWID_MAXLEN - int "DFU FWID max length" +config BT_MESH_PROXY_FILTER_SIZE + int "Maximum number of filter entries per Proxy Client" default 16 - range 0 106 - help - This value defines the maximum length of an image's firmware ID. - -config BT_MESH_DFU_METADATA_MAXLEN - int "DFU metadata max length" - default 32 - range 18 255 if BT_MESH_DFU_METADATA - range 0 255 + range 1 32767 help - This value defines the maximum length of an image's metadata. + This option specifies how many Proxy Filter entries the local + node supports. This helps in reducing unwanted traffic getting sent to + the proxy client. This value is application specific and should be large + enough so that proxy client can communicate with several devices through + this proxy server node using the default accept list filter type. -config BT_MESH_DFU_METADATA - bool "Support for the default metadata format" - help - This option adds a set of functions that can be used to encode and decode a firmware - metadata using the format defined in the Bluetooth mesh DFU subsystem. +endif # BT_MESH_GATT_PROXY -config BT_MESH_DFU_URI_MAXLEN - int "DFU URI max length" - default 32 - range 0 255 +config BT_MESH_PROXY_CLIENT + bool "Proxy client support" + select BT_GATT_CLIENT + select BT_MESH_GATT_CLIENT + depends on BT_CENTRAL help - This value defines the maximum length of an image's URI, not including - a string terminator. + This option enables support for the Mesh GATT Proxy Client, + i.e. the ability to act as a proxy between a Mesh GATT Service + and a Mesh network. -endmenu +config BT_MESH_SOLICITATION + bool -menuconfig BT_MESH_DFU_SLOTS - bool "Firmware image slot manager" - default y if BT_MESH_DFU_CLI +config BT_MESH_PROXY_SOLICITATION + bool "Proxy solicitation feature" + select BT_MESH_SOLICITATION help - Enable the DFU image slot manager, for managing firmware distribution slots - for the Firmware Update Client model. - -if BT_MESH_DFU_SLOTS + This option enables support for sending Solicitation PDUs. -config BT_MESH_DFU_SLOT_CNT - int "Number of firmware image slots" - default 1 - range 1 32767 +config BT_MESH_SOL_ADV_XMIT + int "Solicitation PDU retransmission count" + depends on BT_MESH_PROXY_SOLICITATION + range 0 10 + default 2 help - This value defines the number of firmware slots the DFU image slot manager - can keep simultaneously. + How many times Solicitation PDU advertisements will be repeated. 0 means that there will be + 1 transmission without retransmissions. -endif +endmenu # Proxy -menuconfig BT_MESH_DFD_SRV - bool "Support for Firmware Distribution Server model" - depends on BT_MESH_BLOB_SRV - depends on BT_MESH_DFU_CLI +choice BT_MESH_CRYPTO_LIB + prompt "Crypto library:" + default BT_MESH_USES_TFM_PSA if BUILD_WITH_TFM + default BT_MESH_USES_TINYCRYPT help - Enable the Firmware Distribution Server model. - -if BT_MESH_DFD_SRV + Crypto library selection for mesh security. -config BT_MESH_DFD_SRV_SLOT_MAX_SIZE - int "Largest DFU image that can be stored" - default BT_MESH_BLOB_SIZE_MAX - range 0 BT_MESH_BLOB_SIZE_MAX +config BT_MESH_USES_TINYCRYPT + bool "TinyCrypt" + select TINYCRYPT + select TINYCRYPT_AES + select TINYCRYPT_AES_CMAC + select TINYCRYPT_ECC_DH + select TINYCRYPT_SHA256 + select TINYCRYPT_SHA256_HMAC + select BT_HOST_CCM help - This value defines the largest DFU image a single slot can store. + Use TinyCrypt library to perform crypto operations. -config BT_MESH_DFD_SRV_SLOT_SPACE - int "Total DFU image storage space" - default BT_MESH_DFD_SRV_SLOT_MAX_SIZE - range 0 4294967295 +config BT_MESH_USES_MBEDTLS_PSA + bool "mbed TLS PSA [EXPERIMENTAL]" + select EXPERIMENTAL + select MBEDTLS + select MBEDTLS_ZEPHYR_ENTROPY + select MBEDTLS_PSA_CRYPTO_C + select MBEDTLS_MAC_CMAC_ENABLED + select MBEDTLS_CIPHER_AES_ENABLED + select MBEDTLS_AES_ROM_TABLES + select MBEDTLS_CIPHER_CCM_ENABLED + select MBEDTLS_ECP_C + select MBEDTLS_ECDH_C + select MBEDTLS_ECDSA_C + select MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + select MBEDTLS_ECP_DP_SECP256R1_ENABLED + select MBEDTLS_PK_WRITE_C help - This value defines the total storage space dedicated to storing DFU - images on the Firmware Distribution Server. + Use mbed TLS library to perform crypto operations. Support of + mbed TLS and PSA is experimental and only BabbleSim tests were run. + Mbed TLS still does not support ITS (internal trust storage) based + on Zephyr's settings subsystem. + Not possible to use for embedded devices yet. -config BT_MESH_DFD_SRV_TARGETS_MAX - int "Maximum Target node count" - default 8 - range 1 65535 +config BT_MESH_USES_TFM_PSA + bool "Use TF-M PSA [EXPERIMENTAL]" + select EXPERIMENTAL + depends on BUILD_WITH_TFM help - This value defines the maximum number of Target nodes the Firmware - Distribution Server can target simultaneously. + Use TF-M that implements PSA security framework. Support of TF-M is + experimental. It is only possible to use with platforms that TF-M supports. + For more platform details see TF-M documentation. -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. +endchoice -endif +if BT_MESH_USES_MBEDTLS_PSA || BT_MESH_USES_TFM_PSA -config BT_MESH_RPR_SRV - bool "Support for Remote Provisioning Server model" - help - The Remote Provisioning Server is the proxy for a provisioning - process, allowing provisioners to tunnel their provisioning - messages through the mesh to the Remote Provisioning Server, which - communicates directly with the unprovisioned node. - -config BT_MESH_RPR_CLI - bool "Support for Remote Provisioning Client model" - depends on BT_MESH_PROVISIONER +config BT_MESH_PSA_KEY_ID_USER_MIN_OFFSET + int "Offset of BLE Mesh key id range regarding PSA_KEY_ID_USER_MIN" + default 0 help - The Remote Provisioning Client is instantiated on the provisioner - node, and allows provisioning of new devices through the mesh network - by tunnelling provisioning messages to a Remote Provisioning Server. - -menu "Remote Provisioning configuration" - visible if BT_MESH_RPR_SRV || BT_MESH_RPR_CLI + The PSA specification mandates to set key identifiers for keys + with persistent lifetime. The users of the PSA API is responsible + (BLE Mesh is user of PSA API) to provide correct and unique identifiers. + The BLE Mesh identifier range should be between PSA_KEY_ID_USER_MIN and + PSA_KEY_ID_USER_MAX. BLE Mesh requires two ids for each subnetwork, two ids + for each application key, and two ids for the device key and device key candidate. + It should consider the Mesh Configuration Database instances if database enabled. -config BT_MESH_RPR_AD_TYPES_MAX - int "Max AD types in extended scanning" - default 1 - range 1 16 - help - During extended scanning, the Remote Provisioning Server can include - a set of AD types in the scan reports, collected from the - unprovisioned device's advertisement data. This option controls - the highest number of AD types a single server can scan for, and a - Client can request. +endif # BT_MESH_USES_MBEDTLS_PSA || BT_MESH_USES_TFM_PSA -config BT_MESH_RPR_SRV_SCANNED_ITEMS_MAX - int "Max scannable unprovisioned devices for Remote Provisioning Server" - default 4 - range 4 255 - help - Max number of unique unprovisioned devices a single Remote - Provisioning Server can hold. +menu "Beacons" -config BT_MESH_RPR_SRV_AD_DATA_MAX - int "Max additional advertisement data to report" - default 31 - range 3 255 +config BT_MESH_BEACON_ENABLED + bool "Secure network beacon enabled" + default y help - Buffer size for the additional advertisement data reported during - extended scanning. -endmenu - -config BT_MESH_SAR_CFG - bool + Controls whether the Secure network beacon feature is enabled by + default. Can be changed through runtime configuration. -config BT_MESH_SAR_CFG_SRV - bool "Support for SAR Configuration Server model" - select BT_MESH_SAR_CFG +config BT_MESH_PRIV_BEACONS + bool "Support for private beacons" + default y help - Enable support for the SAR configuration server model. + Enable support for private beacons. -config BT_MESH_SAR_CFG_CLI - bool "Support for SAR Configuration Client Model" - select BT_MESH_SAR_CFG - help - Enable support for the SAR configuration client model. +endmenu # Beacons -config BT_MESH_OP_AGG - bool +menu "IV Index & Sequence number" -config BT_MESH_OP_AGG_SRV - bool "Support for Opcode Aggregator Server Model" - select BT_MESH_OP_AGG +config BT_MESH_IV_UPDATE_TEST + bool "Test the IV Update Procedure" help - Enable support for the Opcode Aggregator Server model. + This option removes the 96 hour limit of the IV Update + Procedure and lets the state be changed at any time. -config BT_MESH_OP_AGG_CLI - bool "Support for Opcode Aggregator Client Model" - select BT_MESH_OP_AGG +config BT_MESH_IV_UPDATE_SEQ_LIMIT + hex "Sequence number limit to start iv update" + default 0x800000 + range 0x000001 0xFFFFFE help - Enable support for the Opcode Aggregator Client model. - -if BT_MESH_OP_AGG_CLI + This option specifies the sequence number value to start iv update. -config BT_MESH_OP_AGG_CLI_TIMEOUT - int "Opcodes Aggregator Client model timeout in milliseconds" - default 10000 +config BT_MESH_IVU_DIVIDER + int "Divider for IV Update state refresh timer" + default 4 + range 2 96 help - This timeout controls how long Opcodes Aggregator Client waits - for a response message to arrive. This value can be changed at - runtime using @ref bt_mesh_op_agg_cli_timeout_set. + When the IV Update state enters Normal operation or IV Update + in Progress, we need to keep track of how many hours has passed + in the state, since the specification requires us to remain in + the state at least for 96 hours (Update in Progress has an + additional upper limit of 144 hours). -endif # BT_MESH_OP_AGG_CLI + In order to fulfill the above requirement, even if the node might + be powered off once in a while, we need to store persistently + how many hours the node has been in the state. This doesn't + necessarily need to happen every hour (thanks to the flexible + duration range). The exact cadence will depend a lot on the + ways that the node will be used and what kind of power source it + has. -config BT_MESH_LARGE_COMP_DATA_SRV - bool "Support for Large Composition Data Server Model" - help - Enable support for the Large Composition Data Server model. + Since there is no single optimal answer, this configuration + option allows specifying a divider, i.e. how many intervals + the 96 hour minimum gets split into. After each interval the + duration that the node has been in the current state gets + stored to flash. E.g. the default value of 4 means that the + state is saved every 24 hours (96 / 4). -if BT_MESH_LARGE_COMP_DATA_SRV +endmenu # IV Index & Sequence number -config BT_MESH_MODELS_METADATA_PAGE_LEN - int "Maximum length of the Models Metadata Page" - default 150 +menuconfig BT_MESH_LOW_POWER + bool "Support for Low Power features" help - This value is the combined total metadata length for - all models on the device. - -endif # BT_MESH_LARGE_COMP_DATA_SRV + Enable this option to be able to act as a Low Power Node. -config BT_MESH_LARGE_COMP_DATA_CLI - bool "Support for Large Composition Data Client model" - help - Enable support for the Large Composition Data Client model. +if BT_MESH_LOW_POWER -config BT_MESH_PRIV_BEACONS - bool "Support for private beacons" +config BT_MESH_LPN_ESTABLISHMENT + bool "Perform Friendship establishment using low power" default y help - Enable support for private beacons. - -if BT_MESH_PRIV_BEACONS - -config BT_MESH_PRIV_BEACON_SRV - bool "Support for Private Beacon Server Model" - help - Enable support for the Private Beacon Server model. - -config BT_MESH_PRIV_BEACON_CLI - bool "Support for Private Beacon Client Model" - help - Enable support for the Private Beacon Client model. - -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 - help - Enable support for Composition Data Page 1. + Perform the Friendship establishment using low power, with + the help of a reduced scan duty cycle. The downside of this + is that the node may miss out on messages intended for it + until it has successfully set up Friendship with a Friend + node. -config BT_MESH_COMP_PAGE_2 - bool "Support for Composition Data Page 2" +config BT_MESH_LPN_AUTO + bool "Automatically start looking for Friend nodes once provisioned" + default y help - Enable support for Composition Data Page 2. + Automatically enable LPN functionality once provisioned and start + looking for Friend nodes. If this option is disabled LPN mode + needs to be manually enabled by calling bt_mesh_lpn_set(true). -config BT_MESH_MODEL_EXTENSION_LIST_SIZE - int "Model extensions list size" - depends on BT_MESH_COMP_PAGE_1 - range 0 255 - default 10 +config BT_MESH_LPN_AUTO_TIMEOUT + int "Time from last received message before going to LPN mode" + default 15 + range 0 3600 + depends on BT_MESH_LPN_AUTO help - This option specifies how many models relations can be saved. - Equals to the number of `bt_mesh_model_extend` and `bt_mesh_model_correspond` calls. - This information is used to construct Composition Data Page 1. - -config BT_MESH_SOLICITATION - bool + Time in seconds from the last received message, that the node + will wait before starting to look for Friend nodes. -config BT_MESH_PROXY_SOLICITATION - bool "Proxy solicitation feature" - select BT_MESH_SOLICITATION +config BT_MESH_LPN_RETRY_TIMEOUT + int "Retry timeout for Friend requests" + default 8 + range 1 3600 help - This option enables support for sending Solicitation PDUs. + Time in seconds between Friend Requests, if a previous Friend + Request did not receive any acceptable Friend Offers. -config BT_MESH_SOL_ADV_XMIT - int "Solicitation PDU retransmission count" - depends on BT_MESH_PROXY_SOLICITATION - range 0 10 - default 2 +config BT_MESH_LPN_RSSI_FACTOR + int "RSSIFactor, used in the Friend Offer Delay calculation" + range 0 3 + default 0 help - How many times Solicitation PDU advertisements will be repeated. 0 means that there will be - 1 transmission without retransmissions. + The contribution of the RSSI measured by the Friend node used + in Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. -config BT_MESH_OD_PRIV_PROXY_CLI - bool "Support for On-Demand Private Proxy Client model" +config BT_MESH_LPN_RECV_WIN_FACTOR + int "ReceiveWindowFactor, used in the Friend Offer Delay calculation" + range 0 3 + default 0 help - On-Demand Private Proxy Client allows to configure and check the state - of On-Demand Private Proxy Servers. The state determines if the peers will - advertise the Private Network Identity type after receiving a Solicitation PDU. - + The contribution of the supported Receive Window used in + Friend Offer Delay calculations. 0 = 1, 1 = 1.5, 2 = 2, 3 = 2.5. -config BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT - int "Solicitation PDU RPL Configuration Client model timeout in milliseconds" - default 5000 - depends on BT_MESH_OD_PRIV_PROXY_CLI +config BT_MESH_LPN_MIN_QUEUE_SIZE + int "Minimum size of acceptable friend queue (MinQueueSizeLog)" + range 1 7 + default 1 help - This timeout controls how long the On-Demand Private Proxy Client waits - for a response message to arrive. This value can be changed at runtime - using @ref bt_mesh_od_priv_proxy_cli_timeout_set. + The MinQueueSizeLog field is defined as log_2(N), where N is + the minimum number of maximum size Lower Transport PDUs that + the Friend node can store in its Friend Queue. As an example, + MinQueueSizeLog value 1 gives N = 2, and value 7 gives N = 128. -config BT_MESH_OD_PRIV_PROXY_SRV - bool "Support for On-Demand Private Proxy Server model" - depends on BT_MESH_PRIV_BEACON_SRV - select BT_MESH_SOLICITATION +config BT_MESH_LPN_RECV_DELAY + int "Receive delay requested by the local node" + range 50 255 if BT_MESH_ADV_LEGACY + range 10 255 + default 100 help - The On-Demand Private Proxy Server is used to support configuration of - advertising with Private Network Identity type of a node. - When enabled, the Solicitation PDU RPL Configuration Server model is also enabled. + The ReceiveDelay is the time between the Low Power node + sending a request and listening for a response. This delay + allows the Friend node time to prepare the response. The value + is in units of milliseconds. When BT_MESH_ADV_LEGACY is used, + the minimal value for the delay can not be less than 50ms due + to a limitation in the legacy advertiser implementation. -config BT_MESH_PROXY_SRPL_SIZE - int "Size of solicitation replay protection list (SRPL)" - depends on BT_MESH_OD_PRIV_PROXY_SRV - default 10 - range 1 255 +config BT_MESH_LPN_POLL_TIMEOUT + int "The value of the PollTimeout timer" + range 10 244735 + default 300 help - Size of SRPL. The list is used to determine if a received Solicitation PDU - is valid. It is valid when the SSRC field value of the received Solicitation PDU - is stored in the SRPL and the SSEQ field value is bigger than the corresponding - stored SSEQ value, or if the SSRC was not stored in the RPL and the SRPL still has - space for new entries. + PollTimeout timer is used to measure time between two + consecutive requests sent by the Low Power node. If no + requests are received by the Friend node before the + PollTimeout timer expires, then the friendship is considered + terminated. The value is in units of 100 milliseconds, so e.g. + a value of 300 means 30 seconds. -config BT_MESH_SOL_PDU_RPL_CLI - bool "Support for Solicitation PDU RPL Configuration Client model" +config BT_MESH_LPN_INIT_POLL_TIMEOUT + int "The starting value of the PollTimeout timer" + range 10 BT_MESH_LPN_POLL_TIMEOUT + default BT_MESH_LPN_POLL_TIMEOUT help - The Solicitation PDU RPL Configuration Client is used to support the - functionality of removing addresses from the solicitation replay - protection list (SRPL) of a node that supports the Solicitation - PDU RPL Configuration Server model. + The initial value of the PollTimeout timer when Friendship + gets established for the first time. After this the timeout + will gradually grow toward the actual PollTimeout, doubling + in value for each iteration. The value is in units of 100 + milliseconds, so e.g. a value of 300 means 30 seconds. -config BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT - int "Solicitation PDU RPL Configuration Client model timeout in milliseconds" - default 5000 - depends on BT_MESH_SOL_PDU_RPL_CLI +config BT_MESH_LPN_SCAN_LATENCY + int "Latency for enabling scanning" + range 0 50 + default 2 help - This timeout controls how long Solicitation PDU RPL Configuration Client waits - for a response message to arrive. This value can be changed at runtime - using @ref bt_mesh_sol_pdu_rpl_cli_timeout_set. - -menu "Transport SAR configuration" + Latency in milliseconds that it takes to enable scanning. This + is in practice how much time in advance before the Receive Window + that scanning is requested to be enabled. -config BT_MESH_SAR_TX_SEG_INT_STEP - hex "Interval between sending two consecutive segments" - range 0x00 0x0F - default 0x05 +config BT_MESH_LPN_GROUPS + int "Number of groups the LPN can subscribe to" + range 0 16384 + default 8 help - This value controls the interval between sending two consecutive - segments in a segmented message. The interval is measured in - milliseconds and calculated using the following formula: - (CONFIG_BT_MESH_SAR_TX_SEG_INT_STEP + 1) * 10 ms. + Maximum number of groups that the LPN can subscribe to. -config BT_MESH_SAR_TX_UNICAST_RETRANS_COUNT - hex "Maximum number of retransmissions to unicast address" - range 0x00 0x0F - default 0x02 +config BT_MESH_LPN_SUB_ALL_NODES_ADDR + bool "Automatically subscribe all nodes address" help - This value controls the maximum number of retransmissions of a - segmented message to a unicast address before giving up the transfer. + Automatically subscribe all nodes address when friendship + established. -config BT_MESH_SAR_TX_UNICAST_RETRANS_WITHOUT_PROG_COUNT - hex "Maximum number of retransmissions without progress to a unicast address" - range 0x00 0x0F - default 0x02 - help - This value defines the maximum number of retransmissions of a - segmented message to a unicast address that the stack will send if no - acknowledgment was received during timeout, or if an - acknowledgment with already confirmed segments was received. +endif # BT_MESH_LOW_POWER -config BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP - hex "Retransmissions interval step of missing segments to unicast address" - range 0x00 0x0F - default 0x07 +menuconfig BT_MESH_FRIEND + bool "Support for acting as a Friend Node" help - This value 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 and - calculated using the following formula: - (CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_STEP + 1) * 25 ms. + Enable this option to be able to act as a Friend Node. -config BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC - hex "Retransmissions interval increment of missing segments to unicast address" - range 0x00 0x0F - default 0x01 - help - This value 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 and - calculated using the following formula: - (CONFIG_BT_MESH_SAR_TX_UNICAST_RETRANS_INT_INC + 1) * 25 ms. +if BT_MESH_FRIEND -config BT_MESH_SAR_TX_MULTICAST_RETRANS_COUNT - hex "Total number of retransmissions to multicast address" - range 0x00 0x0F - default 0x02 +config BT_MESH_FRIEND_ENABLED + bool "Friend feature enabled by default" + default y help - This value controls the total number of retransmissions of a segmented - message to a multicast address. + Controls whether the Friend feature is enabled by default when the + device boots up for the first time or unprovisioned. Can be changed + at runtime using bt_mesh_friend_set() function. -config BT_MESH_SAR_TX_MULTICAST_RETRANS_INT - hex "Interval between retransmissions to multicast address" - range 0x00 0x0F - default 0x09 +config BT_MESH_FRIEND_RECV_WIN + int "Friend Receive Window" + range 1 255 + default 255 help - This value controls the interval between retransmissions of all - segments in a segmented message to a multicast address. The - interval is measured in milliseconds and calculated using the - following formula: - (CONFIG_BT_MESH_SAR_TX_MULTICAST_RETRANS_INT + 1) * 25 ms. + Receive Window in milliseconds supported by the Friend node. -config BT_MESH_SAR_RX_SEG_THRESHOLD - hex "Acknowledgments retransmission threshold" - range 0x00 0x1F - default 0x03 +config BT_MESH_FRIEND_QUEUE_SIZE + int "Minimum number of buffers supported per Friend Queue" + range 2 65536 + default 16 help - This value defines a threshold in number of segments of a segmented - message for acknowledgment retransmissions. 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 value of CONFIG_BT_MESH_SAR_RX_ACK_RETRANS_COUNT. + Minimum number of buffers available to be stored for each + local Friend Queue. -config BT_MESH_SAR_RX_ACK_DELAY_INC - hex "Acknowledgment delay increment" - range 0x00 0x07 - default 0x01 +config BT_MESH_FRIEND_SUB_LIST_SIZE + int "Friend Subscription List Size" + range 0 1023 + default 3 help - This value 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 - and calculated using the following formula: - CONFIG_BT_MESH_SAR_RX_ACK_DELAY_INC + 1.5. + Size of the Subscription List that can be supported by a + Friend node for a Low Power node. -config BT_MESH_SAR_RX_SEG_INT_STEP - hex "Segments reception interval step" - range 0x00 0x0F - default 0x05 +config BT_MESH_FRIEND_LPN_COUNT + int "Number of supported LPN nodes" + range 1 1000 + default 2 help - This value defines the segments reception interval step used for - delaying the transmission of an acknowledgment message after - receiving a new segmnet. The interval is measured in milliseconds - and calculated using the following formula: - (CONFIG_BT_MESH_SAR_RX_SEG_INT_STEP + 1) * 10 ms + Number of Low Power Nodes the Friend can have a Friendship + with simultaneously. -config BT_MESH_SAR_RX_DISCARD_TIMEOUT - hex "Discard timeout for reception of a segmented message" - range 0x00 0x0F - default 0x01 +config BT_MESH_FRIEND_SEG_RX + int "Number of incomplete segment lists per LPN" + range 1 1000 + default 1 help - This value defines the time since the last successfully received - segment before giving up the reception of a segmented message. + Number of incomplete segment lists that we track for each LPN + that we are Friends for. In other words, this determines how + many elements we can simultaneously be receiving segmented + messages from when the messages are going into the Friend queue. -config BT_MESH_SAR_RX_ACK_RETRANS_COUNT - hex "Total number of acknowledgment message retransmission" - range 0x00 0x03 - default 0x00 +config BT_MESH_FRIEND_ADV_LATENCY + int "Latency for enabling advertising" + range 0 4 + default 0 help - This value defines 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 - CONFIG_BT_MESH_SAR_RX_SEG_THRESHOLD value. - -endmenu + Latency in milliseconds between request for and start of Friend + advertising. Used to tune the ReceiveDelay, making Friend + start sending a message earlier thus compensating for the time between + pushing the message to the Bluetooth host and the actual advertising + start. -endif # BT_MESH_V1d1 +endif # BT_MESH_FRIEND menu "Capabilities" @@ -1734,16 +1740,16 @@ config BT_MESH_RPL_STORE_TIMEOUT endif # BT_MESH_RPL_STORAGE_MODE_SETTINGS && BT_SETTINGS config BT_MESH_SETTINGS_WORKQ - bool "Store the Bluetooth mesh settings in a separate work queue" + bool "Store the Bluetooth Mesh settings in a separate work queue" default y help This option enables a separate cooperative thread which is used to - store Bluetooth mesh configuration. When this option is disabled, + store Bluetooth Mesh configuration. When this option is disabled, the stack's configuration is stored in the system workqueue. This means that the system workqueue will be blocked for the time needed to store the pending data. This time may significantly increase if the flash driver does the erase operation. Enabling this option - allows Bluetooth mesh not to block the system workqueue, and thus + allows Bluetooth Mesh not to block the system workqueue, and thus process the incoming and outgoing messages while the flash driver waits for the controller to allocate the time needed to write the data and/or erase the required flash pages. diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index dcf7f0f783b..328ec0dd281 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -19,7 +19,6 @@ #include "host/testing.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "lpn.h" #include "transport.h" @@ -28,11 +27,17 @@ #include "op_agg.h" #include "settings.h" #include "va.h" +#include "delayable_msg.h" #define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_mesh_access); +/* 20 - 50ms */ +#define RANDOM_DELAY_SHORT 30 +/* 20 - 500ms */ +#define RANDOM_DELAY_LONG 480 + /* Model publication information for persistent storage. */ struct mod_pub_val { struct { @@ -761,8 +766,16 @@ static int32_t next_period(const struct bt_mesh_model *mod) if (period && elapsed >= period) { LOG_WRN("Retransmission interval is too short"); - /* Return smallest positive number since 0 means disabled */ - return 1; + + if (!!pub->delayable) { + LOG_WRN("Publication period is too short for" + " retransmissions"); + } + + /* Keep retransmitting the message with the interval sacrificing the + * next publication period start. + */ + return BT_MESH_PUB_TRANSMIT_INT(mod->pub->retransmit); } } @@ -775,6 +788,11 @@ static int32_t next_period(const struct bt_mesh_model *mod) if (elapsed >= period) { LOG_WRN("Publication sending took longer than the period"); + + if (!!pub->delayable) { + LOG_WRN("Publication period is too short to be delayable"); + } + /* Return smallest positive number since 0 means disabled */ return 1; } @@ -855,6 +873,39 @@ static int pub_period_start(struct bt_mesh_model_pub *pub) return 0; } +static uint16_t pub_delay_get(int random_delay_window) +{ + if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) { + return 0; + } + + uint16_t num = 0; + + (void)bt_rand(&num, sizeof(num)); + + return 20 + (num % random_delay_window); +} + +static int pub_delay_schedule(struct bt_mesh_model_pub *pub, int delay) +{ + uint16_t random; + int err; + + if (!IS_ENABLED(CONFIG_BT_MESH_DELAYABLE_PUBLICATION)) { + return -ENOTSUP; + } + + random = pub_delay_get(delay); + err = k_work_reschedule(&pub->timer, K_MSEC(random)); + if (err < 0) { + LOG_ERR("Unable to delay publication (err %d)", err); + return err; + } + + LOG_DBG("Publication delayed by %dms", random); + return 0; +} + static void mod_publish(struct k_work *work) { struct k_work_delayable *dwork = k_work_delayable_from_work(work); @@ -871,7 +922,7 @@ static void mod_publish(struct k_work *work) return; } - LOG_DBG("%u", k_uptime_get_32()); + LOG_DBG("timestamp: %u", k_uptime_get_32()); if (pub->count) { pub->count--; @@ -890,6 +941,13 @@ static void mod_publish(struct k_work *work) if (err) { return; } + + /* Delay the first publication in a period. */ + if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_SHORT)) { + /* Increment count as it would do BT_MESH_PUB_MSG_TOTAL */ + pub->count++; + return; + } } err = publish_transmit(pub->mod); @@ -1008,13 +1066,13 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp) err = 0; - if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + if (MOD_REL_LIST_SIZE > 0) { memset(mod_rel_list, 0, sizeof(mod_rel_list)); } bt_mesh_model_foreach(mod_init, &err); - if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + if (MOD_REL_LIST_SIZE > 0) { int i; MOD_REL_LIST_FOR_EACH(i) { @@ -1424,7 +1482,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->rt->addr); + LOG_DBG("No OpCode 0x%08x for elem 0x%02x", opcode, elem->rt->addr); return ACCESS_STATUS_WRONG_OPCODE; } @@ -1446,6 +1504,10 @@ static int element_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple return ACCESS_STATUS_MESSAGE_NOT_UNDERSTOOD; } + if (IS_ENABLED(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CTX_ENABLED)) { + ctx->rnd_delay = true; + } + net_buf_simple_save(buf, &state); err = op->func(model, ctx, buf); net_buf_simple_restore(buf, &state); @@ -1519,6 +1581,15 @@ int bt_mesh_model_send(const struct bt_mesh_model *model, struct bt_mesh_msg_ctx return -EINVAL; } +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + /* No sense to use delayable message for unicast loopback. */ + if (ctx->rnd_delay && + !(bt_mesh_has_addr(ctx->addr) && BT_MESH_ADDR_IS_UNICAST(ctx->addr))) { + return bt_mesh_delayable_msg_manage(ctx, msg, bt_mesh_model_elem(model)->rt->addr, + cb, cb_data); + } +#endif + return bt_mesh_access_send(ctx, msg, bt_mesh_model_elem(model)->rt->addr, cb, cb_data); } @@ -1557,6 +1628,18 @@ int bt_mesh_model_publish(const struct bt_mesh_model *model) LOG_DBG("Publish Retransmit Count %u Interval %ums", pub->count, BT_MESH_PUB_TRANSMIT_INT(pub->retransmit)); + /* Delay the publication for longer time when the publication is triggered manually (section + * 3.7.3.1): + * + * When the publication of a message is the result of a power-up, a state transition + * progress update, or completion of a state transition, multiple nodes may be reporting the + * state change at the same time. To reduce the probability of a message collision, these + * messages should be sent with a random delay between 20 and 500 milliseconds. + */ + if (!!pub->delayable && !pub_delay_schedule(pub, RANDOM_DELAY_LONG)) { + return 0; + } + k_work_reschedule(&pub->timer, K_NO_WAIT); return 0; @@ -1661,7 +1744,8 @@ static int mod_rel_register(const struct bt_mesh_model *base, return 0; } } - LOG_ERR("Failed to extend"); + + LOG_ERR("CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE is too small"); return -ENOMEM; } @@ -1701,8 +1785,11 @@ int bt_mesh_model_extend(const struct bt_mesh_model *extending_mod, } register_extension: - if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + if (MOD_REL_LIST_SIZE > 0) { return mod_rel_register(base_mod, extending_mod, RELATION_TYPE_EXT); + } else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + LOG_ERR("CONFIG_BT_MESH_MODEL_EXTENSION_LIST_SIZE is too small"); + return -ENOMEM; } return 0; @@ -1714,7 +1801,7 @@ int bt_mesh_model_correspond(const struct bt_mesh_model *corresponding_mod, int i, err; uint8_t cor_id = 0; - if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) { + if (MOD_REL_LIST_SIZE == 0) { return -ENOTSUP; } @@ -2297,7 +2384,6 @@ size_t bt_mesh_comp_page_size(uint8_t page) 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); int err; @@ -2327,7 +2413,7 @@ int bt_mesh_comp_store(void) LOG_DBG("Stored CDP%d", comp_data_pages[i].page); } -#endif + return 0; } @@ -2561,8 +2647,21 @@ static void commit_mod(const struct bt_mesh_model *mod, const struct bt_mesh_ele int32_t ms = bt_mesh_model_pub_period_get(mod); if (ms > 0) { - LOG_DBG("Starting publish timer (period %u ms)", ms); - k_work_schedule(&mod->pub->timer, K_MSEC(ms)); + /* Delay the first publication after power-up for longer time (section + * 3.7.3.1): + * + * When the publication of a message is the result of a power-up, a state + * transition progress update, or completion of a state transition, multiple + * nodes may be reporting the state change at the same time. To reduce the + * probability of a message collision, these messages should be sent with a + * random delay between 20 and 500 milliseconds. + */ + uint16_t random; + + random = !!mod->pub->delayable ? pub_delay_get(RANDOM_DELAY_LONG) : 0; + + LOG_DBG("Starting publish timer (period %u ms, delay %u ms)", ms, random); + k_work_schedule(&mod->pub->timer, K_MSEC(ms + random)); } } @@ -2614,3 +2713,24 @@ uint8_t bt_mesh_comp_parse_page(struct net_buf_simple *buf) return page; } + +void bt_mesh_access_init(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_init(); +#endif +} + +void bt_mesh_access_suspend(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_stop(); +#endif +} + +void bt_mesh_access_reset(void) +{ +#if defined CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG + bt_mesh_delayable_msg_stop(); +#endif +} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index b7ce1abd0ea..210fceee319 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -94,10 +94,27 @@ void bt_mesh_msg_cb_set(void (*cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, * Send a mesh model layer message out into the mesh network without having instantiated * the relevant mesh models. * - * @param ctx The Bluetooth mesh message context. + * @param ctx The Bluetooth Mesh message context. * @param buf The message payload. + * @param src_addr The source address of model + * @param cb Callback function. + * @param cb_data Callback data. * * @return 0 on success or negative error code on failure. */ int bt_mesh_access_send(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, uint16_t src_addr, const struct bt_mesh_send_cb *cb, void *cb_data); + +/** @brief Initialize the Access layer. + * + * Initialize the delayable message mechanism if it has been enabled. + */ +void bt_mesh_access_init(void); + +/** @brief Suspend the Access layer. + */ +void bt_mesh_access_suspend(void); + +/** @brief Reset the Access layer. + */ +void bt_mesh_access_reset(void); diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index 548e7f3fe15..d9b191120d1 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -17,7 +17,6 @@ #include "common/bt_str.h" -#include "adv.h" #include "net.h" #include "foundation.h" #include "beacon.h" @@ -47,124 +46,142 @@ static K_FIFO_DEFINE(bt_mesh_adv_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) +K_MEM_SLAB_DEFINE_STATIC(local_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_ADV_BUF_COUNT, __alignof__(struct bt_mesh_adv)); + +#if defined(CONFIG_BT_MESH_RELAY_BUF_COUNT) +K_MEM_SLAB_DEFINE_STATIC(relay_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_RELAY_BUF_COUNT, __alignof__(struct bt_mesh_adv)); +#endif + +#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) +K_MEM_SLAB_DEFINE_STATIC(friend_adv_pool, sizeof(struct bt_mesh_adv), + CONFIG_BT_MESH_FRIEND_LPN_COUNT, __alignof__(struct bt_mesh_adv)); +#endif + +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv_ctx *ctx) { - if (!adv->started) { - adv->started = 1; + if (!ctx->started) { + ctx->started = 1; - if (adv->cb && adv->cb->start) { - adv->cb->start(duration, err, adv->cb_data); + if (ctx->cb && ctx->cb->start) { + ctx->cb->start(duration, err, ctx->cb_data); } if (err) { - adv->cb = NULL; + ctx->cb = NULL; } else if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { - bt_mesh_stat_succeeded_count(adv); + bt_mesh_stat_succeeded_count(ctx); } } } -static void bt_mesh_adv_send_end(int err, struct bt_mesh_adv const *adv) +void bt_mesh_adv_send_end(int err, struct bt_mesh_adv_ctx const *ctx) { - if (adv->started && adv->cb && adv->cb->end) { - adv->cb->end(err, adv->cb_data); + if (ctx->started && ctx->cb && ctx->cb->end) { + ctx->cb->end(err, ctx->cb_data); } } -static void adv_buf_destroy(struct net_buf *buf) +static struct bt_mesh_adv *adv_create_from_pool(struct k_mem_slab *buf_pool, + enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout) { - struct bt_mesh_adv adv = *BT_MESH_ADV(buf); + struct bt_mesh_adv_ctx *ctx; + struct bt_mesh_adv *adv; + int err; - net_buf_destroy(buf); + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + LOG_WRN("Refusing to allocate buffer while suspended"); + return NULL; + } - bt_mesh_adv_send_end(0, &adv); -} + err = k_mem_slab_alloc(buf_pool, (void **)&adv, timeout); + if (err) { + return NULL; + } -NET_BUF_POOL_DEFINE(adv_buf_pool, CONFIG_BT_MESH_ADV_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + adv->__ref = 1; -static struct bt_mesh_adv adv_local_pool[CONFIG_BT_MESH_ADV_BUF_COUNT]; + net_buf_simple_init_with_data(&adv->b, adv->__bufs, BT_MESH_ADV_DATA_SIZE); + net_buf_simple_reset(&adv->b); -#if defined(CONFIG_BT_MESH_RELAY) -NET_BUF_POOL_DEFINE(relay_buf_pool, CONFIG_BT_MESH_RELAY_BUF_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + ctx = &adv->ctx; -static struct bt_mesh_adv adv_relay_pool[CONFIG_BT_MESH_RELAY_BUF_COUNT]; -#endif + (void)memset(ctx, 0, sizeof(*ctx)); -#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) -NET_BUF_POOL_DEFINE(friend_buf_pool, CONFIG_BT_MESH_FRIEND_LPN_COUNT, - BT_MESH_ADV_DATA_SIZE, BT_MESH_ADV_USER_DATA_SIZE, - adv_buf_destroy); + ctx->type = type; + ctx->tag = tag; + ctx->xmit = xmit; -static struct bt_mesh_adv adv_friend_pool[CONFIG_BT_MESH_FRIEND_LPN_COUNT]; -#endif + return adv; +} -static struct net_buf *bt_mesh_adv_create_from_pool(struct net_buf_pool *buf_pool, - struct bt_mesh_adv *adv_pool, - enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_ref(struct bt_mesh_adv *adv) { - struct bt_mesh_adv *adv; - struct net_buf *buf; + __ASSERT_NO_MSG(adv->__ref < UINT8_MAX); - if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { - LOG_WRN("Refusing to allocate buffer while suspended"); - return NULL; - } + adv->__ref++; - buf = net_buf_alloc(buf_pool, timeout); - if (!buf) { - return NULL; + return adv; +} + +void bt_mesh_adv_unref(struct bt_mesh_adv *adv) +{ + __ASSERT_NO_MSG(adv->__ref > 0); + + if (--adv->__ref > 0) { + return; } - adv = &adv_pool[net_buf_id(buf)]; - BT_MESH_ADV(buf) = adv; + struct k_mem_slab *slab = &local_adv_pool; - (void)memset(adv, 0, sizeof(*adv)); +#if defined(CONFIG_BT_MESH_RELAY) + if (adv->ctx.tag == BT_MESH_ADV_TAG_RELAY) { + slab = &relay_adv_pool; + } +#endif - adv->type = type; - adv->tag = tag; - adv->xmit = xmit; +#if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) + if (adv->ctx.tag == BT_MESH_ADV_TAG_FRIEND) { + slab = &friend_adv_pool; + } +#endif - return buf; + k_mem_slab_free(slab, (void *)adv); } -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_create(enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout) { #if defined(CONFIG_BT_MESH_RELAY) if (tag == BT_MESH_ADV_TAG_RELAY) { - return bt_mesh_adv_create_from_pool(&relay_buf_pool, - adv_relay_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&relay_adv_pool, + type, tag, xmit, timeout); } #endif #if defined(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) if (tag == BT_MESH_ADV_TAG_FRIEND) { - return bt_mesh_adv_create_from_pool(&friend_buf_pool, - adv_friend_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&friend_adv_pool, + type, tag, xmit, timeout); } #endif - return bt_mesh_adv_create_from_pool(&adv_buf_pool, adv_local_pool, type, - tag, xmit, timeout); + return adv_create_from_pool(&local_adv_pool, type, + tag, xmit, timeout); } -static struct net_buf *process_events(struct k_poll_event *ev, int count) +static struct bt_mesh_adv *process_events(struct k_poll_event *ev, int count) { for (; count; ev++, count--) { LOG_DBG("ev->state %u", ev->state); switch (ev->state) { case K_POLL_STATE_FIFO_DATA_AVAILABLE: - return net_buf_get(ev->fifo, K_NO_WAIT); + return k_fifo_get(ev->fifo, K_NO_WAIT); case K_POLL_STATE_NOT_READY: case K_POLL_STATE_CANCELLED: break; @@ -177,7 +194,7 @@ static struct net_buf *process_events(struct k_poll_event *ev, int count) return NULL; } -struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout) +struct bt_mesh_adv *bt_mesh_adv_get(k_timeout_t timeout) { int err; struct k_poll_event events[] = { @@ -204,22 +221,22 @@ 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 bt_mesh_adv *bt_mesh_adv_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_BIT_FRIEND) { - return net_buf_get(&bt_mesh_friend_queue, timeout); + return k_fifo_get(&bt_mesh_friend_queue, timeout); } if (IS_ENABLED(CONFIG_BT_MESH_RELAY) && !(tags & BT_MESH_ADV_TAG_BIT_LOCAL)) { - return net_buf_get(&bt_mesh_relay_queue, timeout); + return k_fifo_get(&bt_mesh_relay_queue, timeout); } - return bt_mesh_adv_buf_get(timeout); + return bt_mesh_adv_get(timeout); } -void bt_mesh_adv_buf_get_cancel(void) +void bt_mesh_adv_get_cancel(void) { LOG_DBG(""); @@ -234,38 +251,42 @@ void bt_mesh_adv_buf_get_cancel(void) } } -void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, +void bt_mesh_adv_send(struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data) { - LOG_DBG("type 0x%02x len %u: %s", BT_MESH_ADV(buf)->type, buf->len, - bt_hex(buf->data, buf->len)); + LOG_DBG("type 0x%02x len %u: %s", adv->ctx.type, adv->b.len, + bt_hex(adv->b.data, adv->b.len)); + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + LOG_WRN("Sending advertisement while suspended"); + } - BT_MESH_ADV(buf)->cb = cb; - BT_MESH_ADV(buf)->cb_data = cb_data; - BT_MESH_ADV(buf)->busy = 1U; + adv->ctx.cb = cb; + adv->ctx.cb_data = cb_data; + adv->ctx.busy = 1U; if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { - bt_mesh_stat_planned_count(BT_MESH_ADV(buf)); + bt_mesh_stat_planned_count(&adv->ctx); } if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && - 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(); + adv->ctx.tag == BT_MESH_ADV_TAG_FRIEND) { + k_fifo_put(&bt_mesh_friend_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_friend_ready(); return; } if ((IS_ENABLED(CONFIG_BT_MESH_RELAY) && - BT_MESH_ADV(buf)->tag == BT_MESH_ADV_TAG_RELAY) || + adv->ctx.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(); + adv->ctx.tag == BT_MESH_ADV_TAG_PROV)) { + k_fifo_put(&bt_mesh_relay_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_relay_ready(); return; } - net_buf_put(&bt_mesh_adv_queue, net_buf_ref(buf)); - bt_mesh_adv_buf_local_ready(); + k_fifo_put(&bt_mesh_adv_queue, bt_mesh_adv_ref(adv)); + bt_mesh_adv_local_ready(); } int bt_mesh_adv_gatt_send(void) diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index a80ff7e8d4b..6595badc9f9 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -4,14 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ + /* Maximum advertising data payload for a single data type */ #define BT_MESH_ADV_DATA_SIZE 29 -/* The user data is a pointer (4 bytes) to struct bt_mesh_adv */ -#define BT_MESH_ADV_USER_DATA_SIZE 4 - -#define BT_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) - #define BT_MESH_ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) #define BT_MESH_SCAN_INTERVAL_MS 30 #define BT_MESH_SCAN_WINDOW_MS 30 @@ -41,7 +39,7 @@ enum bt_mesh_adv_tag_bit { BT_MESH_ADV_TAG_BIT_PROV = BIT(BT_MESH_ADV_TAG_PROV), }; -struct bt_mesh_adv { +struct bt_mesh_adv_ctx { const struct bt_mesh_send_cb *cb; void *cb_data; @@ -53,24 +51,40 @@ struct bt_mesh_adv { uint8_t xmit; }; +struct bt_mesh_adv { + sys_snode_t node; + + struct bt_mesh_adv_ctx ctx; + + struct net_buf_simple b; + + uint8_t __ref; + + uint8_t __bufs[BT_MESH_ADV_DATA_SIZE]; +}; + /* Lookup table for Advertising data types for bt_mesh_adv_type: */ extern const uint8_t bt_mesh_adv_type[BT_MESH_ADV_TYPES]; +struct bt_mesh_adv *bt_mesh_adv_ref(struct bt_mesh_adv *adv); +void bt_mesh_adv_unref(struct bt_mesh_adv *adv); + /* xmit_count: Number of retransmissions, i.e. 0 == 1 transmission */ -struct net_buf *bt_mesh_adv_create(enum bt_mesh_adv_type type, - enum bt_mesh_adv_tag tag, - uint8_t xmit, k_timeout_t timeout); +struct bt_mesh_adv *bt_mesh_adv_create(enum bt_mesh_adv_type type, + enum bt_mesh_adv_tag tag, + uint8_t xmit, k_timeout_t timeout); -void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, +void bt_mesh_adv_send(struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data); +void bt_mesh_adv_send_end(int err, struct bt_mesh_adv_ctx const *ctx); -struct net_buf *bt_mesh_adv_buf_get(k_timeout_t timeout); +struct bt_mesh_adv *bt_mesh_adv_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 bt_mesh_adv *bt_mesh_adv_get_by_tag(enum bt_mesh_adv_tag_bit tags, k_timeout_t timeout); void bt_mesh_adv_gatt_update(void); -void bt_mesh_adv_buf_get_cancel(void); +void bt_mesh_adv_get_cancel(void); void bt_mesh_adv_init(void); @@ -80,13 +94,16 @@ int bt_mesh_scan_disable(void); int bt_mesh_adv_enable(void); -void bt_mesh_adv_buf_local_ready(void); +/* Should not be called from work queue due to undefined behavior */ +int bt_mesh_adv_disable(void); + +void bt_mesh_adv_local_ready(void); -void bt_mesh_adv_buf_relay_ready(void); +void bt_mesh_adv_relay_ready(void); -void bt_mesh_adv_buf_terminate(const struct net_buf *buf); +int bt_mesh_adv_terminate(struct bt_mesh_adv *adv); -void bt_mesh_adv_buf_friend_ready(void); +void bt_mesh_adv_friend_ready(void); int bt_mesh_adv_gatt_send(void); @@ -94,9 +111,11 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len); -void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv); +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv_ctx *ctx); int bt_mesh_scan_active_set(bool active); int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len); + +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_ADV_H_ */ diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 0bfc2041c7d..2df2cbb4597 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -13,12 +13,14 @@ #include #include #include +#if defined(CONFIG_BT_LL_SOFTDEVICE) +#include +#endif #include "common/bt_str.h" #include "host/hci_core.h" -#include "adv.h" #include "net.h" #include "proxy.h" #include "solicitation.h" @@ -60,14 +62,14 @@ struct bt_mesh_ext_adv { const enum bt_mesh_adv_tag_bit tags; ATOMIC_DEFINE(flags, ADV_FLAGS_NUM); struct bt_le_ext_adv *instance; - struct net_buf *buf; - uint64_t timestamp; - struct k_work_delayable work; + struct bt_mesh_adv *adv; + uint32_t timestamp; + struct k_work work; struct bt_le_adv_param adv_param; }; static void send_pending_adv(struct k_work *work); -static bool schedule_send(struct bt_mesh_ext_adv *adv); +static bool schedule_send(struct bt_mesh_ext_adv *ext_adv); static struct bt_mesh_ext_adv advs[] = { [0] = { @@ -86,7 +88,7 @@ static struct bt_mesh_ext_adv advs[] = { #endif /* CONFIG_BT_MESH_PB_ADV */ BT_MESH_ADV_TAG_BIT_LOCAL ), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #if CONFIG_BT_MESH_RELAY_ADV_SETS [1 ... CONFIG_BT_MESH_RELAY_ADV_SETS] = { @@ -98,19 +100,19 @@ static struct bt_mesh_ext_adv advs[] = { BT_MESH_ADV_TAG_BIT_PROV | #endif /* CONFIG_BT_MESH_PB_ADV_USE_RELAY_SETS */ 0), - .work = Z_WORK_DELAYABLE_INITIALIZER(send_pending_adv), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #endif /* CONFIG_BT_MESH_RELAY_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), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #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), + .work = Z_WORK_INITIALIZER(send_pending_adv), }, #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ }; @@ -136,7 +138,29 @@ static inline struct bt_mesh_ext_adv *gatt_adv_get(void) } } -static int adv_start(struct bt_mesh_ext_adv *adv, +static int set_adv_randomness(uint8_t handle, int rand_us) +{ +#if defined(CONFIG_BT_LL_SOFTDEVICE) + struct net_buf *buf; + sdc_hci_cmd_vs_set_adv_randomness_t *cmd_params; + + buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, sizeof(*cmd_params)); + if (!buf) { + LOG_ERR("Could not allocate command buffer"); + return -ENOMEM; + } + + cmd_params = net_buf_add(buf, sizeof(*cmd_params)); + cmd_params->adv_handle = handle; + cmd_params->rand_us = rand_us; + + return bt_hci_cmd_send_sync(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, buf, NULL); +#else + return 0; +#endif /* defined(CONFIG_BT_LL_SOFTDEVICE) */ +} + +static int adv_start(struct bt_mesh_ext_adv *ext_adv, const struct bt_le_adv_param *param, struct bt_le_ext_adv_start_param *start, const struct bt_data *ad, size_t ad_len, @@ -144,47 +168,47 @@ static int adv_start(struct bt_mesh_ext_adv *adv, { int err; - if (!adv->instance) { + if (!ext_adv->instance) { LOG_ERR("Mesh advertiser not enabled"); return -ENODEV; } - if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_ACTIVE)) { + if (atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { LOG_ERR("Advertiser is busy"); return -EBUSY; } - if (atomic_test_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS)) { - err = bt_le_ext_adv_update_param(adv->instance, param); + if (atomic_test_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS)) { + err = bt_le_ext_adv_update_param(ext_adv->instance, param); if (err) { LOG_ERR("Failed updating adv params: %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); return err; } - atomic_set_bit_to(adv->flags, ADV_FLAG_UPDATE_PARAMS, - param != &adv->adv_param); + atomic_set_bit_to(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS, + param != &ext_adv->adv_param); } - err = bt_le_ext_adv_set_data(adv->instance, ad, ad_len, sd, sd_len); + err = bt_le_ext_adv_set_data(ext_adv->instance, ad, ad_len, sd, sd_len); if (err) { LOG_ERR("Failed setting adv data: %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); return err; } - adv->timestamp = k_uptime_get(); + ext_adv->timestamp = k_uptime_get_32(); - err = bt_le_ext_adv_start(adv->instance, start); + err = bt_le_ext_adv_start(ext_adv->instance, start); if (err) { LOG_ERR("Advertising failed: err %d", err); - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); } return err; } -static int bt_data_send(struct bt_mesh_ext_adv *adv, uint8_t num_events, uint16_t adv_interval, +static int bt_data_send(struct bt_mesh_ext_adv *ext_adv, uint8_t num_events, uint16_t adv_interval, const struct bt_data *ad, size_t ad_len) { struct bt_le_ext_adv_start_param start = { @@ -194,41 +218,41 @@ static int bt_data_send(struct bt_mesh_ext_adv *adv, uint8_t num_events, uint16_ adv_interval = MAX(ADV_INT_FAST_MS, adv_interval); /* Only update advertising parameters if they're different */ - if (adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_interval)) { - adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_interval); - adv->adv_param.interval_max = adv->adv_param.interval_min; - atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS); + if (ext_adv->adv_param.interval_min != BT_MESH_ADV_SCAN_UNIT(adv_interval)) { + ext_adv->adv_param.interval_min = BT_MESH_ADV_SCAN_UNIT(adv_interval); + ext_adv->adv_param.interval_max = ext_adv->adv_param.interval_min; + atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS); } - return adv_start(adv, &adv->adv_param, &start, ad, ad_len, NULL, 0); + return adv_start(ext_adv, &ext_adv->adv_param, &start, ad, ad_len, NULL, 0); } -static int buf_send(struct bt_mesh_ext_adv *adv, struct net_buf *buf) +static int adv_send(struct bt_mesh_ext_adv *ext_adv, struct bt_mesh_adv *adv) { - uint8_t num_events = BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1; + uint8_t num_events = BT_MESH_TRANSMIT_COUNT(adv->ctx.xmit) + 1; uint16_t duration, adv_int; struct bt_data ad; int err; - adv_int = BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit); + adv_int = BT_MESH_TRANSMIT_INT(adv->ctx.xmit); /* Upper boundary estimate: */ duration = num_events * (adv_int + 10); - LOG_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); + LOG_DBG("type %u len %u: %s", adv->ctx.type, + adv->b.len, bt_hex(adv->b.data, adv->b.len)); LOG_DBG("count %u interval %ums duration %ums", num_events, adv_int, duration); - ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->len; - ad.data = buf->data; + ad.type = bt_mesh_adv_type[adv->ctx.type]; + ad.data_len = adv->b.len; + ad.data = adv->b.data; - err = bt_data_send(adv, num_events, adv_int, &ad, 1); + err = bt_data_send(ext_adv, num_events, adv_int, &ad, 1); if (!err) { - adv->buf = net_buf_ref(buf); + ext_adv->adv = bt_mesh_adv_ref(adv); } - bt_mesh_adv_send_start(duration, err, BT_MESH_ADV(buf)); + bt_mesh_adv_send_start(duration, err, &adv->ctx); return err; } @@ -243,112 +267,95 @@ static const char * const adv_tag_to_str[] = { static void send_pending_adv(struct k_work *work) { - struct bt_mesh_ext_adv *adv; - struct net_buf *buf; + struct bt_mesh_ext_adv *ext_adv; + struct bt_mesh_adv *adv; int err; - adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work.work); + ext_adv = CONTAINER_OF(work, struct bt_mesh_ext_adv, work); - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SENT)) { - /* Calling k_uptime_delta on a timestamp moves it to the current time. - * This is essential here, as schedule_send() uses the end of the event - * as a reference to avoid sending the next advertisement too soon. - */ - int64_t duration = k_uptime_delta(&adv->timestamp); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SENT)) { + LOG_DBG("Advertising stopped after %u ms for %s", + k_uptime_get_32() - ext_adv->timestamp, + ext_adv->adv ? adv_tag_to_str[ext_adv->adv->ctx.tag] + : adv_tag_to_str[BT_MESH_ADV_TAG_PROXY]); + + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START); - 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]); + if (ext_adv->adv) { + struct bt_mesh_adv_ctx ctx = ext_adv->adv->ctx; - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY); - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY_START); + ext_adv->adv->ctx.started = 0; + bt_mesh_adv_unref(ext_adv->adv); + bt_mesh_adv_send_end(0, &ctx); - if (adv->buf) { - net_buf_unref(adv->buf); - adv->buf = NULL; + ext_adv->adv = NULL; } - (void)schedule_send(adv); + (void)schedule_send(ext_adv); return; } - atomic_clear_bit(adv->flags, ADV_FLAG_SCHEDULED); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULED); - while ((buf = bt_mesh_adv_buf_get_by_tag(adv->tags, K_NO_WAIT))) { + while ((adv = bt_mesh_adv_get_by_tag(ext_adv->tags, K_NO_WAIT))) { /* busy == 0 means this was canceled */ - if (!BT_MESH_ADV(buf)->busy) { - net_buf_unref(buf); + if (!adv->ctx.busy) { + bt_mesh_adv_unref(adv); continue; } - BT_MESH_ADV(buf)->busy = 0U; - err = buf_send(adv, buf); + adv->ctx.busy = 0U; + err = adv_send(ext_adv, adv); - net_buf_unref(buf); + bt_mesh_adv_unref(adv); if (!err) { return; /* Wait for advertising to finish */ } } - if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || - !(adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && + !bt_mesh_sol_send()) { return; } - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && - !bt_mesh_sol_send()) { + if (!IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER) || + !(ext_adv->tags & BT_MESH_ADV_TAG_BIT_PROXY)) { return; } - atomic_set_bit(adv->flags, ADV_FLAG_PROXY_START); + atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY_START); if (!bt_mesh_adv_gatt_send()) { - atomic_set_bit(adv->flags, ADV_FLAG_PROXY); + atomic_set_bit(ext_adv->flags, ADV_FLAG_PROXY); } - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING)) { - schedule_send(adv); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING)) { + schedule_send(ext_adv); } } -static bool schedule_send(struct bt_mesh_ext_adv *adv) +static bool schedule_send(struct bt_mesh_ext_adv *ext_adv) { - uint64_t timestamp; - int64_t delta; - - timestamp = adv->timestamp; + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY)) { + atomic_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START); + (void)bt_le_ext_adv_stop(ext_adv->instance); - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY)) { - atomic_clear_bit(adv->flags, ADV_FLAG_PROXY_START); - (void)bt_le_ext_adv_stop(adv->instance); - - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); } - if (atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { - atomic_set_bit(adv->flags, ADV_FLAG_SCHEDULE_PENDING); + if (atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { + atomic_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING); return false; - } else if (atomic_test_and_set_bit(adv->flags, ADV_FLAG_SCHEDULED)) { + } else if (atomic_test_and_set_bit(ext_adv->flags, ADV_FLAG_SCHEDULED)) { return false; } - 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)) { - k_work_reschedule(&adv->work, K_NO_WAIT); - } else { - /* The controller will send the next advertisement immediately. - * Introduce a delay here to avoid sending the next mesh packet closer - * to the previous packet than what's permitted by the specification. - */ - delta = k_uptime_delta(×tamp); - k_work_reschedule(&adv->work, K_MSEC(ADV_INT_FAST_MS - delta)); - } + atomic_clear_bit(ext_adv->flags, ADV_FLAG_SCHEDULE_PENDING); + k_work_submit(&ext_adv->work); return true; } @@ -358,17 +365,17 @@ void bt_mesh_adv_gatt_update(void) (void)schedule_send(gatt_adv_get()); } -void bt_mesh_adv_buf_local_ready(void) +void bt_mesh_adv_local_ready(void) { (void)schedule_send(advs); } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_relay_ready(void) { - struct bt_mesh_ext_adv *adv = relay_adv_get(); + struct bt_mesh_ext_adv *ext_adv = relay_adv_get(); for (int i = 0; i < CONFIG_BT_MESH_RELAY_ADV_SETS; i++) { - if (schedule_send(&adv[i])) { + if (schedule_send(&ext_adv[i])) { return; } } @@ -379,7 +386,7 @@ void bt_mesh_adv_buf_relay_ready(void) } } -void bt_mesh_adv_buf_friend_ready(void) +void bt_mesh_adv_friend_ready(void) { if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE)) { schedule_send(&advs[1 + CONFIG_BT_MESH_RELAY_ADV_SETS]); @@ -388,36 +395,38 @@ void bt_mesh_adv_buf_friend_ready(void) } } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +int bt_mesh_adv_terminate(struct bt_mesh_adv *adv) { int err; for (int i = 0; i < ARRAY_SIZE(advs); i++) { - struct bt_mesh_ext_adv *adv = &advs[i]; + struct bt_mesh_ext_adv *ext_adv = &advs[i]; - if (adv->buf != buf) { + if (ext_adv->adv != adv) { continue; } - if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { - return; + if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { + return 0; } - err = bt_le_ext_adv_stop(adv->instance); + err = bt_le_ext_adv_stop(ext_adv->instance); if (err) { LOG_ERR("Failed to stop adv %d", err); - return; + return err; } /* Do not call `cb:end`, since this user action */ - BT_MESH_ADV(adv->buf)->cb = NULL; + adv->ctx.cb = NULL; - atomic_set_bit(adv->flags, ADV_FLAG_SENT); + atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT); - k_work_submit(&adv->work.work); + k_work_submit(&ext_adv->work); - return; + return 0; } + + return -EINVAL; } void bt_mesh_adv_init(void) @@ -450,31 +459,31 @@ static struct bt_mesh_ext_adv *adv_instance_find(struct bt_le_ext_adv *instance) static void adv_sent(struct bt_le_ext_adv *instance, struct bt_le_ext_adv_sent_info *info) { - struct bt_mesh_ext_adv *adv = adv_instance_find(instance); + struct bt_mesh_ext_adv *ext_adv = adv_instance_find(instance); - if (!adv) { + if (!ext_adv) { LOG_WRN("Unexpected adv instance"); return; } - if (!atomic_test_bit(adv->flags, ADV_FLAG_ACTIVE)) { + if (!atomic_test_bit(ext_adv->flags, ADV_FLAG_ACTIVE)) { return; } - atomic_set_bit(adv->flags, ADV_FLAG_SENT); + atomic_set_bit(ext_adv->flags, ADV_FLAG_SENT); - k_work_submit(&adv->work.work); + k_work_submit(&ext_adv->work); } #if defined(CONFIG_BT_MESH_GATT_SERVER) static void connected(struct bt_le_ext_adv *instance, struct bt_le_ext_adv_connected_info *info) { - struct bt_mesh_ext_adv *adv = gatt_adv_get(); + struct bt_mesh_ext_adv *ext_adv = gatt_adv_get(); - if (atomic_test_and_clear_bit(adv->flags, ADV_FLAG_PROXY_START)) { - atomic_clear_bit(adv->flags, ADV_FLAG_ACTIVE); - (void)schedule_send(adv); + if (atomic_test_and_clear_bit(ext_adv->flags, ADV_FLAG_PROXY_START)) { + atomic_clear_bit(ext_adv->flags, ADV_FLAG_ACTIVE); + (void)schedule_send(ext_adv); } } #endif /* CONFIG_BT_MESH_GATT_SERVER */ @@ -501,6 +510,45 @@ int bt_mesh_adv_enable(void) if (err) { return err; } + + 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); + if (err) { + LOG_ERR("Failed to set zero randomness: %d", err); + } + } + } + + return 0; +} + +int bt_mesh_adv_disable(void) +{ + int err; + struct k_work_sync sync; + + for (int i = 0; i < ARRAY_SIZE(advs); i++) { + k_work_flush(&advs[i].work, &sync); + + err = bt_le_ext_adv_stop(advs[i].instance); + if (err) { + LOG_ERR("Failed to stop adv %d", err); + return err; + } + + /* `adv_sent` is called to finish transmission of an adv buffer that was pushed to + * the host before the advertiser was stopped, but did not finish. + */ + adv_sent(advs[i].instance, NULL); + + err = bt_le_ext_adv_delete(advs[i].instance); + if (err) { + LOG_ERR("Failed to delete adv %d", err); + return err; + } + advs[i].instance = NULL; } return 0; @@ -511,7 +559,7 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) { - struct bt_mesh_ext_adv *adv = gatt_adv_get(); + struct bt_mesh_ext_adv *ext_adv = gatt_adv_get(); struct bt_le_ext_adv_start_param start = { /* Timeout is set in 10 ms steps, with 0 indicating "forever" */ .timeout = (duration == SYS_FOREVER_MS) ? 0 : MAX(1, duration / 10), @@ -519,9 +567,9 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, LOG_DBG("Start advertising %d ms", duration); - atomic_set_bit(adv->flags, ADV_FLAG_UPDATE_PARAMS); + atomic_set_bit(ext_adv->flags, ADV_FLAG_UPDATE_PARAMS); - return adv_start(adv, param, &start, ad, ad_len, sd, sd_len); + return adv_start(ext_adv, param, &start, ad, ad_len, sd, sd_len); } int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_interval, diff --git a/subsys/bluetooth/mesh/adv_legacy.c b/subsys/bluetooth/mesh/adv_legacy.c index a7d7dd1a320..867c91bbf8e 100644 --- a/subsys/bluetooth/mesh/adv_legacy.c +++ b/subsys/bluetooth/mesh/adv_legacy.c @@ -19,7 +19,6 @@ #include "host/hci_core.h" -#include "adv.h" #include "net.h" #include "foundation.h" #include "beacon.h" @@ -39,10 +38,11 @@ LOG_MODULE_REGISTER(bt_mesh_adv_legacy); static struct k_thread adv_thread_data; static K_KERNEL_STACK_DEFINE(adv_thread_stack, CONFIG_BT_MESH_ADV_STACK_SIZE); static int32_t adv_timeout; +static bool enabled; static int bt_data_send(uint8_t num_events, uint16_t adv_int, const struct bt_data *ad, size_t ad_len, - struct bt_mesh_adv *adv) + struct bt_mesh_adv_ctx *ctx) { struct bt_le_adv_param param = {}; uint64_t uptime = k_uptime_get(); @@ -100,8 +100,8 @@ static int bt_data_send(uint8_t num_events, uint16_t adv_int, LOG_DBG("Advertising started. Sleeping %u ms", duration); - if (adv) { - bt_mesh_adv_send_start(duration, err, adv); + if (ctx) { + bt_mesh_adv_send_start(duration, err, ctx); } k_sleep(K_MSEC(duration)); @@ -123,38 +123,37 @@ int bt_mesh_adv_bt_data_send(uint8_t num_events, uint16_t adv_int, return bt_data_send(num_events, adv_int, ad, ad_len, NULL); } -static inline void buf_send(struct net_buf *buf) +static inline void adv_send(struct bt_mesh_adv *adv) { - uint16_t num_events = BT_MESH_TRANSMIT_COUNT(BT_MESH_ADV(buf)->xmit) + 1; + uint16_t num_events = BT_MESH_TRANSMIT_COUNT(adv->ctx.xmit) + 1; uint16_t adv_int; struct bt_data ad; - adv_int = BT_MESH_TRANSMIT_INT(BT_MESH_ADV(buf)->xmit); + adv_int = BT_MESH_TRANSMIT_INT(adv->ctx.xmit); - LOG_DBG("type %u len %u: %s", BT_MESH_ADV(buf)->type, - buf->len, bt_hex(buf->data, buf->len)); + LOG_DBG("type %u len %u: %s", adv->ctx.type, + adv->b.len, bt_hex(adv->b.data, adv->b.len)); - ad.type = bt_mesh_adv_type[BT_MESH_ADV(buf)->type]; - ad.data_len = buf->len; - ad.data = buf->data; + ad.type = bt_mesh_adv_type[adv->ctx.type]; + ad.data_len = adv->b.len; + ad.data = adv->b.data; - bt_data_send(num_events, adv_int, &ad, 1, BT_MESH_ADV(buf)); + bt_data_send(num_events, adv_int, &ad, 1, &adv->ctx); } static void adv_thread(void *p1, void *p2, void *p3) { LOG_DBG("started"); + struct bt_mesh_adv *adv; - while (1) { - struct net_buf *buf; - + while (enabled) { if (IS_ENABLED(CONFIG_BT_MESH_GATT_SERVER)) { - buf = bt_mesh_adv_buf_get(K_NO_WAIT); - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !buf) { + adv = bt_mesh_adv_get(K_NO_WAIT); + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !adv) { (void)bt_mesh_sol_send(); } - while (!buf) { + while (!adv) { /* Adv timeout may be set by a call from proxy * to bt_mesh_adv_gatt_start: @@ -162,52 +161,64 @@ static void adv_thread(void *p1, void *p2, void *p3) adv_timeout = SYS_FOREVER_MS; (void)bt_mesh_adv_gatt_send(); - buf = bt_mesh_adv_buf_get(SYS_TIMEOUT_MS(adv_timeout)); + adv = bt_mesh_adv_get(SYS_TIMEOUT_MS(adv_timeout)); bt_le_adv_stop(); - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !buf) { + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION) && !adv) { (void)bt_mesh_sol_send(); } } } else { - buf = bt_mesh_adv_buf_get(K_FOREVER); + adv = bt_mesh_adv_get(K_FOREVER); } - if (!buf) { + if (!adv) { continue; } /* busy == 0 means this was canceled */ - if (BT_MESH_ADV(buf)->busy) { - BT_MESH_ADV(buf)->busy = 0U; - buf_send(buf); + if (adv->ctx.busy) { + adv->ctx.busy = 0U; + adv_send(adv); } - net_buf_unref(buf); + struct bt_mesh_adv_ctx ctx = adv->ctx; + + adv->ctx.started = 0; + bt_mesh_adv_unref(adv); + bt_mesh_adv_send_end(0, &ctx); /* Give other threads a chance to run */ k_yield(); } + + /* Empty the advertising pool when advertising is disabled */ + while ((adv = bt_mesh_adv_get(K_NO_WAIT))) { + bt_mesh_adv_send_start(0, -ENODEV, &adv->ctx); + bt_mesh_adv_unref(adv); + } } -void bt_mesh_adv_buf_local_ready(void) +void bt_mesh_adv_local_ready(void) { /* Will be handled automatically */ } -void bt_mesh_adv_buf_relay_ready(void) +void bt_mesh_adv_relay_ready(void) { /* Will be handled automatically */ } void bt_mesh_adv_gatt_update(void) { - bt_mesh_adv_buf_get_cancel(); + bt_mesh_adv_get_cancel(); } -void bt_mesh_adv_buf_terminate(const struct net_buf *buf) +int bt_mesh_adv_terminate(struct bt_mesh_adv *adv) { - ARG_UNUSED(buf); + ARG_UNUSED(adv); + + return 0; } void bt_mesh_adv_init(void) @@ -221,10 +232,19 @@ void bt_mesh_adv_init(void) int bt_mesh_adv_enable(void) { + enabled = true; k_thread_start(&adv_thread_data); return 0; } +int bt_mesh_adv_disable(void) +{ + enabled = false; + k_thread_join(&adv_thread_data, K_FOREVER); + LOG_DBG("Advertising disabled"); + return 0; +} + int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration, const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len) diff --git a/subsys/bluetooth/mesh/app_keys.c b/subsys/bluetooth/mesh/app_keys.c index a47d31447c5..5afd887a8e8 100644 --- a/subsys/bluetooth/mesh/app_keys.c +++ b/subsys/bluetooth/mesh/app_keys.c @@ -17,7 +17,6 @@ #include "rpl.h" #include "settings.h" #include "crypto.h" -#include "adv.h" #include "proxy.h" #include "friend.h" #include "foundation.h" diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index afdea5b4c6a..cdd5862330e 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -16,7 +16,6 @@ #include "common/bt_str.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "prov.h" @@ -41,6 +40,8 @@ LOG_MODULE_REGISTER(bt_mesh_beacon); #define PROV_XMIT BT_MESH_TRANSMIT(0, 20) static struct k_work_delayable beacon_timer; +static struct bt_mesh_subnet *beacon_send_sub_curr; + #if defined(CONFIG_BT_MESH_PRIV_BEACONS) static struct { /** @@ -112,13 +113,26 @@ void bt_mesh_beacon_cache_clear(struct bt_mesh_subnet *sub) #endif } +static void beacon_start(uint16_t duration, int err, void *user_data) +{ + if (err) { + LOG_ERR("Failed to send beacon: err %d", err); + if (beacon_send_sub_curr) { + k_work_reschedule(&beacon_timer, K_NO_WAIT); + } + } +} + static void beacon_complete(int err, void *user_data) { struct bt_mesh_beacon *beacon = user_data; LOG_DBG("err %d", err); - beacon->sent = k_uptime_get_32(); + + if (beacon_send_sub_curr) { + k_work_reschedule(&beacon_timer, K_MSEC(20)); + } } static int secure_beacon_create(struct bt_mesh_subnet *sub, @@ -248,15 +262,16 @@ static bool secure_beacon_is_running(void) atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_INITIATOR); } -static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *beacon, - void *cb_data, int (*beacon_create)(struct bt_mesh_subnet *sub, - struct net_buf_simple *buf)) +static int net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *beacon, + int (*beacon_create)(struct bt_mesh_subnet *sub, + struct net_buf_simple *buf)) { static const struct bt_mesh_send_cb send_cb = { + .start = beacon_start, .end = beacon_complete, }; uint32_t now = k_uptime_get_32(); - struct net_buf *buf; + struct bt_mesh_adv *adv; uint32_t time_diff; uint32_t time_since_last_recv; int err; @@ -268,29 +283,29 @@ static bool net_beacon_send(struct bt_mesh_subnet *sub, struct bt_mesh_beacon *b if (time_diff < (600 * MSEC_PER_SEC) && (time_diff < BEACON_THRESHOLD(beacon) || time_since_last_recv < (10 * MSEC_PER_SEC))) { - return false; + return -ENOMSG; } - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); - return true; /* Bail out */ + if (!adv) { + LOG_ERR("Unable to allocate beacon adv"); + return -ENOMEM; /* Bail out */ } - err = beacon_create(sub, &buf->b); + err = beacon_create(sub, &adv->b); if (!err) { - bt_mesh_adv_send(buf, &send_cb, beacon); + bt_mesh_adv_send(adv, &send_cb, beacon); } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); - return err != 0; + return err; } -static bool net_beacon_for_subnet_send(struct bt_mesh_subnet *sub, void *cb_data) +static int net_beacon_for_subnet_send(struct bt_mesh_subnet *sub) { - bool res = true; + int err = -ENOMSG; struct { struct bt_mesh_beacon *beacon; @@ -316,36 +331,36 @@ static bool net_beacon_for_subnet_send(struct bt_mesh_subnet *sub, void *cb_data continue; } - res = net_beacon_send(sub, beacons[i].beacon, cb_data, beacons[i].create_fn); - if (res) { + err = net_beacon_send(sub, beacons[i].beacon, beacons[i].create_fn); + if (err < 0) { /* Bail out */ break; } } - return res; + return err; } static int unprovisioned_beacon_send(void) { const struct bt_mesh_prov *prov; uint8_t uri_hash[16] = { 0 }; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint16_t oob_info; LOG_DBG(""); - buf = bt_mesh_adv_create(BT_MESH_ADV_BEACON, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); + if (!adv) { + LOG_ERR("Unable to allocate beacon adv"); return -ENOBUFS; } prov = bt_mesh_prov_get(); - net_buf_add_u8(buf, BEACON_TYPE_UNPROVISIONED); - net_buf_add_mem(buf, prov->uuid, 16); + net_buf_simple_add_u8(&adv->b, BEACON_TYPE_UNPROVISIONED); + net_buf_simple_add_mem(&adv->b, prov->uuid, 16); if (prov->uri && bt_mesh_s1_str(prov->uri, uri_hash) == 0) { oob_info = prov->oob_info | BT_MESH_PROV_OOB_URI; @@ -353,31 +368,31 @@ static int unprovisioned_beacon_send(void) oob_info = prov->oob_info; } - net_buf_add_be16(buf, oob_info); - net_buf_add_mem(buf, uri_hash, 4); + net_buf_simple_add_be16(&adv->b, oob_info); + net_buf_simple_add_mem(&adv->b, uri_hash, 4); - bt_mesh_adv_send(buf, NULL, NULL); - net_buf_unref(buf); + bt_mesh_adv_send(adv, NULL, NULL); + bt_mesh_adv_unref(adv); if (prov->uri) { size_t len; - buf = bt_mesh_adv_create(BT_MESH_ADV_URI, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); + if (!adv) { + LOG_ERR("Unable to allocate URI adv"); return -ENOBUFS; } len = strlen(prov->uri); - if (net_buf_tailroom(buf) < len) { + if (net_buf_simple_tailroom(&adv->b) < len) { LOG_WRN("Too long URI to fit advertising data"); } else { - net_buf_add_mem(buf, prov->uri, len); - bt_mesh_adv_send(buf, NULL, NULL); + net_buf_simple_add_mem(&adv->b, prov->uri, len); + bt_mesh_adv_send(adv, NULL, NULL); } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } return 0; @@ -450,6 +465,30 @@ static bool net_beacon_is_running(void) (bt_mesh_priv_beacon_get() == BT_MESH_FEATURE_ENABLED); } +static bool beacons_send_next(void) +{ + int err; + struct bt_mesh_subnet *sub_first = bt_mesh_subnet_next(NULL); + struct bt_mesh_subnet *sub_next; + + do { + sub_next = bt_mesh_subnet_next(beacon_send_sub_curr); + if (sub_next == sub_first && beacon_send_sub_curr != NULL) { + beacon_send_sub_curr = NULL; + return false; + } + + beacon_send_sub_curr = sub_next; + err = net_beacon_for_subnet_send(beacon_send_sub_curr); + if (err < 0 && (err != -ENOMSG)) { + LOG_ERR("Failed to advertise subnet %d: err %d", + beacon_send_sub_curr->net_idx, err); + } + } while (err); + + return true; +} + static void beacon_send(struct k_work *work) { LOG_DBG(""); @@ -459,10 +498,14 @@ static void beacon_send(struct k_work *work) return; } - update_beacon_observation(); - (void)bt_mesh_subnet_find(net_beacon_for_subnet_send, NULL); + if (!beacon_send_sub_curr) { + update_beacon_observation(); + } + + if (!beacons_send_next()) { + k_work_schedule(&beacon_timer, PROVISIONED_INTERVAL); + } - k_work_schedule(&beacon_timer, PROVISIONED_INTERVAL); return; } @@ -474,7 +517,6 @@ static void beacon_send(struct k_work *work) k_work_schedule(&beacon_timer, K_SECONDS(CONFIG_BT_MESH_UNPROV_BEACON_INT)); } - } static bool auth_match(struct bt_mesh_subnet_keys *keys, @@ -529,7 +571,6 @@ static bool secure_beacon_authenticate(struct bt_mesh_subnet *sub, void *cb_data return false; } -#if defined(CONFIG_BT_MESH_V1d1) static bool priv_beacon_decrypt(struct bt_mesh_subnet *sub, void *cb_data) { struct beacon_params *params = cb_data; @@ -568,7 +609,6 @@ static bool priv_beacon_decrypt(struct bt_mesh_subnet *sub, void *cb_data) return false; } -#endif static void net_beacon_register(struct bt_mesh_beacon *beacon, bool priv) { @@ -659,7 +699,6 @@ static void secure_beacon_recv(struct net_buf_simple *buf) net_beacon_resolve(¶ms, secure_beacon_authenticate); } -#if defined(CONFIG_BT_MESH_V1d1) static void private_beacon_recv(struct net_buf_simple *buf) { struct beacon_params params; @@ -676,7 +715,6 @@ static void private_beacon_recv(struct net_buf_simple *buf) net_beacon_resolve(¶ms, priv_beacon_decrypt); } -#endif void bt_mesh_beacon_recv(struct net_buf_simple *buf) { @@ -700,9 +738,7 @@ void bt_mesh_beacon_recv(struct net_buf_simple *buf) secure_beacon_recv(buf); break; case BEACON_TYPE_PRIVATE: -#if defined(CONFIG_BT_MESH_V1d1) private_beacon_recv(buf); -#endif break; default: LOG_WRN("Unknown beacon type 0x%02x", type); @@ -764,6 +800,7 @@ void bt_mesh_beacon_ivu_initiator(bool enable) * still have to implement an early exit mechanism, so we might as well * just use this every time. */ + beacon_send_sub_curr = NULL; k_work_schedule(&beacon_timer, K_NO_WAIT); } @@ -786,11 +823,13 @@ void bt_mesh_beacon_enable(void) bt_mesh_subnet_foreach(subnet_beacon_enable); } + beacon_send_sub_curr = NULL; k_work_reschedule(&beacon_timer, K_NO_WAIT); } void bt_mesh_beacon_disable(void) { /* If this fails, we'll do an early exit in the work handler. */ + beacon_send_sub_curr = NULL; (void)k_work_cancel_delayable(&beacon_timer); } diff --git a/subsys/bluetooth/mesh/cfg.c b/subsys/bluetooth/mesh/cfg.c index c7bea0d29b0..4fef60d5c8d 100644 --- a/subsys/bluetooth/mesh/cfg.c +++ b/subsys/bluetooth/mesh/cfg.c @@ -14,7 +14,6 @@ #include "settings.h" #include "heartbeat.h" #include "friend.h" -#include "adv.h" #include "cfg.h" #include "od_priv_proxy.h" #include "priv_beacon.h" diff --git a/subsys/bluetooth/mesh/cfg_srv.c b/subsys/bluetooth/mesh/cfg_srv.c index fa6bb48703a..268f883d8b8 100644 --- a/subsys/bluetooth/mesh/cfg_srv.c +++ b/subsys/bluetooth/mesh/cfg_srv.c @@ -21,7 +21,6 @@ #include "host/testing.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "lpn.h" diff --git a/subsys/bluetooth/mesh/delayable_msg.c b/subsys/bluetooth/mesh/delayable_msg.c new file mode 100644 index 00000000000..a1a247bb9c9 --- /dev/null +++ b/subsys/bluetooth/mesh/delayable_msg.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include +#include + +#include "msg.h" +#include "access.h" +#include "net.h" + +#define LOG_LEVEL CONFIG_BT_MESH_ACCESS_LOG_LEVEL +#include +LOG_MODULE_REGISTER(bt_mesh_delayable_msg); + +static void delayable_msg_handler(struct k_work *w); +static bool push_msg_from_delayable_msgs(void); + +static struct delayable_msg_chunk { + sys_snode_t node; + uint8_t data[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE]; +} delayable_msg_chunks[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT]; + +static struct delayable_msg_ctx { + sys_snode_t node; + sys_slist_t chunks; + struct bt_mesh_msg_ctx ctx; + uint16_t src_addr; + const struct bt_mesh_send_cb *cb; + void *cb_data; + uint32_t fired_time; + uint16_t len; +} delayable_msgs_ctx[CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT]; + +static struct { + sys_slist_t busy_ctx; + sys_slist_t free_ctx; + sys_slist_t free_chunks; + struct k_work_delayable random_delay; +} access_delayable_msg = {.random_delay = Z_WORK_DELAYABLE_INITIALIZER(delayable_msg_handler)}; + +static void put_ctx_to_busy_list(struct delayable_msg_ctx *ctx) +{ + struct delayable_msg_ctx *curr_ctx; + sys_slist_t *list = &access_delayable_msg.busy_ctx; + sys_snode_t *head = sys_slist_peek_head(list); + sys_snode_t *curr = head; + sys_snode_t *prev = curr; + + if (!head) { + sys_slist_append(list, &ctx->node); + return; + } + + do { + curr_ctx = CONTAINER_OF(curr, struct delayable_msg_ctx, node); + if (ctx->fired_time < curr_ctx->fired_time) { + if (curr == head) { + sys_slist_prepend(list, &ctx->node); + } else { + sys_slist_insert(list, prev, &ctx->node); + } + return; + } + prev = curr; + } while ((curr = sys_slist_peek_next(curr))); + + sys_slist_append(list, &ctx->node); +} + +static struct delayable_msg_ctx *peek_pending_msg(void) +{ + struct delayable_msg_ctx *pending_msg = NULL; + sys_snode_t *node = sys_slist_peek_head(&access_delayable_msg.busy_ctx); + + if (node) { + pending_msg = CONTAINER_OF(node, struct delayable_msg_ctx, node); + } + + return pending_msg; +} + +static void reschedule_delayable_msg(struct delayable_msg_ctx *msg) +{ + uint32_t curr_time; + k_timeout_t delay = K_NO_WAIT; + struct delayable_msg_ctx *pending_msg; + + if (msg) { + put_ctx_to_busy_list(msg); + } + + pending_msg = peek_pending_msg(); + + if (!pending_msg) { + return; + } + + curr_time = k_uptime_get_32(); + if (curr_time < pending_msg->fired_time) { + delay = K_MSEC(pending_msg->fired_time - curr_time); + } + + k_work_reschedule(&access_delayable_msg.random_delay, delay); +} + +static int allocate_delayable_msg_chunks(struct delayable_msg_ctx *msg, int number) +{ + sys_snode_t *node; + + for (int i = 0; i < number; i++) { + node = sys_slist_get(&access_delayable_msg.free_chunks); + if (!node) { + LOG_WRN("Unable allocate %u chunks, allocated %u", number, i); + return i; + } + sys_slist_append(&msg->chunks, node); + } + + return number; +} + +static void release_delayable_msg_chunks(struct delayable_msg_ctx *msg) +{ + sys_snode_t *node; + + while ((node = sys_slist_get(&msg->chunks))) { + sys_slist_append(&access_delayable_msg.free_chunks, node); + } +} + +static struct delayable_msg_ctx *allocate_delayable_msg_ctx(void) +{ + struct delayable_msg_ctx *msg; + sys_snode_t *node; + + if (sys_slist_is_empty(&access_delayable_msg.free_ctx)) { + LOG_WRN("Purge pending delayable message."); + if (!push_msg_from_delayable_msgs()) { + return NULL; + } + } + + node = sys_slist_get(&access_delayable_msg.free_ctx); + msg = CONTAINER_OF(node, struct delayable_msg_ctx, node); + sys_slist_init(&msg->chunks); + + return msg; +} + +static void release_delayable_msg_ctx(struct delayable_msg_ctx *ctx) +{ + if (sys_slist_find_and_remove(&access_delayable_msg.busy_ctx, &ctx->node)) { + sys_slist_append(&access_delayable_msg.free_ctx, &ctx->node); + } +} + +static bool push_msg_from_delayable_msgs(void) +{ + sys_snode_t *node; + struct delayable_msg_chunk *chunk; + struct delayable_msg_ctx *msg = peek_pending_msg(); + uint16_t len; + int err; + + if (!msg) { + return false; + } + + len = msg->len; + + NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_TX_SDU_MAX); + + SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) { + uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, len); + + chunk = CONTAINER_OF(node, struct delayable_msg_chunk, node); + memcpy(net_buf_simple_add(&buf, tmp), chunk->data, tmp); + len -= tmp; + } + + msg->ctx.rnd_delay = false; + err = bt_mesh_access_send(&msg->ctx, &buf, msg->src_addr, msg->cb, msg->cb_data); + msg->ctx.rnd_delay = true; + + if (err == -EBUSY || err == -ENOBUFS) { + return false; + } + + release_delayable_msg_chunks(msg); + release_delayable_msg_ctx(msg); + + if (err && msg->cb && msg->cb->start) { + msg->cb->start(0, err, msg->cb_data); + } + + return true; +} + +static void delayable_msg_handler(struct k_work *w) +{ + if (!push_msg_from_delayable_msgs()) { + sys_snode_t *node = sys_slist_get(&access_delayable_msg.busy_ctx); + struct delayable_msg_ctx *pending_msg = + CONTAINER_OF(node, struct delayable_msg_ctx, node); + + pending_msg->fired_time += 10; + reschedule_delayable_msg(pending_msg); + } else { + reschedule_delayable_msg(NULL); + } +} + +int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, + uint16_t src_addr, const struct bt_mesh_send_cb *cb, void *cb_data) +{ + sys_snode_t *node; + struct delayable_msg_ctx *msg; + uint16_t random_delay; + int total_number = DIV_ROUND_UP(buf->size, CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE); + int allocated_number = 0; + uint16_t len = buf->len; + + if (atomic_test_bit(bt_mesh.flags, BT_MESH_SUSPENDED)) { + LOG_WRN("Refusing to allocate message context while suspended"); + return -ENODEV; + } + + if (total_number > CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT) { + return -EINVAL; + } + + msg = allocate_delayable_msg_ctx(); + if (!msg) { + LOG_WRN("No available free delayable message context."); + return -ENOMEM; + } + + do { + allocated_number += + allocate_delayable_msg_chunks(msg, total_number - allocated_number); + + if (total_number > allocated_number) { + LOG_DBG("Unable allocate %u chunks, allocated %u", total_number, + allocated_number); + if (!push_msg_from_delayable_msgs()) { + LOG_WRN("No available chunk memory."); + release_delayable_msg_chunks(msg); + release_delayable_msg_ctx(msg); + return -ENOMEM; + } + } + } while (total_number > allocated_number); + + SYS_SLIST_FOR_EACH_NODE(&msg->chunks, node) { + uint16_t tmp = MIN(CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_SIZE, buf->len); + + struct delayable_msg_chunk *chunk = + CONTAINER_OF(node, struct delayable_msg_chunk, node); + + memcpy(chunk->data, net_buf_simple_pull_mem(buf, tmp), tmp); + } + + bt_rand(&random_delay, sizeof(uint16_t)); + random_delay = 20 + random_delay % (BT_MESH_ADDR_IS_UNICAST(ctx->recv_dst) ? 30 : 480); + msg->fired_time = k_uptime_get_32() + random_delay; + msg->ctx = *ctx; + msg->src_addr = src_addr; + msg->cb = cb; + msg->cb_data = cb_data; + msg->len = len; + + reschedule_delayable_msg(msg); + + return 0; +} + +void bt_mesh_delayable_msg_init(void) +{ + sys_slist_init(&access_delayable_msg.busy_ctx); + sys_slist_init(&access_delayable_msg.free_ctx); + sys_slist_init(&access_delayable_msg.free_chunks); + + for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_COUNT; i++) { + sys_slist_append(&access_delayable_msg.free_ctx, &delayable_msgs_ctx[i].node); + } + + for (int i = 0; i < CONFIG_BT_MESH_ACCESS_DELAYABLE_MSG_CHUNK_COUNT; i++) { + sys_slist_append(&access_delayable_msg.free_chunks, &delayable_msg_chunks[i].node); + } +} + +void bt_mesh_delayable_msg_stop(void) +{ + sys_snode_t *node; + struct delayable_msg_ctx *ctx; + + k_work_cancel_delayable(&access_delayable_msg.random_delay); + + while ((node = sys_slist_peek_head(&access_delayable_msg.busy_ctx))) { + ctx = CONTAINER_OF(node, struct delayable_msg_ctx, node); + release_delayable_msg_chunks(ctx); + release_delayable_msg_ctx(ctx); + + if (ctx->cb && ctx->cb->start) { + ctx->cb->start(0, -ENODEV, ctx->cb_data); + } + } +} diff --git a/subsys/bluetooth/mesh/delayable_msg.h b/subsys/bluetooth/mesh/delayable_msg.h new file mode 100644 index 00000000000..1ab5dde2e76 --- /dev/null +++ b/subsys/bluetooth/mesh/delayable_msg.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ +#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ + +int bt_mesh_delayable_msg_manage(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, + uint16_t src_addr, const struct bt_mesh_send_cb *cb, + void *cb_data); +void bt_mesh_delayable_msg_init(void); +void bt_mesh_delayable_msg_stop(void); + +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_DELAYABLE_MSG_H__ */ diff --git a/subsys/bluetooth/mesh/dfd_srv.c b/subsys/bluetooth/mesh/dfd_srv.c index 54184acd9b8..e765f2d5d7b 100644 --- a/subsys/bluetooth/mesh/dfd_srv.c +++ b/subsys/bluetooth/mesh/dfd_srv.c @@ -1148,6 +1148,14 @@ enum bt_mesh_dfd_status bt_mesh_dfd_srv_cancel(struct bt_mesh_dfd_srv *srv, return BT_MESH_DFD_ERR_INTERNAL; } + if (prev_phase == BT_MESH_DFD_PHASE_APPLYING_UPDATE && ctx) { + /* Disable randomization for the Firmware Distribution State message to avoid + * reordering when Firmware Distribution Server sends 2 messages in a row when + * cancelling the update (see section 6.2.3.10 of MshDFUv1.0). + */ + ctx->rnd_delay = false; + } + if (ctx != NULL) { status_rsp(srv, ctx, BT_MESH_DFD_SUCCESS); } diff --git a/subsys/bluetooth/mesh/friend.c b/subsys/bluetooth/mesh/friend.c index 73b75eadf4f..6fbd9f81a68 100644 --- a/subsys/bluetooth/mesh/friend.c +++ b/subsys/bluetooth/mesh/friend.c @@ -13,7 +13,6 @@ #include #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "app_keys.h" @@ -1239,7 +1238,7 @@ static void friend_timeout(struct k_work *work) .start = buf_send_start, .end = buf_send_end, }; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint8_t md; if (!friend_is_allocated(frnd)) { @@ -1281,19 +1280,19 @@ 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, + adv = 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"); + if (!adv) { + LOG_ERR("Unable to allocate friend adv"); return; } - net_buf_add_mem(buf, frnd->last->data, frnd->last->len); + net_buf_simple_add_mem(&adv->b, frnd->last->data, frnd->last->len); frnd->pending_req = 0U; frnd->pending_buf = 1U; - bt_mesh_adv_send(buf, &buf_sent_cb, frnd); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &buf_sent_cb, frnd); + bt_mesh_adv_unref(adv); } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) diff --git a/subsys/bluetooth/mesh/gatt_cli.c b/subsys/bluetooth/mesh/gatt_cli.c index bff9b567011..7814f32f27f 100644 --- a/subsys/bluetooth/mesh/gatt_cli.c +++ b/subsys/bluetooth/mesh/gatt_cli.c @@ -18,7 +18,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/health_srv.c b/subsys/bluetooth/mesh/health_srv.c index 8611e1004f6..3db3410aa34 100644 --- a/subsys/bluetooth/mesh/health_srv.c +++ b/subsys/bluetooth/mesh/health_srv.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "transport.h" #include "access.h" diff --git a/subsys/bluetooth/mesh/lpn.c b/subsys/bluetooth/mesh/lpn.c index 2b655f729f3..f6f906b12fe 100644 --- a/subsys/bluetooth/mesh/lpn.c +++ b/subsys/bluetooth/mesh/lpn.c @@ -13,7 +13,6 @@ #include #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index 2c78ea227de..77ca15b2d61 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -18,7 +18,6 @@ #include #include "test.h" -#include "adv.h" #include "prov.h" #include "provisioner.h" #include "net.h" @@ -360,6 +359,7 @@ void bt_mesh_reset(void) */ (void)k_work_cancel_delayable(&bt_mesh.ivu_timer); + bt_mesh_access_reset(); bt_mesh_model_reset(); bt_mesh_cfg_default_set(); bt_mesh_trans_reset(); @@ -401,6 +401,10 @@ void bt_mesh_reset(void) bt_mesh_comp_unprovision(); + if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION)) { + bt_mesh_sol_reset(); + } + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { bt_mesh_settings_store_pending(); } @@ -408,10 +412,6 @@ void bt_mesh_reset(void) if (IS_ENABLED(CONFIG_BT_MESH_PROV)) { bt_mesh_prov_reset(); } - - if (IS_ENABLED(CONFIG_BT_MESH_PROXY_SOLICITATION)) { - bt_mesh_sol_reset(); - } } bool bt_mesh_is_provisioned(void) @@ -460,6 +460,31 @@ int bt_mesh_suspend(void) bt_mesh_model_foreach(model_suspend, NULL); + bt_mesh_access_suspend(); + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) { + err = bt_mesh_pb_gatt_srv_disable(); + if (err && err != -EALREADY) { + LOG_WRN("Disabling PB-GATT failed (err %d)", err); + return err; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + err = bt_mesh_proxy_gatt_disable(); + if (err && err != -EALREADY) { + LOG_WRN("Disabling GATT proxy failed (err %d)", err); + return err; + } + } + + err = bt_mesh_adv_disable(); + if (err) { + atomic_clear_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + LOG_WRN("Disabling advertisers failed (err %d)", err); + return err; + } + return 0; } @@ -488,6 +513,33 @@ int bt_mesh_resume(void) return -EALREADY; } + if (!IS_ENABLED(CONFIG_BT_EXT_ADV)) { + bt_mesh_adv_init(); + } + + err = bt_mesh_adv_enable(); + if (err) { + atomic_set_bit(bt_mesh.flags, BT_MESH_SUSPENDED); + LOG_WRN("Re-enabling advertisers failed (err %d)", err); + return err; + } + + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) && bt_mesh_is_provisioned()) { + err = bt_mesh_proxy_gatt_enable(); + if (err) { + LOG_WRN("Re-enabling GATT proxy failed (err %d)", err); + return err; + } + } + + if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT) && !bt_mesh_is_provisioned()) { + err = bt_mesh_pb_gatt_srv_enable(); + if (err) { + LOG_WRN("Re-enabling PB-GATT failed (err %d)", err); + return err; + } + } + err = bt_mesh_scan_enable(); if (err) { LOG_WRN("Re-enabling scanning failed (err %d)", err); @@ -504,7 +556,13 @@ int bt_mesh_resume(void) bt_mesh_model_foreach(model_resume, NULL); - return err; + err = bt_mesh_adv_gatt_send(); + if (err && (err != -ENOTSUP)) { + LOG_WRN("GATT send failed (err %d)", err); + return err; + } + + return 0; } int bt_mesh_init(const struct bt_mesh_prov *prov, @@ -541,6 +599,7 @@ int bt_mesh_init(const struct bt_mesh_prov *prov, bt_mesh_cfg_default_set(); bt_mesh_net_init(); bt_mesh_trans_init(); + bt_mesh_access_init(); bt_mesh_hb_init(); bt_mesh_beacon_init(); bt_mesh_adv_init(); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 6a9f29b4064..07c6f1aa18a 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -36,10 +35,7 @@ #include "prov.h" #include "cfg.h" #include "statistic.h" - -#ifdef CONFIG_BT_MESH_V1d1 #include "sar_cfg_internal.h" -#endif #define LOG_LEVEL CONFIG_BT_MESH_NET_LOG_LEVEL #include @@ -85,10 +81,8 @@ static uint16_t msg_cache_next; /* Singleton network context (the implementation only supports one) */ struct bt_mesh_net bt_mesh = { .local_queue = SYS_SLIST_STATIC_INIT(&bt_mesh.local_queue), -#ifdef CONFIG_BT_MESH_V1d1 .sar_tx = BT_MESH_SAR_TX_INIT, .sar_rx = BT_MESH_SAR_RX_INIT, -#endif #if defined(CONFIG_BT_MESH_PRIV_BEACONS) .priv_beacon_int = 0x3c, @@ -526,19 +520,19 @@ static int net_loopback(const struct bt_mesh_net_tx *tx, const uint8_t *data, return 0; } -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data) { const struct bt_mesh_net_cred *cred; int err; LOG_DBG("src 0x%04x dst 0x%04x len %u headroom %zu tailroom %zu", tx->src, tx->ctx->addr, - buf->len, net_buf_headroom(buf), net_buf_tailroom(buf)); - LOG_DBG("Payload len %u: %s", buf->len, bt_hex(buf->data, buf->len)); + adv->b.len, net_buf_simple_headroom(&adv->b), net_buf_simple_tailroom(&adv->b)); + LOG_DBG("Payload len %u: %s", adv->b.len, bt_hex(adv->b.data, adv->b.len)); LOG_DBG("Seq 0x%06x", bt_mesh.seq); cred = net_tx_cred_get(tx); - err = net_header_encode(tx, cred->nid, &buf->b); + err = net_header_encode(tx, cred->nid, &adv->b); if (err) { goto done; } @@ -546,7 +540,7 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, /* Deliver to local network interface if necessary */ if (bt_mesh_fixed_group_match(tx->ctx->addr) || bt_mesh_has_addr(tx->ctx->addr)) { - err = net_loopback(tx, buf->data, buf->len); + err = net_loopback(tx, adv->b.data, adv->b.len); /* Local unicast messages should not go out to network */ if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr) || @@ -569,28 +563,28 @@ int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, goto done; } - err = net_encrypt(&buf->b, cred, BT_MESH_NET_IVI_TX, BT_MESH_NONCE_NETWORK); + err = net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_TX, BT_MESH_NONCE_NETWORK); if (err) { goto done; } - BT_MESH_ADV(buf)->cb = cb; - BT_MESH_ADV(buf)->cb_data = cb_data; + adv->ctx.cb = cb; + adv->ctx.cb_data = cb_data; /* Deliver to GATT Proxy Clients if necessary. */ if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_relay(buf, tx->ctx->addr); + (void)bt_mesh_proxy_relay(adv, tx->ctx->addr); } /* Deliver to GATT Proxy Servers if necessary. */ if (IS_ENABLED(CONFIG_BT_MESH_PROXY_CLIENT)) { - (void)bt_mesh_proxy_cli_relay(buf); + (void)bt_mesh_proxy_cli_relay(adv); } - bt_mesh_adv_send(buf, cb, cb_data); + bt_mesh_adv_send(adv, cb, cb_data); done: - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return err; } @@ -684,7 +678,7 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, struct bt_mesh_net_rx *rx) { const struct bt_mesh_net_cred *cred; - struct net_buf *buf; + struct bt_mesh_adv *adv; uint8_t transmit; if (rx->ctx.recv_ttl <= 1U) { @@ -711,10 +705,10 @@ 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, + adv = 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"); + if (!adv) { + LOG_DBG("Out of relay advs"); return; } @@ -722,23 +716,23 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, sbuf->data[1] &= 0x80; sbuf->data[1] |= rx->ctx.recv_ttl - 1U; - net_buf_add_mem(buf, sbuf->data, sbuf->len); + net_buf_simple_add_mem(&adv->b, sbuf->data, sbuf->len); cred = &rx->sub->keys[SUBNET_KEY_TX_IDX(rx->sub)].msg; - LOG_DBG("Relaying packet. TTL is now %u", TTL(buf->data)); + LOG_DBG("Relaying packet. TTL is now %u", TTL(adv->b.data)); /* Update NID if RX or RX was with friend credentials */ if (rx->friend_cred) { - buf->data[0] &= 0x80; /* Clear everything except IVI */ - buf->data[0] |= cred->nid; + adv->b.data[0] &= 0x80; /* Clear everything except IVI */ + adv->b.data[0] |= cred->nid; } /* We re-encrypt and obfuscate using the received IVI rather than * the normal TX IVI (which may be different) since the transport * layer nonce includes the IVI. */ - if (net_encrypt(&buf->b, cred, BT_MESH_NET_IVI_RX(rx), BT_MESH_NONCE_NETWORK)) { + if (net_encrypt(&adv->b, cred, BT_MESH_NET_IVI_RX(rx), BT_MESH_NONCE_NETWORK)) { LOG_ERR("Re-encrypting failed"); goto done; } @@ -751,15 +745,15 @@ static void bt_mesh_net_relay(struct net_buf_simple *sbuf, (rx->friend_cred || bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_PRIV_GATT_PROXY_ENABLED)) { - bt_mesh_proxy_relay(buf, rx->ctx.recv_dst); + bt_mesh_proxy_relay(adv, rx->ctx.recv_dst); } if (relay_to_adv(rx->net_if) || rx->friend_cred) { - bt_mesh_adv_send(buf, NULL, NULL); + bt_mesh_adv_send(adv, NULL, NULL); } done: - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } void bt_mesh_net_header_parse(struct net_buf_simple *buf, diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 04179a4dd49..28c21da3eaf 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +#include "adv.h" #include "subnet.h" #include @@ -291,7 +292,7 @@ bool bt_mesh_net_iv_update(uint32_t iv_index, bool iv_update); int bt_mesh_net_encode(struct bt_mesh_net_tx *tx, struct net_buf_simple *buf, enum bt_mesh_nonce_type type); -int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct net_buf *buf, +int bt_mesh_net_send(struct bt_mesh_net_tx *tx, struct bt_mesh_adv *adv, const struct bt_mesh_send_cb *cb, void *cb_data); int bt_mesh_net_decode(struct net_buf_simple *in, enum bt_mesh_net_if net_if, diff --git a/subsys/bluetooth/mesh/pb_adv.c b/subsys/bluetooth/mesh/pb_adv.c index e273739ed72..c5c56b1e5b0 100644 --- a/subsys/bluetooth/mesh/pb_adv.c +++ b/subsys/bluetooth/mesh/pb_adv.c @@ -11,7 +11,6 @@ #include #include "host/testing.h" #include "net.h" -#include "adv.h" #include "crypto.h" #include "beacon.h" #include "prov.h" @@ -68,6 +67,8 @@ enum { ADV_LINK_INVALID, /* Error occurred during provisioning */ ADV_ACK_PENDING, /* An acknowledgment is being sent */ ADV_PROVISIONER, /* The link was opened as provisioner */ + ADV_LINK_ACK_SENDING, /* Link Ack tx was scheduled but not finished. */ + ADV_SENDING, /* Sending any PDU */ ADV_NUM_FLAGS, }; @@ -101,8 +102,11 @@ struct pb_adv { /* Transaction timeout in seconds */ uint8_t timeout; - /* Pending outgoing buffer(s) */ - struct net_buf *buf[3]; + /* Pending outgoing adv(s) (Link Open, Gen Trans Start and Gen Trans Cont) */ + struct bt_mesh_adv *adv[3]; + + /* Index of the next adv to be sent */ + int next; prov_bearer_send_complete_t cb; @@ -110,6 +114,18 @@ struct pb_adv { /* Retransmit timer */ struct k_work_delayable retransmit; + + /* Unacked adv buffers (Link Ack, Link Close and Gen Trans Ack). Array size is + * hardcoded to 2 allowing to send Gen Trans Ack and Link Close at the same time. + */ + struct unacked_adv_ctx { + struct bt_mesh_adv *adv; + prov_bearer_send_complete_t cb; + void *cb_data; + } unacked[2]; + + /* Last sent unacked[] buffer */ + int last_unacked; } tx; /* Protocol timeout */ @@ -133,28 +149,124 @@ static void link_close(struct prov_rx *rx, struct net_buf_simple *buf); static void prov_link_close(enum prov_bearer_link_status status); static void close_link(enum prov_bearer_link_status status); -static void buf_sent(int err, void *user_data) +static void tx_work_handler(struct k_work *work); +static K_WORK_DELAYABLE_DEFINE(tx_work, tx_work_handler); + +static void tx_schedule(void) { - enum prov_bearer_link_status reason = (enum prov_bearer_link_status)(int)user_data; + uint16_t random_delay; - if (atomic_test_and_clear_bit(link.flags, ADV_LINK_CLOSING)) { - close_link(reason); + if (atomic_test_bit(link.flags, ADV_SENDING)) { + LOG_DBG("Another tx is in progress"); return; } + + (void)bt_rand(&random_delay, sizeof(random_delay)); + random_delay = 20 + (random_delay % 30); + + LOG_DBG("Next PDU delayed by %ums", random_delay); + + (void)k_work_schedule(&tx_work, K_MSEC(random_delay)); +} + +static int send_unacked(struct bt_mesh_adv *adv, prov_bearer_send_complete_t cb, + void *cb_data) +{ + for (int i = 0; i < ARRAY_SIZE(link.tx.unacked); i++) { + if (link.tx.unacked[i].adv != NULL) { + continue; + } + + link.tx.unacked[i].adv = adv; + link.tx.unacked[i].cb = cb; + link.tx.unacked[i].cb_data = cb_data; + + tx_schedule(); + + return 0; + } + + LOG_WRN("No memory to send unacked PDU: %s", bt_hex(adv->b.data, adv->b.len)); + return -ENOMEM; +} + +static void send_reliable(void) +{ + /* Dropping next tx adv index to start transmission from the first adv buffer. */ + link.tx.next = 0; + + tx_schedule(); +} + +static void delayed_adv_send_end(int err, void *user_data) +{ + bool unacked = (bool)user_data; + struct unacked_adv_ctx *unacked_adv = &link.tx.unacked[link.tx.last_unacked]; + + if (unacked && unacked_adv->adv != NULL) { + if (unacked_adv->cb) { + unacked_adv->cb(err, unacked_adv->cb_data); + } + + bt_mesh_adv_unref(unacked_adv->adv); + unacked_adv->adv = NULL; + } + + atomic_clear_bit(link.flags, ADV_SENDING); + tx_schedule(); } -static void buf_start(uint16_t duration, int err, void *user_data) +static void delayed_adv_send_start(uint16_t duration, int err, void *user_data) { if (err) { - buf_sent(err, user_data); + delayed_adv_send_end(err, user_data); } } -static struct bt_mesh_send_cb buf_sent_cb = { - .start = buf_start, - .end = buf_sent, +static const struct bt_mesh_send_cb delayed_adv_send_cb = { + .start = delayed_adv_send_start, + .end = delayed_adv_send_end, }; +static void tx_work_handler(struct k_work *work) +{ + int i; + + /* Send Link Ack, Link Close and Gen Trans Ack first. */ + for (i = 0; i < ARRAY_SIZE(link.tx.unacked); i++) { + int idx = (i + link.tx.last_unacked) % ARRAY_SIZE(link.tx.unacked); + struct unacked_adv_ctx *unacked = &link.tx.unacked[idx]; + + if (!unacked->adv) { + continue; + } + + atomic_set_bit(link.flags, ADV_SENDING); + bt_mesh_adv_send(unacked->adv, &delayed_adv_send_cb, (void *)true); + + link.tx.last_unacked = idx; + + return; + } + + /* Send Trans Start, Trans Cont and Link Open */ + if (link.tx.next >= ARRAY_SIZE(link.tx.adv) || link.tx.adv[link.tx.next] == NULL) { + LOG_DBG("All PDUs were sent"); + return; + } + + atomic_set_bit(link.flags, ADV_SENDING); + bt_mesh_adv_send(link.tx.adv[link.tx.next], &delayed_adv_send_cb, (void *)false); + + link.tx.next++; + + if (link.tx.next == ARRAY_SIZE(link.tx.adv) || link.tx.adv[link.tx.next] == NULL) { + /* All ack-able PDUs are sent. Now we can run the retransmit timer. */ + LOG_DBG("Starting retransmit timer"); + k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); + } +} + static uint8_t last_seg(uint16_t len) { if (len <= START_PAYLOAD_MAX) { @@ -169,25 +281,36 @@ static uint8_t last_seg(uint16_t len) static void free_segments(void) { int i; + bool canceled = false; - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; + for (i = 0; i < ARRAY_SIZE(link.tx.adv); i++) { + struct bt_mesh_adv *adv = link.tx.adv[i]; + int err; - if (!buf) { + if (!adv) { break; } - link.tx.buf[i] = NULL; + link.tx.adv[i] = NULL; /* Terminate active adv */ - if (BT_MESH_ADV(buf)->busy == 0U) { - bt_mesh_adv_buf_terminate(buf); + if (adv->ctx.busy == 0U) { + err = bt_mesh_adv_terminate(adv); + if (err == 0) { + canceled = true; + } } else { /* Mark as canceled */ - BT_MESH_ADV(buf)->busy = 0U; + adv->ctx.busy = 0U; + canceled = true; } - net_buf_unref(buf); + bt_mesh_adv_unref(adv); + } + + if (canceled) { + atomic_clear_bit(link.flags, ADV_SENDING); + tx_schedule(); } } @@ -200,7 +323,7 @@ static void prov_clear_tx(void) { LOG_DBG(""); - /* If this fails, the work handler will not find any buffers to send, + /* If this fails, the work handler will not find any advs to send, * and return without rescheduling. The work handler also checks the * LINK_ACTIVE flag, so if this call is part of reset_adv_link, it'll * exit early. @@ -254,22 +377,22 @@ static void close_link(enum prov_bearer_link_status reason) cb->link_closed(&bt_mesh_pb_adv, cb_data, reason); } -static struct net_buf *adv_buf_create(uint8_t retransmits) +static struct bt_mesh_adv *adv_create(uint8_t retransmits) { - struct net_buf *buf; + struct bt_mesh_adv *adv; - buf = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, + adv = bt_mesh_adv_create(BT_MESH_ADV_PROV, BT_MESH_ADV_TAG_PROV, BT_MESH_TRANSMIT(retransmits, 20), BUF_TIMEOUT); - if (!buf) { - LOG_ERR("Out of provisioning buffers"); + if (!adv) { + LOG_ERR("Out of provisioning advs"); return NULL; } - return buf; + return adv; } -static void ack_complete(uint16_t duration, int err, void *user_data) +static void ack_complete(int err, void *user_data) { LOG_DBG("xact 0x%x complete", (uint8_t)link.tx.pending_ack); atomic_clear_bit(link.flags, ADV_ACK_PENDING); @@ -324,12 +447,9 @@ static void protocol_timeout(struct k_work *work) static void gen_prov_ack_send(uint8_t xact_id) { - static const struct bt_mesh_send_cb cb = { - .start = ack_complete, - }; - const struct bt_mesh_send_cb *complete; - struct net_buf *buf; + struct bt_mesh_adv *adv; bool pending = atomic_test_and_set_bit(link.flags, ADV_ACK_PENDING); + int err; LOG_DBG("xact_id 0x%x", xact_id); @@ -338,25 +458,24 @@ static void gen_prov_ack_send(uint8_t xact_id) return; } - buf = adv_buf_create(RETRANSMITS_ACK); - if (!buf) { + adv = adv_create(RETRANSMITS_ACK); + if (!adv) { atomic_clear_bit(link.flags, ADV_ACK_PENDING); return; } - if (pending) { - complete = NULL; - } else { + if (!pending) { link.tx.pending_ack = xact_id; - complete = &cb; } - net_buf_add_be32(buf, link.id); - net_buf_add_u8(buf, xact_id); - net_buf_add_u8(buf, GPC_ACK); + net_buf_simple_add_be32(&adv->b, link.id); + net_buf_simple_add_u8(&adv->b, xact_id); + net_buf_simple_add_u8(&adv->b, GPC_ACK); - bt_mesh_adv_send(buf, complete, NULL); - net_buf_unref(buf); + err = send_unacked(adv, pending ? NULL : ack_complete, NULL); + if (err) { + atomic_clear_bit(link.flags, ADV_ACK_PENDING); + } } static void gen_prov_cont(struct prov_rx *rx, struct net_buf_simple *buf) @@ -431,7 +550,7 @@ static void gen_prov_ack(struct prov_rx *rx, struct net_buf_simple *buf) { LOG_DBG("len %u", buf->len); - if (!link.tx.buf[0]) { + if (!link.tx.adv[0]) { return; } @@ -592,29 +711,6 @@ static void gen_prov_recv(struct prov_rx *rx, struct net_buf_simple *buf) * TX ******************************************************************************/ -static void send_reliable(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(link.tx.buf); i++) { - struct net_buf *buf = link.tx.buf[i]; - - if (!buf) { - break; - } - - if (BT_MESH_ADV(buf)->busy) { - continue; - } - - LOG_DBG("%u bytes: %s", buf->len, bt_hex(buf->data, buf->len)); - - bt_mesh_adv_send(buf, NULL, NULL); - } - - k_work_reschedule(&link.tx.retransmit, RETRANSMIT_TIMEOUT); -} - static void prov_retransmit(struct k_work *work) { LOG_DBG(""); @@ -633,30 +729,30 @@ static void prov_retransmit(struct k_work *work) send_reliable(); } -static struct net_buf *ctl_buf_create(uint8_t op, const void *data, uint8_t data_len, - uint8_t retransmits) +static struct bt_mesh_adv *ctl_adv_create(uint8_t op, const void *data, uint8_t data_len, + uint8_t retransmits) { - struct net_buf *buf; + struct bt_mesh_adv *adv; LOG_DBG("op 0x%02x data_len %u", op, data_len); - buf = adv_buf_create(retransmits); - if (!buf) { + adv = adv_create(retransmits); + if (!adv) { return NULL; } - net_buf_add_be32(buf, link.id); + net_buf_simple_add_be32(&adv->b, link.id); /* Transaction ID, always 0 for Bearer messages */ - net_buf_add_u8(buf, 0x00); - net_buf_add_u8(buf, GPC_CTL(op)); - net_buf_add_mem(buf, data, data_len); + net_buf_simple_add_u8(&adv->b, 0x00); + net_buf_simple_add_u8(&adv->b, GPC_CTL(op)); + net_buf_simple_add_mem(&adv->b, data, data_len); - return buf; + return adv; } -static int bearer_ctl_send(struct net_buf *buf) +static int bearer_ctl_send(struct bt_mesh_adv *adv) { - if (!buf) { + if (!adv) { return -ENOMEM; } @@ -664,50 +760,66 @@ static int bearer_ctl_send(struct net_buf *buf) k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); link.tx.start = k_uptime_get(); - link.tx.buf[0] = buf; + link.tx.adv[0] = adv; send_reliable(); return 0; } -static int bearer_ctl_send_unacked(struct net_buf *buf, void *user_data) +static void buf_sent(int err, void *user_data) { - if (!buf) { + enum prov_bearer_link_status reason = (enum prov_bearer_link_status)(int)user_data; + + atomic_clear_bit(link.flags, ADV_LINK_ACK_SENDING); + + if (atomic_test_and_clear_bit(link.flags, ADV_LINK_CLOSING)) { + close_link(reason); + return; + } +} + +static int bearer_ctl_send_unacked(struct bt_mesh_adv *adv, void *user_data) +{ + int err; + + if (!adv) { return -ENOMEM; } prov_clear_tx(); k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); - bt_mesh_adv_send(buf, &buf_sent_cb, user_data); - net_buf_unref(buf); + err = send_unacked(adv, &buf_sent, user_data); + if (err) { + bt_mesh_adv_unref(adv); + } - return 0; + return err; } static int prov_send_adv(struct net_buf_simple *msg, prov_bearer_send_complete_t cb, void *cb_data) { - struct net_buf *start, *buf; + struct bt_mesh_adv *start, *adv; uint8_t seg_len, seg_id; prov_clear_tx(); k_work_reschedule(&link.prot_timer, bt_mesh_prov_protocol_timeout_get()); - start = adv_buf_create(RETRANSMITS_RELIABLE); + start = adv_create(RETRANSMITS_RELIABLE); if (!start) { return -ENOBUFS; } link.tx.id = next_transaction_id(link.tx.id); - net_buf_add_be32(start, link.id); - net_buf_add_u8(start, link.tx.id); + net_buf_simple_add_be32(&start->b, link.id); + net_buf_simple_add_u8(&start->b, link.tx.id); - net_buf_add_u8(start, GPC_START(last_seg(msg->len))); - net_buf_add_be16(start, msg->len); - net_buf_add_u8(start, bt_mesh_fcs_calc(msg->data, msg->len)); + net_buf_simple_add_u8(&start->b, GPC_START(last_seg(msg->len))); + net_buf_simple_add_be16(&start->b, msg->len); + net_buf_simple_add_u8(&start->b, bt_mesh_fcs_calc(msg->data, msg->len)); - link.tx.buf[0] = start; + link.tx.adv[0] = start; link.tx.cb = cb; link.tx.cb_data = cb_data; link.tx.start = k_uptime_get(); @@ -716,33 +828,33 @@ static int prov_send_adv(struct net_buf_simple *msg, seg_len = MIN(msg->len, START_PAYLOAD_MAX); LOG_DBG("seg 0 len %u: %s", seg_len, bt_hex(msg->data, seg_len)); - net_buf_add_mem(start, msg->data, seg_len); + net_buf_simple_add_mem(&start->b, msg->data, seg_len); net_buf_simple_pull(msg, seg_len); - buf = start; + adv = start; for (seg_id = 1U; msg->len > 0; seg_id++) { - if (seg_id >= ARRAY_SIZE(link.tx.buf)) { + if (seg_id >= ARRAY_SIZE(link.tx.adv)) { LOG_ERR("Too big message"); free_segments(); return -E2BIG; } - buf = adv_buf_create(RETRANSMITS_RELIABLE); - if (!buf) { + adv = adv_create(RETRANSMITS_RELIABLE); + if (!adv) { free_segments(); return -ENOBUFS; } - link.tx.buf[seg_id] = buf; + link.tx.adv[seg_id] = adv; seg_len = MIN(msg->len, CONT_PAYLOAD_MAX); LOG_DBG("seg %u len %u: %s", seg_id, seg_len, bt_hex(msg->data, seg_len)); - net_buf_add_be32(buf, link.id); - net_buf_add_u8(buf, link.tx.id); - net_buf_add_u8(buf, GPC_CONT(seg_id)); - net_buf_add_mem(buf, msg->data, seg_len); + net_buf_simple_add_be32(&adv->b, link.id); + net_buf_simple_add_u8(&adv->b, link.tx.id); + net_buf_simple_add_u8(&adv->b, GPC_CONT(seg_id)); + net_buf_simple_add_mem(&adv->b, msg->data, seg_len); net_buf_simple_pull(msg, seg_len); } @@ -773,10 +885,15 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) return; } - LOG_DBG("Resending link ack"); + if (atomic_test_bit(link.flags, ADV_LINK_ACK_SENDING)) { + LOG_DBG("Still sending Link Ack"); + return; + } + /* Ignore errors, message will be attempted again if we keep receiving link open: */ + atomic_set_bit(link.flags, ADV_LINK_ACK_SENDING); (void)bearer_ctl_send_unacked( - ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), + ctl_adv_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), (void *)PROV_BEARER_LINK_STATUS_SUCCESS); return; } @@ -790,8 +907,9 @@ static void link_open(struct prov_rx *rx, struct net_buf_simple *buf) atomic_set_bit(link.flags, ADV_LINK_ACTIVE); net_buf_simple_reset(link.rx.buf); + atomic_set_bit(link.flags, ADV_LINK_ACK_SENDING); err = bearer_ctl_send_unacked( - ctl_buf_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), + ctl_adv_create(LINK_ACK, NULL, 0, RETRANSMITS_ACK), (void *)PROV_BEARER_LINK_STATUS_SUCCESS); if (err) { reset_adv_link(); @@ -891,7 +1009,7 @@ static int prov_link_open(const uint8_t uuid[16], uint8_t timeout, net_buf_simple_reset(link.rx.buf); - return bearer_ctl_send(ctl_buf_create(LINK_OPEN, uuid, 16, RETRANSMITS_RELIABLE)); + return bearer_ctl_send(ctl_adv_create(LINK_OPEN, uuid, 16, RETRANSMITS_RELIABLE)); } static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) @@ -924,6 +1042,8 @@ static int prov_link_accept(const struct prov_bearer_cb *cb, void *cb_data) static void prov_link_close(enum prov_bearer_link_status status) { + int err; + if (atomic_test_and_set_bit(link.flags, ADV_LINK_CLOSING)) { return; } @@ -935,9 +1055,12 @@ static void prov_link_close(enum prov_bearer_link_status status) */ link.tx.timeout = CLOSING_TIMEOUT; /* Ignore errors, the link will time out eventually if this doesn't get sent */ - bearer_ctl_send_unacked( - ctl_buf_create(LINK_CLOSE, &status, 1, RETRANSMITS_LINK_CLOSE), + err = bearer_ctl_send_unacked( + ctl_adv_create(LINK_CLOSE, &status, 1, RETRANSMITS_LINK_CLOSE), (void *)status); + if (err) { + close_link(status); + } } void bt_mesh_pb_adv_init(void) diff --git a/subsys/bluetooth/mesh/pb_gatt.c b/subsys/bluetooth/mesh/pb_gatt.c index f8acc8f6c5a..849914f4b5f 100644 --- a/subsys/bluetooth/mesh/pb_gatt.c +++ b/subsys/bluetooth/mesh/pb_gatt.c @@ -8,7 +8,6 @@ #include #include "net.h" #include "proxy.h" -#include "adv.h" #include "prov.h" #include "pb_gatt.h" #include "proxy_msg.h" diff --git a/subsys/bluetooth/mesh/pb_gatt_cli.c b/subsys/bluetooth/mesh/pb_gatt_cli.c index 9231cc0f0b1..bf7dc14029a 100644 --- a/subsys/bluetooth/mesh/pb_gatt_cli.c +++ b/subsys/bluetooth/mesh/pb_gatt_cli.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/pb_gatt_srv.c b/subsys/bluetooth/mesh/pb_gatt_srv.c index f6d9298fc78..f4fdac53570 100644 --- a/subsys/bluetooth/mesh/pb_gatt_srv.c +++ b/subsys/bluetooth/mesh/pb_gatt_srv.c @@ -17,7 +17,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" diff --git a/subsys/bluetooth/mesh/priv_beacon_srv.c b/subsys/bluetooth/mesh/priv_beacon_srv.c index 5b5e62f1736..98be589fc22 100644 --- a/subsys/bluetooth/mesh/priv_beacon_srv.c +++ b/subsys/bluetooth/mesh/priv_beacon_srv.c @@ -5,7 +5,6 @@ */ #include #include "net.h" -#include "adv.h" #include #include "proxy.h" #include "foundation.h" diff --git a/subsys/bluetooth/mesh/prov_device.c b/subsys/bluetooth/mesh/provisionee.c similarity index 98% rename from subsys/bluetooth/mesh/prov_device.c rename to subsys/bluetooth/mesh/provisionee.c index af890396ac7..dcecb5838f0 100644 --- a/subsys/bluetooth/mesh/prov_device.c +++ b/subsys/bluetooth/mesh/provisionee.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -33,9 +32,9 @@ #include "settings.h" #include "rpr.h" -#define LOG_LEVEL CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL +#define LOG_LEVEL CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL #include -LOG_MODULE_REGISTER(bt_mesh_prov_device); +LOG_MODULE_REGISTER(bt_mesh_provisionee); static void reprovision_fail(void); @@ -697,8 +696,8 @@ int bt_mesh_prov_enable(bt_mesh_prov_bearer_t bearers) return -EALREADY; } -#if defined(CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL) - if (CONFIG_BT_MESH_PROV_DEVICE_LOG_LEVEL > 2) { +#if defined(CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL) + if (CONFIG_BT_MESH_PROVISIONEE_LOG_LEVEL > 2) { struct bt_uuid_128 uuid = { .uuid = { BT_UUID_TYPE_128 } }; sys_memcpy_swap(uuid.val, bt_mesh_prov->uuid, 16); diff --git a/subsys/bluetooth/mesh/provisioner.c b/subsys/bluetooth/mesh/provisioner.c index aba2449892f..08b3f8bb8f1 100644 --- a/subsys/bluetooth/mesh/provisioner.c +++ b/subsys/bluetooth/mesh/provisioner.c @@ -21,7 +21,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "rpl.h" @@ -47,7 +46,7 @@ static struct { uint8_t attention_duration; uint8_t uuid[16]; uint8_t new_dev_key[16]; -} prov_device; +} provisionee; static void send_pub_key(void); static void prov_dh_key_gen(void); @@ -55,8 +54,8 @@ static void prov_dh_key_gen(void); static int reset_state(void) { if (!atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION) && - prov_device.node != NULL) { - bt_mesh_cdb_node_del(prov_device.node, false); + provisionee.node != NULL) { + bt_mesh_cdb_node_del(provisionee.node, false); } return bt_mesh_prov_reset_state(); @@ -87,9 +86,9 @@ static void send_invite(void) LOG_DBG(""); bt_mesh_prov_buf_init(&inv, PROV_INVITE); - net_buf_simple_add_u8(&inv, prov_device.attention_duration); + net_buf_simple_add_u8(&inv, provisionee.attention_duration); - memcpy(bt_mesh_prov_link.conf_inputs.invite, &prov_device.attention_duration, + memcpy(bt_mesh_prov_link.conf_inputs.invite, &provisionee.attention_duration, PDU_LEN_INVITE); if (bt_mesh_prov_send(&inv, NULL)) { @@ -247,8 +246,8 @@ static void prov_capabilities(const uint8_t *data) LOG_DBG("Input OOB Size: %u", caps.input_size); LOG_DBG("Input OOB Action: 0x%04x", caps.input_actions); - prov_device.elem_count = caps.elem_count; - if (prov_device.elem_count == 0) { + provisionee.elem_count = caps.elem_count; + if (provisionee.elem_count == 0) { LOG_ERR("Invalid number of elements"); prov_fail(PROV_ERR_NVAL_FMT); return; @@ -272,7 +271,7 @@ static void prov_capabilities(const uint8_t *data) if (atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION)) { if (!bt_mesh_prov_link.addr) { bt_mesh_prov_link.addr = bt_mesh_cdb_free_addr_get( - prov_device.elem_count); + provisionee.elem_count); if (!bt_mesh_prov_link.addr) { LOG_ERR("Failed allocating address for node"); prov_fail(PROV_ERR_ADDR); @@ -280,19 +279,19 @@ static void prov_capabilities(const uint8_t *data) } } } else { - prov_device.node = - bt_mesh_cdb_node_alloc(prov_device.uuid, + provisionee.node = + bt_mesh_cdb_node_alloc(provisionee.uuid, bt_mesh_prov_link.addr, - prov_device.elem_count, - prov_device.net_idx); - if (prov_device.node == NULL) { + provisionee.elem_count, + provisionee.net_idx); + if (provisionee.node == NULL) { LOG_ERR("Failed allocating node 0x%04x", bt_mesh_prov_link.addr); prov_fail(PROV_ERR_RESOURCES); return; } /* Address might change in the alloc call */ - bt_mesh_prov_link.addr = prov_device.node->addr; + bt_mesh_prov_link.addr = provisionee.node->addr; } memcpy(bt_mesh_prov_link.conf_inputs.capabilities, data, PDU_LEN_CAPABILITIES); @@ -518,16 +517,16 @@ static void send_prov_data(void) LOG_DBG("Nonce: %s", bt_hex(nonce, 13)); err = bt_mesh_dev_key(bt_mesh_prov_link.dhkey, - bt_mesh_prov_link.prov_salt, prov_device.new_dev_key); + bt_mesh_prov_link.prov_salt, provisionee.new_dev_key); if (err) { LOG_ERR("Unable to generate device key"); prov_fail(PROV_ERR_UNEXP_ERR); goto session_key_destructor; } - sub = bt_mesh_cdb_subnet_get(prov_device.node->net_idx); + sub = bt_mesh_cdb_subnet_get(provisionee.node->net_idx); if (sub == NULL) { - LOG_ERR("No subnet with net_idx %u", prov_device.node->net_idx); + LOG_ERR("No subnet with net_idx %u", provisionee.node->net_idx); prov_fail(PROV_ERR_UNEXP_ERR); goto session_key_destructor; } @@ -541,14 +540,14 @@ static void send_prov_data(void) bt_mesh_prov_buf_init(&pdu, PROV_DATA); net_buf_simple_add_mem(&pdu, net_key, sizeof(net_key)); - net_buf_simple_add_be16(&pdu, prov_device.node->net_idx); + net_buf_simple_add_be16(&pdu, provisionee.node->net_idx); net_buf_simple_add_u8(&pdu, bt_mesh_cdb_subnet_flags(sub)); net_buf_simple_add_be32(&pdu, bt_mesh_cdb.iv_index); net_buf_simple_add_be16(&pdu, bt_mesh_prov_link.addr); net_buf_simple_add(&pdu, 8); /* For MIC */ LOG_DBG("net_idx %u, iv_index 0x%08x, addr 0x%04x", - prov_device.node->net_idx, bt_mesh.iv_index, + provisionee.node->net_idx, bt_mesh.iv_index, bt_mesh_prov_link.addr); err = bt_mesh_prov_encrypt(&session_key, nonce, &pdu.data[1], @@ -572,10 +571,10 @@ static void send_prov_data(void) static void prov_complete(const uint8_t *data) { - struct bt_mesh_cdb_node *node = prov_device.node; + struct bt_mesh_cdb_node *node = provisionee.node; LOG_DBG("key %s, net_idx %u, num_elem %u, addr 0x%04x", - bt_hex(&prov_device.new_dev_key, 16), node->net_idx, + bt_hex(&provisionee.new_dev_key, 16), node->net_idx, node->num_elem, node->addr); bt_mesh_prov_link.expect = PROV_NO_PDU; @@ -587,15 +586,15 @@ static void prov_complete(const uint8_t *data) static void prov_node_add(void) { LOG_DBG(""); - struct bt_mesh_cdb_node *node = prov_device.node; + struct bt_mesh_cdb_node *node = provisionee.node; int err; if (atomic_test_bit(bt_mesh_prov_link.flags, REPROVISION)) { bt_mesh_cdb_node_update(node, bt_mesh_prov_link.addr, - prov_device.elem_count); + provisionee.elem_count); } - err = bt_mesh_cdb_node_key_import(node, prov_device.new_dev_key); + err = bt_mesh_cdb_node_key_import(node, provisionee.new_dev_key); if (err) { LOG_ERR("Failed to import node device key"); return; @@ -605,7 +604,7 @@ static void prov_node_add(void) bt_mesh_cdb_node_store(node); } - prov_device.node = NULL; + provisionee.node = NULL; if (bt_mesh_prov->node_added) { bt_mesh_prov->node_added(node->net_idx, node->uuid, node->addr, @@ -808,7 +807,7 @@ static int link_open(const uint8_t *uuid, const struct prov_bearer *bearer, } if (uuid) { - memcpy(prov_device.uuid, uuid, 16); + memcpy(provisionee.uuid, uuid, 16); struct bt_uuid_128 uuid_repr = { .uuid = { BT_UUID_TYPE_128 } }; @@ -824,8 +823,8 @@ static int link_open(const uint8_t *uuid, const struct prov_bearer *bearer, bt_mesh_prov_link.addr = addr; bt_mesh_prov_link.bearer = bearer; bt_mesh_prov_link.role = &role_provisioner; - prov_device.net_idx = net_idx; - prov_device.attention_duration = attention_duration; + provisionee.net_idx = net_idx; + provisionee.attention_duration = attention_duration; err = bt_mesh_prov_link.bearer->link_open( uuid, timeout, bt_mesh_prov_bearer_cb_get(), bearer_cb_data); @@ -878,15 +877,15 @@ static int reprovision_local_client_server(uint16_t addr) } LOG_DBG("net_idx %u iv_index 0x%08x, addr 0x%04x", - prov_device.node->net_idx, bt_mesh_cdb.iv_index, addr); + provisionee.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; + provisionee.net_idx = provisionee.node->net_idx; + provisionee.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) { @@ -909,13 +908,13 @@ static int reprovision_local_client_server(uint16_t addr) 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); + bt_mesh_prov_link.prov_salt, provisionee.new_dev_key); if (err) { LOG_ERR("Unable to generate device key"); return err; } - bt_mesh_dev_key_cand(prov_device.new_dev_key); + bt_mesh_dev_key_cand(provisionee.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); @@ -944,8 +943,8 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, ctx.refresh = BT_MESH_RPR_NODE_REFRESH_DEVKEY; } - prov_device.node = bt_mesh_cdb_node_get(srv->addr); - if (!prov_device.node) { + provisionee.node = bt_mesh_cdb_node_get(srv->addr); + if (!provisionee.node) { LOG_ERR("No CDB node for 0x%04x", srv->addr); return -ENOENT; } @@ -955,7 +954,7 @@ int bt_mesh_pb_remote_open_node(struct bt_mesh_rpr_cli *cli, return reprovision_local_client_server(addr); } - return link_open(NULL, &pb_remote_cli, prov_device.node->net_idx, addr, + return link_open(NULL, &pb_remote_cli, provisionee.node->net_idx, addr, 0, &ctx, 0); } #endif diff --git a/subsys/bluetooth/mesh/proxy.h b/subsys/bluetooth/mesh/proxy.h index a2f6bb45ff6..34a119c3df6 100644 --- a/subsys/bluetooth/mesh/proxy.h +++ b/subsys/bluetooth/mesh/proxy.h @@ -34,6 +34,6 @@ int bt_mesh_proxy_adv_start(void); void bt_mesh_proxy_identity_start(struct bt_mesh_subnet *sub, bool private); void bt_mesh_proxy_identity_stop(struct bt_mesh_subnet *sub); -bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst); +bool bt_mesh_proxy_relay(struct bt_mesh_adv *adv, 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 a0a25751b41..5dd6b02361f 100644 --- a/subsys/bluetooth/mesh/proxy_cli.c +++ b/subsys/bluetooth/mesh/proxy_cli.c @@ -16,7 +16,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -79,7 +78,7 @@ static struct bt_mesh_proxy_server *find_proxy_srv_by_conn(struct bt_conn *conn) return NULL; } -bool bt_mesh_proxy_cli_relay(struct net_buf *buf) +bool bt_mesh_proxy_cli_relay(struct bt_mesh_adv *adv) { bool relayed = false; int i; @@ -91,7 +90,7 @@ bool bt_mesh_proxy_cli_relay(struct net_buf *buf) continue; } - if (bt_mesh_proxy_relay_send(server->role->conn, buf)) { + if (bt_mesh_proxy_relay_send(server->role->conn, adv)) { continue; } diff --git a/subsys/bluetooth/mesh/proxy_cli.h b/subsys/bluetooth/mesh/proxy_cli.h index 8c1fae10e84..c0b69f4aaf6 100644 --- a/subsys/bluetooth/mesh/proxy_cli.h +++ b/subsys/bluetooth/mesh/proxy_cli.h @@ -8,6 +8,6 @@ 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_relay(struct bt_mesh_adv *adv); bool bt_mesh_proxy_cli_is_connected(uint16_t net_idx); diff --git a/subsys/bluetooth/mesh/proxy_msg.c b/subsys/bluetooth/mesh/proxy_msg.c index 025909e0503..b2fa113d456 100644 --- a/subsys/bluetooth/mesh/proxy_msg.c +++ b/subsys/bluetooth/mesh/proxy_msg.c @@ -21,7 +21,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -196,12 +195,12 @@ int bt_mesh_proxy_msg_send(struct bt_conn *conn, uint8_t type, static void buf_send_end(struct bt_conn *conn, void *user_data) { - struct net_buf *buf = user_data; + struct bt_mesh_adv *adv = user_data; - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } -int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) +int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv) { int err; @@ -211,12 +210,12 @@ int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) * so we need to make a copy. */ net_buf_simple_reserve(&msg, 1); - net_buf_simple_add_mem(&msg, buf->data, buf->len); + net_buf_simple_add_mem(&msg, adv->b.data, adv->b.len); err = bt_mesh_proxy_msg_send(conn, BT_MESH_PROXY_NET_PDU, - &msg, buf_send_end, net_buf_ref(buf)); + &msg, buf_send_end, bt_mesh_adv_ref(adv)); - bt_mesh_adv_send_start(0, err, BT_MESH_ADV(buf)); + bt_mesh_adv_send_start(0, err, &adv->ctx); if (err) { LOG_ERR("Failed to send proxy message (err %d)", err); @@ -225,7 +224,7 @@ int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf) * which is just opaque data to segment_and send) reference given * to segment_and_send() here. */ - net_buf_unref(buf); + bt_mesh_adv_unref(adv); } return err; diff --git a/subsys/bluetooth/mesh/proxy_msg.h b/subsys/bluetooth/mesh/proxy_msg.h index 7d4bd51ae4f..7ad4be7ae5d 100644 --- a/subsys/bluetooth/mesh/proxy_msg.h +++ b/subsys/bluetooth/mesh/proxy_msg.h @@ -51,7 +51,7 @@ ssize_t bt_mesh_proxy_msg_recv(struct bt_conn *conn, int bt_mesh_proxy_msg_send(struct bt_conn *conn, uint8_t type, struct net_buf_simple *msg, bt_gatt_complete_func_t end, void *user_data); -int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct net_buf *buf); +int bt_mesh_proxy_relay_send(struct bt_conn *conn, struct bt_mesh_adv *adv); struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(struct bt_conn *conn, proxy_send_cb_t send, proxy_recv_cb_t recv); diff --git a/subsys/bluetooth/mesh/proxy_srv.c b/subsys/bluetooth/mesh/proxy_srv.c index 571144ceaed..a903d94ffa9 100644 --- a/subsys/bluetooth/mesh/proxy_srv.c +++ b/subsys/bluetooth/mesh/proxy_srv.c @@ -20,7 +20,6 @@ #include "common/bt_str.h" #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "transport.h" @@ -626,7 +625,7 @@ static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration) return 0; } -static bool advertise_subnet(struct bt_mesh_subnet *sub) +static bool is_sub_proxy_active(struct bt_mesh_subnet *sub) { if (sub->net_idx == BT_MESH_KEY_UNUSED) { return false; @@ -634,201 +633,252 @@ static bool advertise_subnet(struct bt_mesh_subnet *sub) return (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING || #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - sub->solicited || + (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited) || #endif bt_mesh_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED || bt_mesh_priv_gatt_proxy_get() == BT_MESH_GATT_PROXY_ENABLED); } -static struct bt_mesh_subnet *next_sub(void) +static bool active_proxy_sub_cnt_cb(struct bt_mesh_subnet *sub, void *cb_data) { - struct bt_mesh_subnet *sub = NULL; + int *cnt = cb_data; - if (!beacon_sub) { - beacon_sub = bt_mesh_subnet_next(NULL); - if (!beacon_sub) { - /* No valid subnets */ - return NULL; - } + if (is_sub_proxy_active(sub)) { + (*cnt)++; } - sub = beacon_sub; - do { - if (advertise_subnet(sub)) { - beacon_sub = sub; - return sub; - } + /* Don't stop until we've visited all subnets. + * We're only using the "find" variant of the subnet iteration to get a context parameter. + */ + return false; +} + +static int active_proxy_sub_cnt_get(void) +{ + int cnt = 0; - sub = bt_mesh_subnet_next(sub); - } while (sub != beacon_sub); + (void)bt_mesh_subnet_find(active_proxy_sub_cnt_cb, &cnt); - /* No subnets to advertise on */ - return NULL; + return cnt; } -static bool sub_count_cb(struct bt_mesh_subnet *sub, void *cb_data) +static void proxy_adv_timeout_eval(struct bt_mesh_subnet *sub) { - int *count = cb_data; - - if (advertise_subnet(sub)) { - (*count)++; + int32_t time_passed; + + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + time_passed = k_uptime_get_32() - sub->node_id_start; + if (time_passed > (NODE_ID_TIMEOUT - MSEC_PER_SEC)) { + bt_mesh_proxy_identity_stop(sub); + LOG_DBG("Node ID stopped for subnet %d after %dms", sub->net_idx, + time_passed); + } } - /* Don't stop until we've visited all subnets. - * We're only using the "find" variant of the subnet iteration to get a context parameter. - */ - return false; +#if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) + if (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited && sub->priv_net_id_sent) { + time_passed = k_uptime_get_32() - sub->priv_net_id_sent; + if (time_passed > ((MSEC_PER_SEC * bt_mesh_od_priv_proxy_get()) - MSEC_PER_SEC)) { + sub->priv_net_id_sent = 0; + sub->solicited = false; + LOG_DBG("Private Network ID stopped for subnet %d after %dms on " + "solicitation", + sub->net_idx, time_passed); + } + } +#endif } -static int sub_count(void) +enum proxy_adv_evt { + NET_ID, + PRIV_NET_ID, + NODE_ID, + PRIV_NODE_ID, + OD_PRIV_NET_ID, +}; + +struct proxy_adv_request { + int32_t duration; + enum proxy_adv_evt evt; +}; + +static bool proxy_adv_request_get(struct bt_mesh_subnet *sub, struct proxy_adv_request *request) { - int count = 0; + if (!sub) { + return false; + } - (void)bt_mesh_subnet_find(sub_count_cb, &count); + if (sub->net_idx == BT_MESH_KEY_UNUSED) { + return false; + } - return count; -} + /** The priority for proxy adv is first solicitation, then Node Identity, + * and lastly Network ID. Network ID is prioritized last since, in many + * cases, another device can fulfill the same demand. Solicitation is + * prioritized first since legacy devices are dependent on this to + * connect to the network. + */ #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) -static void gatt_proxy_solicited(struct bt_mesh_subnet *sub) -{ - int64_t now = k_uptime_get(); - int64_t timeout = 0; - int32_t remaining; - - if (sub->priv_net_id_sent > 0) { - 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(); + if (bt_mesh_od_priv_proxy_get() > 0 && sub->solicited) { + int32_t timeout = MSEC_PER_SEC * (int32_t)bt_mesh_od_priv_proxy_get(); + + request->evt = OD_PRIV_NET_ID; + request->duration = !sub->priv_net_id_sent + ? timeout + : timeout - (k_uptime_get_32() - sub->priv_net_id_sent); + return true; } +#endif - if ((timeout > 0 && now > timeout) || (remaining / MSEC_PER_SEC < 1)) { - LOG_DBG("Advertising Private Network ID timed out " - "after solicitation"); - sub->priv_net_id_sent = 0; - sub->solicited = false; - } else { - LOG_DBG("Advertising Private Network ID for %ds" - "(%d remaining)", - bt_mesh_od_priv_proxy_get(), - remaining / MSEC_PER_SEC); - priv_net_id_adv(sub, remaining); + if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { + request->duration = NODE_ID_TIMEOUT - (k_uptime_get_32() - sub->node_id_start); + request->evt = +#if defined(CONFIG_BT_MESH_PRIV_BEACONS) + sub->priv_beacon_ctx.node_id ? PRIV_NODE_ID : +#endif + NODE_ID; - if (!sub->priv_net_id_sent) { - sub->priv_net_id_sent = now; - } + return true; + } + + if (bt_mesh_priv_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { + request->evt = PRIV_NET_ID; + request->duration = PROXY_RANDOM_UPDATE_INTERVAL; + return true; } + + if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { + request->evt = NET_ID; + request->duration = SYS_FOREVER_MS; + return true; + } + + return false; } -#endif -static int gatt_proxy_advertise(struct bt_mesh_subnet *sub) +static struct bt_mesh_subnet *adv_sub_get_next(struct bt_mesh_subnet *sub_start, + struct proxy_adv_request *request) { - int32_t remaining = SYS_FOREVER_MS; - int subnet_count; - int err = -EBUSY; - bool planned = false; + struct bt_mesh_subnet *sub_temp = bt_mesh_subnet_next(sub_start); + + do { + if (proxy_adv_request_get(sub_temp, request)) { + return sub_temp; + } + + sub_temp = bt_mesh_subnet_next(sub_temp); + } while (sub_temp != sub_start); + + return NULL; +} + +static struct { + int32_t start; + struct bt_mesh_subnet *sub; + struct proxy_adv_request request; +} sub_adv; + +static int gatt_proxy_advertise(void) +{ + int err; + + int32_t max_adv_duration; + int cnt; + struct bt_mesh_subnet *sub; + struct proxy_adv_request request; LOG_DBG(""); + /* Close proxy activity that has timed out on all subnets */ + bt_mesh_subnet_foreach(proxy_adv_timeout_eval); + if (!bt_mesh_proxy_has_avail_conn()) { LOG_DBG("Connectable advertising deferred (max connections)"); return -ENOMEM; } - sub = beacon_sub ? beacon_sub : bt_mesh_subnet_next(beacon_sub); - if (!sub) { - LOG_WRN("No subnets to advertise on"); + cnt = active_proxy_sub_cnt_get(); + if (!cnt) { + LOG_DBG("No subnets to advertise proxy on"); return -ENOENT; - } - - subnet_count = sub_count(); - LOG_DBG("sub_count %u", subnet_count); - if (subnet_count > 1) { - int32_t max_timeout; + } else if (cnt > 1) { + /** There is more than one subnet that requires proxy adv, + * and the adv resources must be shared. + */ /* We use NODE_ID_TIMEOUT as a starting point since it may * be less than 60 seconds. Divide this period into at least - * 6 slices, but make sure that a slice is at least one + * 6 slices, but make sure that a slice is more than one * second long (to avoid excessive rotation). */ - max_timeout = NODE_ID_TIMEOUT / MAX(subnet_count, 6); - max_timeout = MAX(max_timeout, 1 * MSEC_PER_SEC); - - if (remaining > max_timeout || remaining == SYS_FOREVER_MS) { - remaining = max_timeout; + max_adv_duration = NODE_ID_TIMEOUT / MAX(cnt, 6); + max_adv_duration = MAX(max_adv_duration, MSEC_PER_SEC + 20); + + /* Check if the previous subnet finished its allocated timeslot */ + if ((sub_adv.request.duration != SYS_FOREVER_MS) && + proxy_adv_request_get(sub_adv.sub, &request) && + (sub_adv.request.evt == request.evt)) { + int32_t time_passed = k_uptime_get_32() - sub_adv.start; + + if (time_passed < sub_adv.request.duration && + ((sub_adv.request.duration - time_passed) >= MSEC_PER_SEC)) { + sub = sub_adv.sub; + request.duration = sub_adv.request.duration - time_passed; + goto end; + } } } - for (int i = 0; i < subnet_count; i++) { - - if (sub->node_id == BT_MESH_NODE_IDENTITY_RUNNING) { - uint32_t active = k_uptime_get_32() - sub->node_id_start; - bool priv_node_id = false; - - if (active < NODE_ID_TIMEOUT) { - remaining = MIN(remaining, NODE_ID_TIMEOUT - active); - LOG_DBG("Node ID active for %u ms, %d ms remaining", - active, remaining); -#if defined(CONFIG_BT_MESH_PRIV_BEACONS) - priv_node_id = sub->priv_beacon_ctx.node_id; -#endif - if (priv_node_id) { - err = priv_node_id_adv(sub, remaining); - } else { - err = node_id_adv(sub, remaining); - } - planned = true; - } else { - bt_mesh_proxy_identity_stop(sub); - LOG_DBG("Node ID stopped"); - } - } + sub = adv_sub_get_next(sub_adv.sub, &request); + if (!sub) { + LOG_ERR("Could not find subnet to advertise"); + return -ENOENT; + } +end: + if (cnt > 1) { + request.duration = (request.duration == SYS_FOREVER_MS) + ? max_adv_duration + : MIN(request.duration, max_adv_duration); + } - /* 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)) { - /* 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. - */ - if (remaining == SYS_FOREVER_MS || - remaining > PROXY_RANDOM_UPDATE_INTERVAL) { - remaining = PROXY_RANDOM_UPDATE_INTERVAL; - } - - err = priv_net_id_adv(sub, remaining); - planned = true; - } else if (bt_mesh_gatt_proxy_get() == BT_MESH_FEATURE_ENABLED) { - err = net_id_adv(sub, remaining); - planned = true; - } + /* Save current state for next iteration */ + sub_adv.start = k_uptime_get_32(); + sub_adv.sub = sub; + sub_adv.request = request; + switch (request.evt) { + case NET_ID: + err = net_id_adv(sub, request.duration); + break; #if defined(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV) - else if (bt_mesh_od_priv_proxy_get() > 0 && - sub->solicited) { - gatt_proxy_solicited(sub); - } -#endif - } - - beacon_sub = bt_mesh_subnet_next(sub); - - if (planned) { - LOG_DBG("Advertising %d ms for net_idx 0x%04x", remaining, sub->net_idx); - return err; + case OD_PRIV_NET_ID: + if (!sub->priv_net_id_sent) { + sub->priv_net_id_sent = k_uptime_get(); } + /* Fall through */ +#endif + case PRIV_NET_ID: + err = priv_net_id_adv(sub, request.duration); + break; + case NODE_ID: + err = node_id_adv(sub, request.duration); + break; + case PRIV_NODE_ID: + err = priv_node_id_adv(sub, request.duration); + break; + default: + LOG_ERR("Unexpected proxy adv evt: %d", request.evt); + return -ENODEV; + } - sub = beacon_sub; + if (err) { + LOG_ERR("Advertising proxy failed (err: %d)", err); + return err; } - return 0; + LOG_DBG("Advertising %d ms for net_idx 0x%04x", request.duration, sub->net_idx); + return err; } static void subnet_evt(struct bt_mesh_subnet *sub, enum bt_mesh_key_evt evt) @@ -925,6 +975,8 @@ static void svc_reg_work_handler(struct k_work *work) int bt_mesh_proxy_gatt_enable(void) { + int err; + LOG_DBG(""); if (!bt_mesh_is_provisioned()) { @@ -936,7 +988,13 @@ int bt_mesh_proxy_gatt_enable(void) } svc_reg_attempts = PROXY_SVC_REG_ATTEMPTS; - return k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT); + err = k_work_schedule(&svc_reg_work, PROXY_SVC_INIT_TIMEOUT); + if (err < 0) { + LOG_ERR("Enabling GATT proxy failed (err %d)", err); + return err; + } + + return 0; } void bt_mesh_proxy_gatt_disconnect(void) @@ -1022,12 +1080,12 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, return false; } -bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst) +bool bt_mesh_proxy_relay(struct bt_mesh_adv *adv, uint16_t dst) { bool relayed = false; int i; - LOG_DBG("%u bytes to dst 0x%04x", buf->len, dst); + LOG_DBG("%u bytes to dst 0x%04x", adv->b.len, dst); for (i = 0; i < ARRAY_SIZE(clients); i++) { struct bt_mesh_proxy_client *client = &clients[i]; @@ -1040,7 +1098,7 @@ bool bt_mesh_proxy_relay(struct net_buf *buf, uint16_t dst) continue; } - if (bt_mesh_proxy_relay_send(client->cli->conn, buf)) { + if (bt_mesh_proxy_relay_send(client->cli->conn, adv)) { continue; } @@ -1153,7 +1211,7 @@ int bt_mesh_proxy_adv_start(void) return -ENOTSUP; } - return gatt_proxy_advertise(next_sub()); + return gatt_proxy_advertise(); } BT_CONN_CB_DEFINE(conn_callbacks) = { diff --git a/subsys/bluetooth/mesh/rpl.c b/subsys/bluetooth/mesh/rpl.c index b3113530854..df67ddf9d2e 100644 --- a/subsys/bluetooth/mesh/rpl.c +++ b/subsys/bluetooth/mesh/rpl.c @@ -20,7 +20,6 @@ #include #include "mesh.h" -#include "adv.h" #include "net.h" #include "rpl.h" #include "settings.h" @@ -41,8 +40,9 @@ static ATOMIC_DEFINE(store, CONFIG_BT_MESH_CRPL); enum { PENDING_CLEAR, PENDING_RESET, + RPL_FLAGS_COUNT, }; -static atomic_t rpl_flags; +static ATOMIC_DEFINE(rpl_flags, RPL_FLAGS_COUNT); static inline int rpl_idx(const struct bt_mesh_rpl *rpl) { @@ -133,7 +133,7 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, /* Existing slot for given address */ if (rpl->src == rx->ctx.addr) { if (!rpl->old_iv && - atomic_test_bit(&rpl_flags, PENDING_RESET) && + atomic_test_bit(rpl_flags, PENDING_RESET) && !atomic_test_bit(store, i)) { /* Until rpl reset is finished, entry with old_iv == false and * without "store" bit set will be removed, therefore it can be @@ -178,7 +178,7 @@ void bt_mesh_rpl_clear(void) return; } - atomic_set_bit(&rpl_flags, PENDING_CLEAR); + atomic_set_bit(rpl_flags, PENDING_CLEAR); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } @@ -233,7 +233,7 @@ void bt_mesh_rpl_reset(void) } if (i != 0) { - atomic_set_bit(&rpl_flags, PENDING_RESET); + atomic_set_bit(rpl_flags, PENDING_RESET); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } } else { @@ -358,8 +358,8 @@ void bt_mesh_rpl_pending_store(uint16_t addr) bt_mesh_settings_store_cancel(BT_MESH_SETTINGS_RPL_PENDING); } - clr = atomic_test_and_clear_bit(&rpl_flags, PENDING_CLEAR); - rst = atomic_test_bit(&rpl_flags, PENDING_RESET); + clr = atomic_test_and_clear_bit(rpl_flags, PENDING_CLEAR); + rst = atomic_test_bit(rpl_flags, PENDING_RESET); for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { struct bt_mesh_rpl *rpl = &replay_list[i]; @@ -398,7 +398,7 @@ void bt_mesh_rpl_pending_store(uint16_t addr) } } - atomic_clear_bit(&rpl_flags, PENDING_RESET); + atomic_clear_bit(rpl_flags, PENDING_RESET); if (addr == BT_MESH_ADDR_ALL_NODES) { (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); diff --git a/subsys/bluetooth/mesh/rpr_srv.c b/subsys/bluetooth/mesh/rpr_srv.c index 9813842a367..ac3fd190880 100644 --- a/subsys/bluetooth/mesh/rpr_srv.c +++ b/subsys/bluetooth/mesh/rpr_srv.c @@ -14,7 +14,6 @@ #include #include #include "access.h" -#include "adv.h" #include "prov.h" #include "crypto.h" #include "rpr.h" @@ -969,6 +968,12 @@ static int handle_link_close(const struct bt_mesh_model *mod, struct bt_mesh_msg * which will be used in the link report when the link is fully closed. */ + /* Disable randomization for the Remote Provisioning Link Status message to avoid reordering + * of it with the Remote Provisioning Link Report message that shall be sent in a sequence + * when closing an active link (see section 4.4.5.5.3.3 of MshPRTv1.1). + */ + ctx->rnd_delay = false; + link_status_send(ctx, BT_MESH_RPR_SUCCESS); link_close(BT_MESH_RPR_ERR_LINK_CLOSED_BY_CLIENT, reason); diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 771aad9b946..8ec9c66481a 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -88,7 +88,7 @@ static int mesh_commit(void) } if (!atomic_test_bit(bt_dev.flags, BT_DEV_ENABLE)) { - /* The Bluetooth mesh settings loader calls bt_mesh_start() immediately + /* The Bluetooth Mesh settings loader calls bt_mesh_start() immediately * after loading the settings. This is not intended to work before * bt_enable(). The doc on @ref bt_enable requires the "bt/" settings * tree to be loaded after @ref bt_enable is completed, so this handler @@ -186,8 +186,7 @@ static void store_pending(struct k_work *work) { LOG_DBG(""); - if (IS_ENABLED(CONFIG_BT_MESH_RPL_STORAGE_MODE_SETTINGS) && - atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING)) { + if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_RPL_PENDING)) { bt_mesh_rpl_pending_store(BT_MESH_ADDR_ALL_NODES); } diff --git a/subsys/bluetooth/mesh/shell/Kconfig b/subsys/bluetooth/mesh/shell/Kconfig index 5e1e43f0057..46671c3bfaa 100644 --- a/subsys/bluetooth/mesh/shell/Kconfig +++ b/subsys/bluetooth/mesh/shell/Kconfig @@ -1,13 +1,13 @@ -# Bluetooth mesh shell configuration options +# Bluetooth Mesh shell configuration options # Copyright (c) 2022 Nordic Semiconductor # SPDX-License-Identifier: Apache-2.0 menuconfig BT_MESH_SHELL - bool "Bluetooth mesh shell" + bool "Bluetooth Mesh shell" select SHELL help - Activate shell module that provides Bluetooth mesh commands to + Activate shell module that provides Bluetooth Mesh commands to the console. if BT_MESH_SHELL @@ -24,7 +24,7 @@ config BT_MESH_SHELL_PROV_CTX_INSTANCE depends on BT_MESH_SHELL_PROV help This option enables the provisioning context instance in the - Bluetooth mesh shell module together with several provisioning + Bluetooth Mesh shell module together with several provisioning commands and target utility features. To use the provisioning context instance, use bt_mesh_shell_prov in the initialization of mesh. @@ -54,7 +54,7 @@ config BT_MESH_SHELL_HEALTH_SRV_INSTANCE depends on BT_MESH_SHELL_TEST help This option enables Health Server model instance in the - Bluetooth mesh shell module together with fault controlling + Bluetooth Mesh shell module together with fault controlling shell commands. To use the model instance, add bt_mesh_shell_health_srv to the device composition data. Use BT_MESH_SHELL_HEALTH_PUB_DEFINE to instantiate publication context. diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index a169bb16422..9a0e5ece5e3 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -771,7 +771,7 @@ static int cmd_provision_gatt(const struct shell *sh, size_t argc, } #endif /* CONFIG_BT_MESH_PB_GATT_CLIENT */ -#if defined(CONFIG_BT_MESH_PROV_DEVICE) +#if defined(CONFIG_BT_MESH_PROVISIONEE) static int cmd_pb(bt_mesh_prov_bearer_t bearer, const struct shell *sh, size_t argc, char *argv[]) { @@ -822,7 +822,7 @@ static int cmd_pb_gatt(const struct shell *sh, size_t argc, char *argv[]) return cmd_pb(BT_MESH_PROV_GATT, sh, argc, argv); } #endif /* CONFIG_BT_MESH_PB_GATT */ -#endif /* CONFIG_BT_MESH_PROV_DEVICE */ +#endif /* CONFIG_BT_MESH_PROVISIONEE */ #if defined(CONFIG_BT_MESH_PROVISIONER) static int cmd_remote_pub_key_set(const struct shell *sh, size_t argc, char *argv[]) @@ -1681,14 +1681,14 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(comp-change, NULL, NULL, cmd_comp_change, 1, 0), /* Provisioning operations */ -#if defined(CONFIG_BT_MESH_PROV_DEVICE) +#if defined(CONFIG_BT_MESH_PROVISIONEE) #if defined(CONFIG_BT_MESH_PB_GATT) SHELL_CMD_ARG(pb-gatt, NULL, "", cmd_pb_gatt, 2, 0), #endif #if defined(CONFIG_BT_MESH_PB_ADV) SHELL_CMD_ARG(pb-adv, NULL, "", cmd_pb_adv, 2, 0), #endif -#endif /* CONFIG_BT_MESH_PROV_DEVICE */ +#endif /* CONFIG_BT_MESH_PROVISIONEE */ #if defined(CONFIG_BT_MESH_PROVISIONER) SHELL_CMD(auth-method, &auth_cmds, "Authentication methods", bt_mesh_shell_mdl_cmds_help), @@ -1814,5 +1814,5 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds, SHELL_SUBCMD_SET_END ); -SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth mesh shell commands", +SHELL_CMD_ARG_REGISTER(mesh, &mesh_cmds, "Bluetooth Mesh shell commands", bt_mesh_shell_mdl_cmds_help, 1, 1); diff --git a/subsys/bluetooth/mesh/solicitation.c b/subsys/bluetooth/mesh/solicitation.c index e2100fa42db..a2872daecb0 100644 --- a/subsys/bluetooth/mesh/solicitation.c +++ b/subsys/bluetooth/mesh/solicitation.c @@ -12,7 +12,6 @@ #include #include #include "access.h" -#include "adv.h" #include "cfg.h" #include "crypto.h" #include "mesh.h" @@ -66,7 +65,7 @@ static int srpl_entry_save(struct bt_mesh_subnet *sub, uint32_t sseq, uint16_t s entry = srpl_find_by_addr(ssrc); if (entry) { - if (entry->sseq >= sseq && sseq != 0) { + if (entry->sseq >= sseq) { LOG_WRN("Higher or equal SSEQ already saved for this SSRC"); return -EALREADY; } diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c index 21c451bee73..b9f542a5923 100644 --- a/subsys/bluetooth/mesh/statistic.c +++ b/subsys/bluetooth/mesh/statistic.c @@ -6,7 +6,6 @@ #include -#include "adv.h" #include "net.h" #include "statistic.h" @@ -22,24 +21,24 @@ void bt_mesh_stat_reset(void) memset(&stat, 0, sizeof(struct bt_mesh_statistic)); } -void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) +void bt_mesh_stat_planned_count(struct bt_mesh_adv_ctx *ctx) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (ctx->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (ctx->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_planned++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (ctx->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_planned++; } } -void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv_ctx *ctx) { - if (adv->tag == BT_MESH_ADV_TAG_LOCAL) { + if (ctx->tag == BT_MESH_ADV_TAG_LOCAL) { stat.tx_local_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_RELAY) { + } else if (ctx->tag == BT_MESH_ADV_TAG_RELAY) { stat.tx_adv_relay_succeeded++; - } else if (adv->tag == BT_MESH_ADV_TAG_FRIEND) { + } else if (ctx->tag == BT_MESH_ADV_TAG_FRIEND) { stat.tx_friend_succeeded++; } } diff --git a/subsys/bluetooth/mesh/statistic.h b/subsys/bluetooth/mesh/statistic.h index fdb488f0d81..4cd9187f45a 100644 --- a/subsys/bluetooth/mesh/statistic.h +++ b/subsys/bluetooth/mesh/statistic.h @@ -7,8 +7,8 @@ #ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ #define ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ -void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv); -void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv); +void bt_mesh_stat_planned_count(struct bt_mesh_adv_ctx *ctx); +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv_ctx *ctx); void bt_mesh_stat_rx(enum bt_mesh_net_if net_if); #endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ */ diff --git a/subsys/bluetooth/mesh/subnet.c b/subsys/bluetooth/mesh/subnet.c index ef90ff8f725..695dd321b49 100644 --- a/subsys/bluetooth/mesh/subnet.c +++ b/subsys/bluetooth/mesh/subnet.c @@ -22,7 +22,6 @@ #include "common/bt_str.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "lpn.h" diff --git a/subsys/bluetooth/mesh/subnet.h b/subsys/bluetooth/mesh/subnet.h index f19b1d2abea..e04f9855b66 100644 --- a/subsys/bluetooth/mesh/subnet.h +++ b/subsys/bluetooth/mesh/subnet.h @@ -76,9 +76,7 @@ struct bt_mesh_subnet { struct bt_mesh_key identity; /* IdentityKey */ #endif struct bt_mesh_key beacon; /* BeaconKey */ -#if defined(CONFIG_BT_MESH_V1d1) struct bt_mesh_key priv_beacon; /* PrivateBeaconKey */ -#endif } keys[2]; #if defined(CONFIG_BT_MESH_PROXY_SOLICITATION) bool sol_tx; diff --git a/subsys/bluetooth/mesh/transport.c b/subsys/bluetooth/mesh/transport.c index 94c1f698e91..a0364dceb25 100644 --- a/subsys/bluetooth/mesh/transport.c +++ b/subsys/bluetooth/mesh/transport.c @@ -22,7 +22,6 @@ #include "host/testing.h" #include "crypto.h" -#include "adv.h" #include "mesh.h" #include "net.h" #include "app_keys.h" @@ -122,26 +121,26 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, const struct bt_mesh_send_cb *cb, void *cb_data, const uint8_t *ctl_op) { - struct net_buf *buf; + struct bt_mesh_adv *adv; - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); + if (!adv) { + LOG_ERR("Out of network advs"); return -ENOBUFS; } - net_buf_reserve(buf, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&adv->b, BT_MESH_NET_HDR_LEN); if (ctl_op) { - net_buf_add_u8(buf, TRANS_CTL_HDR(*ctl_op, 0)); + net_buf_simple_add_u8(&adv->b, TRANS_CTL_HDR(*ctl_op, 0)); } else if (BT_MESH_IS_DEV_KEY(tx->ctx->app_idx)) { - net_buf_add_u8(buf, UNSEG_HDR(0, 0)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(0, 0)); } else { - net_buf_add_u8(buf, UNSEG_HDR(1, tx->aid)); + net_buf_simple_add_u8(&adv->b, UNSEG_HDR(1, tx->aid)); } - net_buf_add_mem(buf, sdu->data, sdu->len); + net_buf_simple_add_mem(&adv->b, sdu->data, sdu->len); if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, @@ -149,7 +148,7 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, NULL, 1)) { if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { LOG_ERR("Not enough space in Friend Queue"); - net_buf_unref(buf); + bt_mesh_adv_unref(adv); return -ENOBUFS; } else { LOG_WRN("No space in Friend Queue"); @@ -158,19 +157,19 @@ static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, } if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - NULL, 1, &buf->b) && + NULL, 1, &adv->b) && BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { /* PDUs for a specific Friend should only go * out through the Friend Queue. */ - net_buf_unref(buf); + bt_mesh_adv_unref(adv); send_cb_finalize(cb, cb_data); return 0; } } send: - return bt_mesh_net_send(tx, buf, cb, cb_data); + return bt_mesh_net_send(tx, adv, cb, cb_data); } static inline uint8_t seg_len(bool ctl) @@ -405,7 +404,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) (uint16_t)(tx->seq_auth & TRANS_SEQ_ZERO_MASK), tx->attempts_left); while (tx->seg_o <= tx->seg_n) { - struct net_buf *seg; + struct bt_mesh_adv *seg; int err; if (!tx->seg[tx->seg_o]) { @@ -421,7 +420,7 @@ static void seg_tx_send_unacked(struct seg_tx *tx) goto end; } - net_buf_reserve(seg, BT_MESH_NET_HDR_LEN); + net_buf_simple_reserve(&seg->b, BT_MESH_NET_HDR_LEN); seg_tx_buf_build(tx, tx->seg_o, &seg->b); LOG_DBG("Sending %u/%u", tx->seg_o, tx->seg_n); @@ -870,6 +869,8 @@ static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, /* Best effort - we don't have enough info for true SeqAuth */ *seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(rx), seq_zero); return 0; + } else if (!rx->local_match) { + return 0; } ack = net_buf_simple_pull_be32(buf); @@ -970,7 +971,7 @@ static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, return bt_mesh_hb_recv(rx, buf); } - /* Only acks and heartbeats may need processing without local_match */ + /* Only acks for friendship and heartbeats may need processing without local_match */ if (!rx->local_match) { return 0; } diff --git a/subsys/bluetooth/mesh/transport_legacy.c b/subsys/bluetooth/mesh/transport_legacy.c deleted file mode 100644 index da0c1830f73..00000000000 --- a/subsys/bluetooth/mesh/transport_legacy.c +++ /dev/null @@ -1,1657 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "common/bt_str.h" - -#include "host/testing.h" - -#include "crypto.h" -#include "adv.h" -#include "mesh.h" -#include "net.h" -#include "app_keys.h" -#include "lpn.h" -#include "rpl.h" -#include "friend.h" -#include "access.h" -#include "foundation.h" -#include "settings.h" -#include "heartbeat.h" -#include "transport.h" -#include "va.h" - -#define LOG_LEVEL CONFIG_BT_MESH_TRANS_LOG_LEVEL -#include -LOG_MODULE_REGISTER(bt_mesh_transport); - -#define AID_MASK ((uint8_t)(BIT_MASK(6))) - -#define SEG(data) ((data)[0] >> 7) -#define AKF(data) (((data)[0] >> 6) & 0x01) -#define AID(data) ((data)[0] & AID_MASK) -#define ASZMIC(data) (((data)[1] >> 7) & 1) - -#define APP_MIC_LEN(aszmic) ((aszmic) ? BT_MESH_MIC_LONG : BT_MESH_MIC_SHORT) - -#define UNSEG_HDR(akf, aid) ((akf << 6) | (aid & AID_MASK)) -#define SEG_HDR(akf, aid) (UNSEG_HDR(akf, aid) | 0x80) - -#define BLOCK_COMPLETE(seg_n) (uint32_t)(((uint64_t)1 << (seg_n + 1)) - 1) - -#define SEQ_AUTH(iv_index, seq) (((uint64_t)iv_index) << 24 | (uint64_t)seq) - -/* Number of retransmit attempts (after the initial transmit) per segment */ -#define SEG_RETRANSMIT_ATTEMPTS CONFIG_BT_MESH_TX_SEG_RETRANS_COUNT - -/* "This timer shall be set to a minimum of 200 + 50 * TTL milliseconds.". - * We use 400 since 300 is a common send duration for standard HCI, and we - * need to have a timeout that's bigger than that. - */ -#define SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) \ - (CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_UNICAST + 50 * (tx)->ttl) - -/* When sending to a group, the messages are not acknowledged, and there's no - * reason to delay the repetitions significantly. Delaying by more than 0 ms - * to avoid flooding the network. - */ -#define SEG_RETRANSMIT_TIMEOUT_GROUP CONFIG_BT_MESH_TX_SEG_RETRANS_TIMEOUT_GROUP - -#define SEG_RETRANSMIT_TIMEOUT(tx) \ - (BT_MESH_ADDR_IS_UNICAST(tx->dst) ? \ - SEG_RETRANSMIT_TIMEOUT_UNICAST(tx) : \ - SEG_RETRANSMIT_TIMEOUT_GROUP) -/* How long to wait for available buffers before giving up */ -#define BUF_TIMEOUT K_NO_WAIT - -static struct seg_tx { - struct bt_mesh_subnet *sub; - void *seg[BT_MESH_TX_SEG_MAX]; - uint64_t seq_auth; - uint16_t src; - uint16_t dst; - uint16_t ack_src; - uint16_t len; - uint8_t hdr; - uint8_t xmit; - uint8_t seg_n; /* Last segment index */ - uint8_t seg_o; /* Segment being sent */ - uint8_t nack_count; /* Number of unacked segs */ - uint8_t attempts; /* Remaining tx attempts */ - uint8_t ttl; /* Transmitted TTL value */ - uint8_t blocked:1, /* Blocked by ongoing tx */ - ctl:1, /* Control packet */ - aszmic:1, /* MIC size */ - started:1, /* Start cb called */ - friend_cred:1, /* Using Friend credentials */ - seg_send_started:1; /* Used to check if seg_send_start cb is called */ - const struct bt_mesh_send_cb *cb; - void *cb_data; - struct k_work_delayable retransmit; /* Retransmit timer */ -} seg_tx[CONFIG_BT_MESH_TX_SEG_MSG_COUNT]; - -static struct seg_rx { - struct bt_mesh_subnet *sub; - void *seg[BT_MESH_RX_SEG_MAX]; - uint64_t seq_auth; - uint16_t src; - uint16_t dst; - uint16_t len; - uint8_t hdr; - uint8_t seg_n:5, - ctl:1, - in_use:1, - obo:1; - uint8_t ttl; - uint32_t block; - uint32_t last; - struct k_work_delayable ack; -} seg_rx[CONFIG_BT_MESH_RX_SEG_MSG_COUNT]; - -K_MEM_SLAB_DEFINE(segs, BT_MESH_APP_SEG_SDU_MAX, CONFIG_BT_MESH_SEG_BUFS, 4); - -static int send_unseg(struct bt_mesh_net_tx *tx, struct net_buf_simple *sdu, - const struct bt_mesh_send_cb *cb, void *cb_data, - const uint8_t *ctl_op) -{ - struct net_buf *buf; - - 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"); - return -ENOBUFS; - } - - net_buf_reserve(buf, BT_MESH_NET_HDR_LEN); - - if (ctl_op) { - net_buf_add_u8(buf, TRANS_CTL_HDR(*ctl_op, 0)); - } else if (BT_MESH_IS_DEV_KEY(tx->ctx->app_idx)) { - net_buf_add_u8(buf, UNSEG_HDR(0, 0)); - } else { - net_buf_add_u8(buf, UNSEG_HDR(1, tx->aid)); - } - - net_buf_add_mem(buf, sdu->data, sdu->len); - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { - if (!bt_mesh_friend_queue_has_space(tx->sub->net_idx, - tx->src, tx->ctx->addr, - NULL, 1)) { - if (BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - LOG_ERR("Not enough space in Friend Queue"); - net_buf_unref(buf); - return -ENOBUFS; - } - - LOG_WRN("No space in Friend Queue"); - goto send; - } - - if (bt_mesh_friend_enqueue_tx(tx, BT_MESH_FRIEND_PDU_SINGLE, - NULL, 1, &buf->b) && - BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr)) { - /* PDUs for a specific Friend should only go - * out through the Friend Queue. - */ - net_buf_unref(buf); - send_cb_finalize(cb, cb_data); - return 0; - } - } - -send: - return bt_mesh_net_send(tx, buf, cb, cb_data); -} - -static inline uint8_t seg_len(bool ctl) -{ - if (ctl) { - return BT_MESH_CTL_SEG_SDU_MAX; - } else { - return BT_MESH_APP_SEG_SDU_MAX; - } -} - -bool bt_mesh_tx_in_progress(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { - if (seg_tx[i].nack_count) { - return true; - } - } - - return false; -} - -static void seg_tx_done(struct seg_tx *tx, uint8_t seg_idx) -{ - k_mem_slab_free(&segs, (void *)tx->seg[seg_idx]); - tx->seg[seg_idx] = NULL; - tx->nack_count--; -} - -static bool seg_tx_blocks(struct seg_tx *tx, uint16_t src, uint16_t dst) -{ - return (tx->src == src) && (tx->dst == dst); -} - -static void seg_tx_unblock_check(struct seg_tx *tx) -{ - struct seg_tx *blocked = NULL; - int i; - - /* Unblock the first blocked tx with the same params. */ - for (i = 0; i < ARRAY_SIZE(seg_tx); ++i) { - if (&seg_tx[i] != tx && - seg_tx[i].blocked && - seg_tx_blocks(tx, seg_tx[i].src, seg_tx[i].dst) && - (!blocked || seg_tx[i].seq_auth < blocked->seq_auth)) { - blocked = &seg_tx[i]; - } - } - - if (blocked) { - LOG_DBG("Unblocked 0x%04x", (uint16_t)(blocked->seq_auth & TRANS_SEQ_ZERO_MASK)); - blocked->blocked = false; - k_work_reschedule(&blocked->retransmit, K_NO_WAIT); - } -} - -static void seg_tx_reset(struct seg_tx *tx) -{ - int i; - - /* If this call fails, the handler will exit early, as nack_count is 0. */ - (void)k_work_cancel_delayable(&tx->retransmit); - - tx->cb = NULL; - tx->cb_data = NULL; - tx->seq_auth = 0U; - tx->sub = NULL; - tx->src = BT_MESH_ADDR_UNASSIGNED; - tx->dst = BT_MESH_ADDR_UNASSIGNED; - tx->ack_src = BT_MESH_ADDR_UNASSIGNED; - tx->blocked = false; - - for (i = 0; i <= tx->seg_n && tx->nack_count; i++) { - if (!tx->seg[i]) { - continue; - } - - seg_tx_done(tx, i); - } - - tx->nack_count = 0; - tx->seg_send_started = 0; - - if (atomic_test_and_clear_bit(bt_mesh.flags, BT_MESH_IVU_PENDING)) { - LOG_DBG("Proceeding with pending IV Update"); - /* bt_mesh_net_iv_update() will re-enable the flag if this - * wasn't the only transfer. - */ - bt_mesh_net_iv_update(bt_mesh.iv_index, false); - } -} - -static inline void seg_tx_complete(struct seg_tx *tx, int err) -{ - const struct bt_mesh_send_cb *cb = tx->cb; - void *cb_data = tx->cb_data; - - seg_tx_unblock_check(tx); - - seg_tx_reset(tx); - - if (cb && cb->end) { - cb->end(err, cb_data); - } -} - -static void schedule_retransmit(struct seg_tx *tx) -{ - if (!tx->nack_count) { - return; - } - - LOG_DBG(""); - - /* If we haven't gone through all the segments for this attempt yet, - * (likely because of a buffer allocation failure or because we - * called this from inside bt_mesh_net_send), we should continue the - * retransmit immediately, as we just freed up a tx buffer. - */ - k_work_reschedule(&tx->retransmit, K_NO_WAIT); -} - -static void seg_send_start(uint16_t duration, int err, void *user_data) -{ - struct seg_tx *tx = user_data; - - if (!tx->started && tx->cb && tx->cb->start) { - tx->cb->start(duration, err, tx->cb_data); - tx->started = 1U; - } - - tx->seg_send_started = 1U; - - /* If there's an error in transmitting the 'sent' callback will never - * be called. Make sure that we kick the retransmit timer also in this - * case since otherwise we risk the transmission of becoming stale. - */ - if (err) { - schedule_retransmit(tx); - } -} - -static void seg_sent(int err, void *user_data) -{ - struct seg_tx *tx = user_data; - - if (!tx->seg_send_started) { - return; - } - - schedule_retransmit(tx); -} - -static const struct bt_mesh_send_cb seg_sent_cb = { - .start = seg_send_start, - .end = seg_sent, -}; - -static void seg_tx_buf_build(struct seg_tx *tx, uint8_t seg_o, - struct net_buf_simple *buf) -{ - uint16_t seq_zero = tx->seq_auth & TRANS_SEQ_ZERO_MASK; - uint8_t len = MIN(seg_len(tx->ctl), tx->len - (seg_len(tx->ctl) * seg_o)); - - net_buf_simple_add_u8(buf, tx->hdr); - net_buf_simple_add_u8(buf, (tx->aszmic << 7) | seq_zero >> 6); - net_buf_simple_add_u8(buf, (((seq_zero & 0x3f) << 2) | (seg_o >> 3))); - net_buf_simple_add_u8(buf, ((seg_o & 0x07) << 5) | tx->seg_n); - net_buf_simple_add_mem(buf, tx->seg[seg_o], len); -} - -static void seg_tx_send_unacked(struct seg_tx *tx) -{ - if (!tx->nack_count) { - return; - } - - struct bt_mesh_msg_ctx ctx = { - .net_idx = tx->sub->net_idx, - /* App idx only used by network to detect control messages: */ - .app_idx = (tx->ctl ? BT_MESH_KEY_UNUSED : 0), - .addr = tx->dst, - .send_rel = true, - .send_ttl = tx->ttl, - }; - struct bt_mesh_net_tx net_tx = { - .sub = tx->sub, - .ctx = &ctx, - .src = tx->src, - .xmit = tx->xmit, - .friend_cred = tx->friend_cred, - .aid = tx->hdr & AID_MASK, - }; - - if (!tx->attempts) { - if (BT_MESH_ADDR_IS_UNICAST(tx->dst)) { - LOG_ERR("Ran out of retransmit attempts"); - seg_tx_complete(tx, -ETIMEDOUT); - } else { - /* Segmented sending to groups doesn't have acks, so - * running out of attempts is the expected behavior. - */ - seg_tx_complete(tx, 0); - } - - return; - } - - LOG_DBG("SeqZero: 0x%04x Attempts: %u", (uint16_t)(tx->seq_auth & TRANS_SEQ_ZERO_MASK), - tx->attempts); - - while (tx->seg_o <= tx->seg_n) { - struct net_buf *seg; - int err; - - if (!tx->seg[tx->seg_o]) { - /* Move on to the next segment */ - tx->seg_o++; - continue; - } - - 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"); - goto end; - } - - net_buf_reserve(seg, BT_MESH_NET_HDR_LEN); - seg_tx_buf_build(tx, tx->seg_o, &seg->b); - - LOG_DBG("Sending %u/%u", tx->seg_o, tx->seg_n); - - err = bt_mesh_net_send(&net_tx, seg, &seg_sent_cb, tx); - if (err) { - LOG_DBG("Sending segment failed"); - goto end; - } - - /* Move on to the next segment */ - tx->seg_o++; - - return; - } - - tx->seg_o = 0U; - tx->attempts--; - -end: - if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && - bt_mesh_lpn_established() && !bt_mesh_has_addr(ctx.addr)) { - bt_mesh_lpn_poll(); - } - - k_work_reschedule(&tx->retransmit, K_MSEC(SEG_RETRANSMIT_TIMEOUT(tx))); -} - -static void seg_retransmit(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct seg_tx *tx = CONTAINER_OF(dwork, struct seg_tx, retransmit); - - seg_tx_send_unacked(tx); -} - -static int send_seg(struct bt_mesh_net_tx *net_tx, struct net_buf_simple *sdu, - const struct bt_mesh_send_cb *cb, void *cb_data, - uint8_t *ctl_op) -{ - bool blocked = false; - struct seg_tx *tx; - uint8_t seg_o; - int i; - - LOG_DBG("src 0x%04x dst 0x%04x app_idx 0x%04x aszmic %u sdu_len %u", net_tx->src, - net_tx->ctx->addr, net_tx->ctx->app_idx, net_tx->aszmic, sdu->len); - - for (tx = NULL, i = 0; i < ARRAY_SIZE(seg_tx); i++) { - if (seg_tx[i].nack_count) { - blocked |= seg_tx_blocks(&seg_tx[i], net_tx->src, - net_tx->ctx->addr); - } else if (!tx) { - tx = &seg_tx[i]; - } - } - - if (!tx) { - LOG_ERR("No multi-segment message contexts available"); - return -EBUSY; - } - - if (ctl_op) { - tx->hdr = TRANS_CTL_HDR(*ctl_op, 1); - } else if (BT_MESH_IS_DEV_KEY(net_tx->ctx->app_idx)) { - tx->hdr = SEG_HDR(0, 0); - } else { - tx->hdr = SEG_HDR(1, net_tx->aid); - } - - tx->src = net_tx->src; - tx->dst = net_tx->ctx->addr; - tx->seg_n = (sdu->len - 1) / seg_len(!!ctl_op); - tx->seg_o = 0; - tx->len = sdu->len; - tx->nack_count = tx->seg_n + 1; - tx->seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_TX, bt_mesh.seq); - tx->sub = net_tx->sub; - tx->cb = cb; - tx->cb_data = cb_data; - tx->attempts = SEG_RETRANSMIT_ATTEMPTS; - tx->xmit = net_tx->xmit; - tx->aszmic = net_tx->aszmic; - tx->friend_cred = net_tx->friend_cred; - tx->blocked = blocked; - tx->started = 0; - tx->seg_send_started = 0; - tx->ctl = !!ctl_op; - tx->ttl = net_tx->ctx->send_ttl; - - LOG_DBG("SeqZero 0x%04x (segs: %u)", (uint16_t)(tx->seq_auth & TRANS_SEQ_ZERO_MASK), - tx->nack_count); - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && - !bt_mesh_friend_queue_has_space(tx->sub->net_idx, net_tx->src, - tx->dst, &tx->seq_auth, - tx->seg_n + 1) && - BT_MESH_ADDR_IS_UNICAST(tx->dst)) { - LOG_ERR("Not enough space in Friend Queue for %u segments", tx->seg_n + 1); - seg_tx_reset(tx); - return -ENOBUFS; - } - - for (seg_o = 0U; sdu->len; seg_o++) { - void *buf; - uint16_t len; - int err; - - err = k_mem_slab_alloc(&segs, &buf, BUF_TIMEOUT); - if (err) { - LOG_ERR("Out of segment buffers"); - seg_tx_reset(tx); - return -ENOBUFS; - } - - len = MIN(sdu->len, seg_len(!!ctl_op)); - memcpy(buf, net_buf_simple_pull_mem(sdu, len), len); - - LOG_DBG("seg %u: %s", seg_o, bt_hex(buf, len)); - - tx->seg[seg_o] = buf; - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { - enum bt_mesh_friend_pdu_type type; - - NET_BUF_SIMPLE_DEFINE(seg, 16); - seg_tx_buf_build(tx, seg_o, &seg); - - if (seg_o == tx->seg_n) { - type = BT_MESH_FRIEND_PDU_COMPLETE; - } else { - type = BT_MESH_FRIEND_PDU_PARTIAL; - } - - if (bt_mesh_friend_enqueue_tx( - net_tx, type, ctl_op ? NULL : &tx->seq_auth, - tx->seg_n + 1, &seg) && - BT_MESH_ADDR_IS_UNICAST(net_tx->ctx->addr)) { - /* PDUs for a specific Friend should only go - * out through the Friend Queue. - */ - k_mem_slab_free(&segs, buf); - tx->seg[seg_o] = NULL; - } - - } - - } - - /* This can happen if segments only went into the Friend Queue */ - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !tx->seg[0]) { - seg_tx_reset(tx); - - /* If there was a callback notify sending immediately since - * there's no other way to track this (at least currently) - * with the Friend Queue. - */ - send_cb_finalize(cb, cb_data); - return 0; - } - - if (blocked) { - /* Move the sequence number, so we don't end up creating - * another segmented transmission with the same SeqZero while - * this one is blocked. - */ - bt_mesh_next_seq(); - LOG_DBG("Blocked."); - return 0; - } - - seg_tx_send_unacked(tx); - - return 0; -} - -static int trans_encrypt(const struct bt_mesh_net_tx *tx, const struct bt_mesh_key *key, - struct net_buf_simple *msg) -{ - struct bt_mesh_app_crypto_ctx crypto = { - .dev_key = BT_MESH_IS_DEV_KEY(tx->ctx->app_idx), - .aszmic = tx->aszmic, - .src = tx->src, - .dst = tx->ctx->addr, - .seq_num = bt_mesh.seq, - .iv_index = BT_MESH_NET_IVI_TX, - }; - - if (BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) { - crypto.ad = tx->ctx->uuid; - if (crypto.ad == NULL) { - return -ENOENT; - } - } - - return bt_mesh_app_encrypt(key, &crypto, msg); -} - -int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct net_buf_simple *msg, - const struct bt_mesh_send_cb *cb, void *cb_data) -{ - const struct bt_mesh_key *key; - uint8_t aid; - int err; - - if (msg->len < 1) { - LOG_ERR("Zero-length SDU not allowed"); - return -EINVAL; - } - - if (msg->len > BT_MESH_TX_SDU_MAX - BT_MESH_MIC_SHORT) { - LOG_ERR("Message too big: %u", msg->len); - return -EMSGSIZE; - } - - if (net_buf_simple_tailroom(msg) < BT_MESH_MIC_SHORT) { - LOG_ERR("Insufficient tailroom for Transport MIC"); - return -EINVAL; - } - - if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) { - tx->ctx->send_ttl = bt_mesh_default_ttl_get(); - } else if (tx->ctx->send_ttl > BT_MESH_TTL_MAX) { - LOG_ERR("TTL too large (max 127)"); - return -EINVAL; - } - - if (msg->len > BT_MESH_SDU_UNSEG_MAX) { - tx->ctx->send_rel = true; - } - - if (tx->ctx->addr == BT_MESH_ADDR_UNASSIGNED || - (!BT_MESH_ADDR_IS_UNICAST(tx->ctx->addr) && - BT_MESH_IS_DEV_KEY(tx->ctx->app_idx))) { - LOG_ERR("Invalid destination address"); - return -EINVAL; - } - - err = bt_mesh_keys_resolve(tx->ctx, &tx->sub, &key, &aid); - if (err) { - return err; - } - - LOG_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx, tx->ctx->app_idx, - tx->ctx->addr); - LOG_DBG("len %u: %s", msg->len, bt_hex(msg->data, msg->len)); - - tx->xmit = bt_mesh_net_transmit_get(); - tx->aid = aid; - - if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) { - tx->aszmic = 0U; - } else { - tx->aszmic = 1U; - } - - err = trans_encrypt(tx, key, msg); - if (err) { - return err; - } - - if (tx->ctx->send_rel) { - err = send_seg(tx, msg, cb, cb_data, NULL); - } else { - err = send_unseg(tx, msg, cb, cb_data, NULL); - } - - return err; -} - -static void seg_rx_assemble(struct seg_rx *rx, struct net_buf_simple *buf, - uint8_t aszmic) -{ - int i; - - net_buf_simple_reset(buf); - - for (i = 0; i <= rx->seg_n; i++) { - net_buf_simple_add_mem(buf, rx->seg[i], - MIN(seg_len(rx->ctl), - rx->len - (i * seg_len(rx->ctl)))); - } - - /* Adjust the length to not contain the MIC at the end */ - if (!rx->ctl) { - buf->len -= APP_MIC_LEN(aszmic); - } -} - -struct decrypt_ctx { - struct bt_mesh_app_crypto_ctx crypto; - struct net_buf_simple *buf; - struct net_buf_simple *sdu; - struct seg_rx *seg; -}; - -static int sdu_try_decrypt(struct bt_mesh_net_rx *rx, const struct bt_mesh_key *key, - void *cb_data) -{ - struct decrypt_ctx *ctx = cb_data; - int err; - - ctx->crypto.ad = NULL; - - do { - if (ctx->seg) { - seg_rx_assemble(ctx->seg, ctx->buf, ctx->crypto.aszmic); - } - - if (BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { - ctx->crypto.ad = bt_mesh_va_uuid_get(rx->ctx.recv_dst, ctx->crypto.ad, - NULL); - - if (!ctx->crypto.ad) { - return -ENOENT; - } - } - - net_buf_simple_reset(ctx->sdu); - - err = bt_mesh_app_decrypt(key, &ctx->crypto, ctx->buf, ctx->sdu); - } while (err && ctx->crypto.ad != NULL); - - if (!err && BT_MESH_ADDR_IS_VIRTUAL(rx->ctx.recv_dst)) { - rx->ctx.uuid = ctx->crypto.ad; - } - - return err; -} - -static int sdu_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, uint8_t aszmic, - struct net_buf_simple *buf, struct net_buf_simple *sdu, - struct seg_rx *seg) -{ - struct decrypt_ctx ctx = { - .crypto = { - .dev_key = !AKF(&hdr), - .aszmic = aszmic, - .src = rx->ctx.addr, - .dst = rx->ctx.recv_dst, - .seq_num = seg ? (seg->seq_auth & 0xffffff) : rx->seq, - .iv_index = BT_MESH_NET_IVI_RX(rx), - }, - .buf = buf, - .sdu = sdu, - .seg = seg, - }; - - LOG_DBG("AKF %u AID 0x%02x", !ctx.crypto.dev_key, AID(&hdr)); - - if (!rx->local_match) { - return 0; - } - - rx->ctx.app_idx = bt_mesh_app_key_find(ctx.crypto.dev_key, AID(&hdr), - rx, sdu_try_decrypt, &ctx); - if (rx->ctx.app_idx == BT_MESH_KEY_UNUSED) { - LOG_DBG("No matching AppKey"); - return 0; - } - - LOG_DBG("Decrypted (AppIdx: 0x%03x)", rx->ctx.app_idx); - - bt_mesh_model_recv(&rx->ctx, sdu); - - return 0; -} - -static struct seg_tx *seg_tx_lookup(uint16_t seq_zero, uint8_t obo, uint16_t addr) -{ - struct seg_tx *tx; - int i; - - for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { - tx = &seg_tx[i]; - - if ((tx->seq_auth & TRANS_SEQ_ZERO_MASK) != seq_zero) { - continue; - } - - if (tx->dst == addr) { - return tx; - } - - /* If the expected remote address doesn't match, - * but the OBO flag is set and this is the first - * acknowledgment, assume it's a Friend that's - * responding and therefore accept the message. - */ - if (obo && (tx->nack_count == tx->seg_n + 1 || tx->ack_src == addr)) { - tx->ack_src = addr; - return tx; - } - } - - return NULL; -} - -static int trans_ack(struct bt_mesh_net_rx *rx, uint8_t hdr, - struct net_buf_simple *buf, uint64_t *seq_auth) -{ - struct seg_tx *tx; - unsigned int bit; - uint32_t ack; - uint16_t seq_zero; - uint8_t obo; - - if (buf->len < 6) { - LOG_ERR("Too short ack message"); - return -EINVAL; - } - - seq_zero = net_buf_simple_pull_be16(buf); - obo = seq_zero >> 15; - seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match) { - LOG_DBG("Ack for LPN 0x%04x of this Friend", rx->ctx.recv_dst); - /* Best effort - we don't have enough info for true SeqAuth */ - *seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(rx), seq_zero); - return 0; - } - - ack = net_buf_simple_pull_be32(buf); - - LOG_DBG("OBO %u seq_zero 0x%04x ack 0x%08x", obo, seq_zero, ack); - - tx = seg_tx_lookup(seq_zero, obo, rx->ctx.addr); - if (!tx) { - LOG_WRN("No matching TX context for ack"); - return -EINVAL; - } - - if (!BT_MESH_ADDR_IS_UNICAST(tx->dst)) { - LOG_ERR("Received ack for group seg"); - return -EINVAL; - } - - *seq_auth = tx->seq_auth; - - if (!ack) { - LOG_WRN("SDU canceled"); - seg_tx_complete(tx, -ECANCELED); - return 0; - } - - if (find_msb_set(ack) - 1 > tx->seg_n) { - LOG_ERR("Too large segment number in ack"); - return -EINVAL; - } - - while ((bit = find_lsb_set(ack))) { - if (tx->seg[bit - 1]) { - LOG_DBG("seg %u/%u acked", bit - 1, tx->seg_n); - seg_tx_done(tx, bit - 1); - } - - ack &= ~BIT(bit - 1); - } - - if (tx->nack_count) { - /* 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); - } - } else { - LOG_DBG("SDU TX complete"); - seg_tx_complete(tx, 0); - } - - return 0; -} - -static int ctl_recv(struct bt_mesh_net_rx *rx, uint8_t hdr, - struct net_buf_simple *buf, uint64_t *seq_auth) -{ - uint8_t ctl_op = TRANS_CTL_OP(&hdr); - - LOG_DBG("OpCode 0x%02x len %u", ctl_op, buf->len); - - switch (ctl_op) { - case TRANS_CTL_OP_ACK: - return trans_ack(rx, hdr, buf, seq_auth); - case TRANS_CTL_OP_HEARTBEAT: - return bt_mesh_hb_recv(rx, buf); - } - - /* Only acks and heartbeats may need processing without local_match */ - if (!rx->local_match) { - return 0; - } - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && !bt_mesh_lpn_established()) { - switch (ctl_op) { - case TRANS_CTL_OP_FRIEND_POLL: - return bt_mesh_friend_poll(rx, buf); - case TRANS_CTL_OP_FRIEND_REQ: - return bt_mesh_friend_req(rx, buf); - case TRANS_CTL_OP_FRIEND_CLEAR: - return bt_mesh_friend_clear(rx, buf); - case TRANS_CTL_OP_FRIEND_CLEAR_CFM: - return bt_mesh_friend_clear_cfm(rx, buf); - case TRANS_CTL_OP_FRIEND_SUB_ADD: - return bt_mesh_friend_sub_add(rx, buf); - case TRANS_CTL_OP_FRIEND_SUB_REM: - return bt_mesh_friend_sub_rem(rx, buf); - } - } - -#if defined(CONFIG_BT_MESH_LOW_POWER) - if (ctl_op == TRANS_CTL_OP_FRIEND_OFFER) { - return bt_mesh_lpn_friend_offer(rx, buf); - } - - if (rx->ctx.addr == bt_mesh.lpn.frnd) { - if (ctl_op == TRANS_CTL_OP_FRIEND_CLEAR_CFM) { - return bt_mesh_lpn_friend_clear_cfm(rx, buf); - } - - if (!rx->friend_cred) { - LOG_WRN("Message from friend with wrong credentials"); - return -EINVAL; - } - - switch (ctl_op) { - case TRANS_CTL_OP_FRIEND_UPDATE: - return bt_mesh_lpn_friend_update(rx, buf); - case TRANS_CTL_OP_FRIEND_SUB_CFM: - return bt_mesh_lpn_friend_sub_cfm(rx, buf); - } - } -#endif /* CONFIG_BT_MESH_LOW_POWER */ - - LOG_WRN("Unhandled TransOpCode 0x%02x", ctl_op); - - return -ENOENT; -} - -static int trans_unseg(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx, - uint64_t *seq_auth) -{ - NET_BUF_SIMPLE_DEFINE_STATIC(sdu, BT_MESH_SDU_UNSEG_MAX); - uint8_t hdr; - - LOG_DBG("AFK %u AID 0x%02x", AKF(buf->data), AID(buf->data)); - - if (buf->len < 1) { - LOG_ERR("Too small unsegmented PDU"); - return -EINVAL; - } - - if (bt_mesh_rpl_check(rx, NULL)) { - LOG_WRN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", rx->ctx.addr, rx->ctx.recv_dst, - rx->seq); - return -EINVAL; - } - - hdr = net_buf_simple_pull_u8(buf); - - if (rx->ctl) { - return ctl_recv(rx, hdr, buf, seq_auth); - } - - if (buf->len < 1 + APP_MIC_LEN(0)) { - LOG_ERR("Too short SDU + MIC"); - return -EINVAL; - } - - /* Adjust the length to not contain the MIC at the end */ - buf->len -= APP_MIC_LEN(0); - - return sdu_recv(rx, hdr, 0, buf, &sdu, NULL); -} - -static inline int32_t ack_timeout(struct seg_rx *rx) -{ - int32_t to; - uint8_t ttl; - - if (rx->ttl == BT_MESH_TTL_DEFAULT) { - ttl = bt_mesh_default_ttl_get(); - } else { - ttl = rx->ttl; - } - - /* The acknowledgment timer shall be set to a minimum of - * 150 + 50 * TTL milliseconds. - */ - to = CONFIG_BT_MESH_SEG_ACK_BASE_TIMEOUT + - (ttl * (int32_t)CONFIG_BT_MESH_SEG_ACK_PER_HOP_TIMEOUT); - - /* Add timeout for evenry not yet received segment. */ - to += ((rx->seg_n + 1) - POPCOUNT(rx->block)) * - (int32_t)CONFIG_BT_MESH_SEG_ACK_PER_SEGMENT_TIMEOUT; - - /* Make sure we don't send more frequently than the duration for - * each packet (default is 400ms). - */ - return MAX(to, 400); -} - -int bt_mesh_ctl_send(struct bt_mesh_net_tx *tx, uint8_t ctl_op, void *data, - size_t data_len, - const struct bt_mesh_send_cb *cb, void *cb_data) -{ - struct net_buf_simple buf; - - if (tx->ctx->send_ttl == BT_MESH_TTL_DEFAULT) { - tx->ctx->send_ttl = bt_mesh_default_ttl_get(); - } else if (tx->ctx->send_ttl > BT_MESH_TTL_MAX) { - LOG_ERR("TTL too large (max 127)"); - return -EINVAL; - } - - net_buf_simple_init_with_data(&buf, data, data_len); - - if (data_len > BT_MESH_SDU_UNSEG_MAX) { - tx->ctx->send_rel = true; - } - - tx->ctx->app_idx = BT_MESH_KEY_UNUSED; - - if (tx->ctx->addr == BT_MESH_ADDR_UNASSIGNED || - BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) { - LOG_ERR("Invalid destination address"); - return -EINVAL; - } - - LOG_DBG("src 0x%04x dst 0x%04x ttl 0x%02x ctl 0x%02x", tx->src, tx->ctx->addr, - tx->ctx->send_ttl, ctl_op); - LOG_DBG("len %zu: %s", data_len, bt_hex(data, data_len)); - - if (tx->ctx->send_rel) { - return send_seg(tx, &buf, cb, cb_data, &ctl_op); - } else { - return send_unseg(tx, &buf, cb, cb_data, &ctl_op); - } -} - -static int send_ack(struct bt_mesh_subnet *sub, uint16_t src, uint16_t dst, - uint8_t ttl, uint64_t *seq_auth, uint32_t block, uint8_t obo) -{ - struct bt_mesh_msg_ctx ctx = { - .net_idx = sub->net_idx, - .app_idx = BT_MESH_KEY_UNUSED, - .addr = dst, - .send_ttl = ttl, - }; - struct bt_mesh_net_tx tx = { - .sub = sub, - .ctx = &ctx, - .src = obo ? bt_mesh_primary_addr() : src, - .xmit = bt_mesh_net_transmit_get(), - }; - uint16_t seq_zero = *seq_auth & TRANS_SEQ_ZERO_MASK; - uint8_t buf[6]; - - LOG_DBG("SeqZero 0x%04x Block 0x%08x OBO %u", seq_zero, block, obo); - - if (bt_mesh_lpn_established() && !bt_mesh_has_addr(ctx.addr)) { - LOG_WRN("Not sending ack when LPN is enabled"); - return 0; - } - - /* This can happen if the segmented message was destined for a group - * or virtual address. - */ - if (!BT_MESH_ADDR_IS_UNICAST(src)) { - LOG_DBG("Not sending ack for non-unicast address"); - return 0; - } - - sys_put_be16(((seq_zero << 2) & 0x7ffc) | (obo << 15), buf); - sys_put_be32(block, &buf[2]); - - return bt_mesh_ctl_send(&tx, TRANS_CTL_OP_ACK, buf, sizeof(buf), - NULL, NULL); -} - -static void seg_rx_reset(struct seg_rx *rx, bool full_reset) -{ - int i; - - LOG_DBG("rx %p", rx); - - /* If this fails, the handler will exit early on the next execution, as - * it checks rx->in_use. - */ - (void)k_work_cancel_delayable(&rx->ack); - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->obo && - rx->block != BLOCK_COMPLETE(rx->seg_n)) { - LOG_WRN("Clearing incomplete buffers from Friend queue"); - bt_mesh_friend_clear_incomplete(rx->sub, rx->src, rx->dst, - &rx->seq_auth); - } - - for (i = 0; i <= rx->seg_n; i++) { - if (!rx->seg[i]) { - continue; - } - - k_mem_slab_free(&segs, rx->seg[i]); - rx->seg[i] = NULL; - } - - rx->in_use = 0U; - - /* We don't always reset these values since we need to be able to - * send an ack if we receive a segment after we've already received - * the full SDU. - */ - if (full_reset) { - rx->seq_auth = 0U; - rx->sub = NULL; - rx->src = BT_MESH_ADDR_UNASSIGNED; - rx->dst = BT_MESH_ADDR_UNASSIGNED; - } -} - -static void seg_ack(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct seg_rx *rx = CONTAINER_OF(dwork, struct seg_rx, ack); - int32_t timeout; - - if (!rx->in_use || rx->block == BLOCK_COMPLETE(rx->seg_n)) { - /* Cancellation of this timer may have failed. If it fails as - * part of seg_reset, in_use will be false. - * If it fails as part of the processing of a fully received - * SDU, the ack is already being sent from the receive handler, - * and the timer based ack sending can be ignored. - */ - return; - } - - LOG_DBG("rx %p", rx); - - if (k_uptime_get_32() - rx->last > (60 * MSEC_PER_SEC)) { - LOG_WRN("Incomplete timer expired"); - seg_rx_reset(rx, false); - - if (IS_ENABLED(CONFIG_BT_TESTING)) { - bt_test_mesh_trans_incomp_timer_exp(); - } - - return; - } - - send_ack(rx->sub, rx->dst, rx->src, rx->ttl, &rx->seq_auth, - rx->block, rx->obo); - - timeout = ack_timeout(rx); - k_work_schedule(&rx->ack, K_MSEC(timeout)); -} - -static inline bool sdu_len_is_ok(bool ctl, uint8_t seg_n) -{ - return (seg_n < BT_MESH_RX_SEG_MAX); -} - -static struct seg_rx *seg_rx_find(struct bt_mesh_net_rx *net_rx, - const uint64_t *seq_auth) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { - struct seg_rx *rx = &seg_rx[i]; - - if (rx->src != net_rx->ctx.addr || - rx->dst != net_rx->ctx.recv_dst) { - continue; - } - - /* Return newer RX context in addition to an exact match, so - * the calling function can properly discard an old SeqAuth. - */ - if (rx->seq_auth >= *seq_auth) { - return rx; - } - - if (rx->in_use) { - LOG_WRN("Duplicate SDU from src 0x%04x", net_rx->ctx.addr); - - /* Clear out the old context since the sender - * has apparently started sending a new SDU. - */ - seg_rx_reset(rx, true); - - /* Return non-match so caller can re-allocate */ - return NULL; - } - } - - return NULL; -} - -static bool seg_rx_is_valid(struct seg_rx *rx, struct bt_mesh_net_rx *net_rx, - const uint8_t *hdr, uint8_t seg_n) -{ - if (rx->hdr != *hdr || rx->seg_n != seg_n) { - LOG_ERR("Invalid segment for ongoing session"); - return false; - } - - if (rx->src != net_rx->ctx.addr || rx->dst != net_rx->ctx.recv_dst) { - LOG_ERR("Invalid source or destination for segment"); - return false; - } - - if (rx->ctl != net_rx->ctl) { - LOG_ERR("Inconsistent CTL in segment"); - return false; - } - - return true; -} - -static struct seg_rx *seg_rx_alloc(struct bt_mesh_net_rx *net_rx, - const uint8_t *hdr, const uint64_t *seq_auth, - uint8_t seg_n) -{ - int i; - - /* No race condition on this check, as this function only executes in - * the collaborative Bluetooth rx thread: - */ - if (k_mem_slab_num_free_get(&segs) < 1) { - LOG_WRN("Not enough segments for incoming message"); - return NULL; - } - - for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { - struct seg_rx *rx = &seg_rx[i]; - - if (rx->in_use) { - continue; - } - - rx->in_use = 1U; - rx->sub = net_rx->sub; - rx->ctl = net_rx->ctl; - rx->seq_auth = *seq_auth; - rx->seg_n = seg_n; - rx->hdr = *hdr; - rx->ttl = net_rx->ctx.send_ttl; - rx->src = net_rx->ctx.addr; - rx->dst = net_rx->ctx.recv_dst; - rx->block = 0U; - - LOG_DBG("New RX context. Block Complete 0x%08x", BLOCK_COMPLETE(seg_n)); - - return rx; - } - - return NULL; -} - -static int trans_seg(struct net_buf_simple *buf, struct bt_mesh_net_rx *net_rx, - enum bt_mesh_friend_pdu_type *pdu_type, uint64_t *seq_auth, - uint8_t *seg_count) -{ - struct bt_mesh_rpl *rpl = NULL; - struct seg_rx *rx; - uint8_t *hdr = buf->data; - uint16_t seq_zero; - uint32_t auth_seqnum; - uint8_t seg_n; - uint8_t seg_o; - int err; - - if (buf->len < 5) { - LOG_ERR("Too short segmented message (len %u)", buf->len); - return -EINVAL; - } - - if (bt_mesh_rpl_check(net_rx, &rpl)) { - LOG_WRN("Replay: src 0x%04x dst 0x%04x seq 0x%06x", net_rx->ctx.addr, - net_rx->ctx.recv_dst, net_rx->seq); - return -EINVAL; - } - - LOG_DBG("ASZMIC %u AKF %u AID 0x%02x", ASZMIC(hdr), AKF(hdr), AID(hdr)); - - net_buf_simple_pull(buf, 1); - - seq_zero = net_buf_simple_pull_be16(buf); - seg_o = (seq_zero & 0x03) << 3; - seq_zero = (seq_zero >> 2) & TRANS_SEQ_ZERO_MASK; - seg_n = net_buf_simple_pull_u8(buf); - seg_o |= seg_n >> 5; - seg_n &= 0x1f; - - LOG_DBG("SeqZero 0x%04x SegO %u SegN %u", seq_zero, seg_o, seg_n); - - if (seg_o > seg_n) { - LOG_ERR("SegO greater than SegN (%u > %u)", seg_o, seg_n); - return -EINVAL; - } - - /* According to MshPRFv1.0.1: - * "The SeqAuth is composed of the IV Index and the sequence number - * (SEQ) of the first segment" - * - * Therefore we need to calculate very first SEQ in order to find - * seqAuth. We can calculate as below: - * - * SEQ(0) = SEQ(n) - (delta between seqZero and SEQ(n) by looking into - * 14 least significant bits of SEQ(n)) - * - * Mentioned delta shall be >= 0, if it is not then seq_auth will - * be broken and it will be verified by the code below. - */ - *seq_auth = SEQ_AUTH(BT_MESH_NET_IVI_RX(net_rx), - (net_rx->seq - - ((((net_rx->seq & BIT_MASK(14)) - seq_zero)) & - BIT_MASK(13)))); - auth_seqnum = *seq_auth & BIT_MASK(24); - *seg_count = seg_n + 1; - - /* Look for old RX sessions */ - rx = seg_rx_find(net_rx, seq_auth); - if (rx) { - /* Discard old SeqAuth packet */ - if (rx->seq_auth > *seq_auth) { - LOG_WRN("Ignoring old SeqAuth"); - return -EINVAL; - } - - if (!seg_rx_is_valid(rx, net_rx, hdr, seg_n)) { - return -EINVAL; - } - - if (rx->in_use) { - LOG_DBG("Existing RX context. Block 0x%08x", rx->block); - goto found_rx; - } - - if (rx->block == BLOCK_COMPLETE(rx->seg_n)) { - LOG_DBG("Got segment for already complete SDU"); - - send_ack(net_rx->sub, net_rx->ctx.recv_dst, - net_rx->ctx.addr, net_rx->ctx.send_ttl, - seq_auth, rx->block, rx->obo); - - if (rpl) { - bt_mesh_rpl_update(rpl, net_rx); - } - - return -EALREADY; - } - - /* We ignore instead of sending block ack 0 since the - * ack timer is always smaller than the incomplete - * timer, i.e. the sender is misbehaving. - */ - LOG_WRN("Got segment for canceled SDU"); - return -EINVAL; - } - - /* Bail out early if we're not ready to receive such a large SDU */ - if (!sdu_len_is_ok(net_rx->ctl, seg_n)) { - LOG_ERR("Too big incoming SDU length"); - send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, - net_rx->ctx.send_ttl, seq_auth, 0, - net_rx->friend_match); - return -EMSGSIZE; - } - - /* Verify early that there will be space in the Friend Queue(s) in - * case this message is destined to an LPN of ours. - */ - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && - net_rx->friend_match && !net_rx->local_match && - !bt_mesh_friend_queue_has_space(net_rx->sub->net_idx, - net_rx->ctx.addr, - net_rx->ctx.recv_dst, seq_auth, - *seg_count)) { - LOG_ERR("No space in Friend Queue for %u segments", *seg_count); - send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, - net_rx->ctx.send_ttl, seq_auth, 0, - net_rx->friend_match); - return -ENOBUFS; - } - - /* Keep track of the received SeqAuth values received from this address - * and discard segmented messages that are not newer, as described in - * 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 - * comparison check with auth_seqnum: - * - If this is the first time we receive from this source, rpl->src - * will be 0, and we can skip this check. - * - If this is the first time we receive from this source on the new IV - * index, rpl->old_iv will be set, and the check is also skipped. - * - If this is the first segmented message on the new IV index, but we - * have received an unsegmented message already, the unsegmented - * message will have reset rpl->seg to 0, and this message's SeqAuth - * cannot be zero. - */ - if (rpl && rpl->src && auth_seqnum <= rpl->seg && - (!rpl->old_iv || net_rx->old_iv)) { - LOG_WRN("Ignoring old SeqAuth 0x%06x", auth_seqnum); - return -EALREADY; - } - - /* Look for free slot for a new RX session */ - rx = seg_rx_alloc(net_rx, hdr, seq_auth, seg_n); - if (!rx) { - /* Warn but don't cancel since the existing slots will - * eventually be freed up and we'll be able to process - * this one. - */ - LOG_WRN("No free slots for new incoming segmented messages"); - return -ENOMEM; - } - - rx->obo = net_rx->friend_match; - -found_rx: - if (BIT(seg_o) & rx->block) { - LOG_DBG("Received already received fragment"); - return -EALREADY; - } - - /* All segments, except the last one, must either have 8 bytes of - * payload (for 64bit Net MIC) or 12 bytes of payload (for 32bit - * Net MIC). - */ - if (seg_o == seg_n) { - /* Set the expected final buffer length */ - rx->len = seg_n * seg_len(rx->ctl) + buf->len; - LOG_DBG("Target len %u * %u + %u = %u", seg_n, seg_len(rx->ctl), buf->len, rx->len); - - if (rx->len > BT_MESH_RX_SDU_MAX) { - LOG_ERR("Too large SDU len"); - send_ack(net_rx->sub, net_rx->ctx.recv_dst, - net_rx->ctx.addr, net_rx->ctx.send_ttl, - seq_auth, 0, rx->obo); - seg_rx_reset(rx, true); - return -EMSGSIZE; - } - } else { - if (buf->len != seg_len(rx->ctl)) { - LOG_ERR("Incorrect segment size for message type"); - return -EINVAL; - } - } - - /* Reset the Incomplete Timer */ - rx->last = k_uptime_get_32(); - - if (!bt_mesh_lpn_established()) { - int32_t timeout = ack_timeout(rx); - /* Should only start ack timer if it isn't running already: */ - k_work_schedule(&rx->ack, K_MSEC(timeout)); - } - - /* Allocated segment here */ - err = k_mem_slab_alloc(&segs, &rx->seg[seg_o], K_NO_WAIT); - if (err) { - LOG_WRN("Unable allocate buffer for Seg %u", seg_o); - return -ENOBUFS; - } - - memcpy(rx->seg[seg_o], buf->data, buf->len); - - LOG_DBG("Received %u/%u", seg_o, seg_n); - - /* Mark segment as received */ - rx->block |= BIT(seg_o); - - if (rx->block != BLOCK_COMPLETE(seg_n)) { - *pdu_type = BT_MESH_FRIEND_PDU_PARTIAL; - return 0; - } - - LOG_DBG("Complete SDU"); - - if (rpl) { - bt_mesh_rpl_update(rpl, net_rx); - /* Update the seg, unless it has already been surpassed: - * This needs to happen after rpl_update to ensure that the IV - * update reset logic inside rpl_update doesn't overwrite the - * change. - */ - rpl->seg = MAX(rpl->seg, auth_seqnum); - } - - *pdu_type = BT_MESH_FRIEND_PDU_COMPLETE; - - /* If this fails, the work handler will either exit early because the - * block is fully received, or rx->in_use is false. - */ - (void)k_work_cancel_delayable(&rx->ack); - send_ack(net_rx->sub, net_rx->ctx.recv_dst, net_rx->ctx.addr, - net_rx->ctx.send_ttl, seq_auth, rx->block, rx->obo); - - if (net_rx->ctl) { - NET_BUF_SIMPLE_DEFINE(sdu, BT_MESH_RX_CTL_MAX); - seg_rx_assemble(rx, &sdu, 0U); - err = ctl_recv(net_rx, *hdr, &sdu, seq_auth); - } else if (rx->len < 1 + APP_MIC_LEN(ASZMIC(hdr))) { - LOG_ERR("Too short SDU + MIC"); - err = -EINVAL; - } else { - NET_BUF_SIMPLE_DEFINE_STATIC(seg_buf, BT_MESH_RX_SDU_MAX); - struct net_buf_simple sdu; - - /* Decrypting in place to avoid creating two assembly buffers. - * We'll reassemble the buffer from the segments before each - * decryption attempt. - */ - net_buf_simple_init(&seg_buf, 0); - net_buf_simple_init_with_data( - &sdu, seg_buf.data, rx->len - APP_MIC_LEN(ASZMIC(hdr))); - - err = sdu_recv(net_rx, *hdr, ASZMIC(hdr), &seg_buf, &sdu, rx); - } - - seg_rx_reset(rx, false); - - return err; -} - -int bt_mesh_trans_recv(struct net_buf_simple *buf, struct bt_mesh_net_rx *rx) -{ - uint64_t seq_auth = TRANS_SEQ_AUTH_NVAL; - enum bt_mesh_friend_pdu_type pdu_type = BT_MESH_FRIEND_PDU_SINGLE; - struct net_buf_simple_state state; - uint8_t seg_count = 0; - int err; - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND)) { - rx->friend_match = bt_mesh_friend_match(rx->sub->net_idx, - rx->ctx.recv_dst); - } else { - rx->friend_match = false; - } - - LOG_DBG("src 0x%04x dst 0x%04x seq 0x%08x friend_match %u", rx->ctx.addr, rx->ctx.recv_dst, - rx->seq, rx->friend_match); - - /* Remove network headers */ - net_buf_simple_pull(buf, BT_MESH_NET_HDR_LEN); - - LOG_DBG("Payload %s", bt_hex(buf->data, buf->len)); - - if (IS_ENABLED(CONFIG_BT_TESTING)) { - bt_test_mesh_net_recv(rx->ctx.recv_ttl, rx->ctl, rx->ctx.addr, - rx->ctx.recv_dst, buf->data, buf->len); - } - - /* If LPN mode is enabled messages are only accepted when we've - * requested the Friend to send them. The messages must also - * be encrypted using the Friend Credentials. - */ - if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER) && - bt_mesh_lpn_established() && rx->net_if == BT_MESH_NET_IF_ADV && - (!bt_mesh_lpn_waiting_update() || !rx->friend_cred)) { - LOG_WRN("Ignoring unexpected message in Low Power mode"); - return -EAGAIN; - } - - /* Save the app-level state so the buffer can later be placed in - * the Friend Queue. - */ - net_buf_simple_save(buf, &state); - - if (SEG(buf->data)) { - /* Segmented messages must match a local element or an - * LPN of this Friend. - */ - if (!rx->local_match && !rx->friend_match) { - return 0; - } - - err = trans_seg(buf, rx, &pdu_type, &seq_auth, &seg_count); - } else { - seg_count = 1; - err = trans_unseg(buf, rx, &seq_auth); - } - - /* Notify LPN state machine so a Friend Poll will be sent. */ - if (IS_ENABLED(CONFIG_BT_MESH_LOW_POWER)) { - bt_mesh_lpn_msg_received(rx); - } - - net_buf_simple_restore(buf, &state); - - if (IS_ENABLED(CONFIG_BT_MESH_FRIEND) && rx->friend_match && !err) { - if (seq_auth == TRANS_SEQ_AUTH_NVAL) { - bt_mesh_friend_enqueue_rx(rx, pdu_type, NULL, - seg_count, buf); - } else { - bt_mesh_friend_enqueue_rx(rx, pdu_type, &seq_auth, - seg_count, buf); - } - } - - return err; -} - -void bt_mesh_rx_reset(void) -{ - int i; - - LOG_DBG(""); - - for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { - seg_rx_reset(&seg_rx[i], true); - } -} - -void bt_mesh_trans_reset(void) -{ - int i; - - bt_mesh_rx_reset(); - - LOG_DBG(""); - - for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { - seg_tx_reset(&seg_tx[i]); - } - - bt_mesh_rpl_clear(); - bt_mesh_va_clear(); -} - -void bt_mesh_trans_init(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(seg_tx); i++) { - k_work_init_delayable(&seg_tx[i].retransmit, seg_retransmit); - } - - for (i = 0; i < ARRAY_SIZE(seg_rx); i++) { - k_work_init_delayable(&seg_rx[i].ack, seg_ack); - } -} diff --git a/subsys/bluetooth/mesh/va.c b/subsys/bluetooth/mesh/va.c index 6db9194da47..b69c22f40e9 100644 --- a/subsys/bluetooth/mesh/va.c +++ b/subsys/bluetooth/mesh/va.c @@ -306,6 +306,10 @@ void bt_mesh_va_clear(void) { int i; + if (CONFIG_BT_MESH_LABEL_COUNT == 0) { + return; + } + for (i = 0; i < ARRAY_SIZE(virtual_addrs); i++) { if (virtual_addrs[i].ref) { virtual_addrs[i].ref = 0U; diff --git a/subsys/bluetooth/shell/bt.c b/subsys/bluetooth/shell/bt.c index 3f1af44de6f..ac1d78c44df 100644 --- a/subsys/bluetooth/shell/bt.c +++ b/subsys/bluetooth/shell/bt.c @@ -99,10 +99,14 @@ static const char *phy2str(uint8_t phy) { switch (phy) { case 0: return "No packets"; - case BT_GAP_LE_PHY_1M: return "LE 1M"; - case BT_GAP_LE_PHY_2M: return "LE 2M"; - case BT_GAP_LE_PHY_CODED: return "LE Coded"; - default: return "Unknown"; + case BT_GAP_LE_PHY_1M: + return "LE 1M"; + case BT_GAP_LE_PHY_2M: + return "LE 2M"; + case BT_GAP_LE_PHY_CODED: + return "LE Coded"; + default: + return "Unknown"; } } #endif @@ -123,6 +127,67 @@ static void print_le_addr(const char *desc, const bt_addr_le_t *addr) } #endif /* CONFIG_BT_CONN || (CONFIG_BT_BROADCASTER && CONFIG_BT_EXT_ADV) */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +static const char *tx_power_flag2str(int8_t flag) +{ + switch (flag) { + case 0: + return "Neither Max nor Min Tx Power"; + case 1: + return "Tx Power Level is at minimum"; + case 2: + return "Tx Power Level is at maximum"; + /* Current Tx Power Level is the only available one*/ + case 3: + return "Tx Power Level is at minimum & maximum."; + default: + return "Unknown"; + } +} + +static const char *tx_power_report_reason2str(uint8_t reason) +{ + switch (reason) { + case BT_HCI_LE_TX_POWER_REPORT_REASON_LOCAL_CHANGED: + return "Local Tx Power changed"; + case BT_HCI_LE_TX_POWER_REPORT_REASON_REMOTE_CHANGED: + return "Remote Tx Power changed"; + case BT_HCI_LE_TX_POWER_REPORT_REASON_READ_REMOTE_COMPLETED: + return "Completed to read remote Tx Power"; + default: + return "Unknown"; + } +} + +static const char *tx_pwr_ctrl_phy2str(enum bt_conn_le_tx_power_phy phy) +{ + switch (phy) { + case BT_CONN_LE_TX_POWER_PHY_NONE: + return "None"; + case BT_CONN_LE_TX_POWER_PHY_1M: + return "LE 1M"; + case BT_CONN_LE_TX_POWER_PHY_2M: + return "LE 2M"; + case BT_CONN_LE_TX_POWER_PHY_CODED_S8: + return "LE Coded S8"; + case BT_CONN_LE_TX_POWER_PHY_CODED_S2: + return "LE Coded S2"; + default: + return "Unknown"; + } +} + +static const char *enabled2str(bool enabled) +{ + if (enabled) { + return "Enabled"; + } else { + return "Disabled"; + } +} + +#endif /* CONFIG_BT_TRANSMIT_POWER_CONTROL */ + #if defined(CONFIG_BT_CENTRAL) static int cmd_scan_off(const struct shell *sh); static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[]); @@ -809,6 +874,19 @@ void le_phy_updated(struct bt_conn *conn, } #endif +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +void tx_power_report(struct bt_conn *conn, + const struct bt_conn_le_tx_power_report *report) +{ + shell_print(ctx_shell, "Tx Power Report: Reason: %s, PHY: %s, Tx Power Level: %d", + tx_power_report_reason2str(report->reason), tx_pwr_ctrl_phy2str(report->phy), + report->tx_power_level); + shell_print(ctx_shell, "Tx Power Level Flag Info: %s, Delta: %d", + tx_power_flag2str(report->tx_power_level_flag), report->delta); +} +#endif + + static struct bt_conn_cb conn_callbacks = { .connected = connected, .disconnected = disconnected, @@ -829,6 +907,9 @@ static struct bt_conn_cb conn_callbacks = { #if defined(CONFIG_BT_USER_PHY_UPDATE) .le_phy_updated = le_phy_updated, #endif +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + .tx_power_report = tx_power_report, +#endif }; #endif /* CONFIG_BT_CONN */ @@ -2608,6 +2689,102 @@ static int cmd_per_adv_set_info_transfer(const struct shell *sh, size_t argc, } #endif /* CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER && CONFIG_BT_PER_ADV */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) +static int cmd_read_remote_tx_power(const struct shell *sh, size_t argc, char *argv[]) +{ + if (argc < 3) { + int err = 0; + enum bt_conn_le_tx_power_phy phy = strtoul(argv[1], NULL, 16); + + err = bt_conn_le_get_remote_tx_power_level(default_conn, phy); + + if (!err) { + shell_print(sh, "Read Remote TX Power for PHY %s", + tx_pwr_ctrl_phy2str(phy)); + } else { + shell_print(sh, "error %d", err); + } + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + return 0; +} + +static int cmd_read_local_tx_power(const struct shell *sh, size_t argc, char *argv[]) +{ + int err = 0; + + if (argc < 3) { + struct bt_conn_le_tx_power tx_power_level; + + tx_power_level.phy = strtoul(argv[1], NULL, 16); + + int8_t unachievable_current_level = -100; + /* Arbitrary, these are output parameters.*/ + tx_power_level.current_level = unachievable_current_level; + tx_power_level.max_level = 6; + + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + err = bt_conn_le_get_tx_power_level(default_conn, &tx_power_level); + if (err) { + shell_print(sh, "Commad returned error error %d", err); + return err; + } + if (tx_power_level.current_level == unachievable_current_level) { + shell_print(sh, "We received no current tx power level."); + return -EIO; + } + shell_print(sh, "Read local TX Power: current level: %d, PHY: %s, Max Level: %d", + tx_power_level.current_level, + tx_pwr_ctrl_phy2str((enum bt_conn_le_tx_power_phy)tx_power_level.phy), + tx_power_level.max_level); + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + + return err; +} + +static int cmd_set_power_report_enable(const struct shell *sh, size_t argc, char *argv[]) +{ + if (argc < 4) { + int err = 0; + bool local_enable = 0; + bool remote_enable = 0; + + if (*argv[1] == '1') { + local_enable = 1; + } + if (*argv[2] == '1') { + remote_enable = 1; + } + if (default_conn == NULL) { + shell_error(sh, "Conn handle error, at least one connection is required."); + return -ENOEXEC; + } + err = bt_conn_le_set_tx_power_report_enable(default_conn, local_enable, + remote_enable); + if (!err) { + shell_print(sh, "Tx Power Report: local: %s, remote: %s", + enabled2str(local_enable), enabled2str(remote_enable)); + } else { + shell_print(sh, "error %d", err); + } + } else { + shell_help(sh); + return SHELL_CMD_HELP_PRINTED; + } + return 0; +} + +#endif + + #if defined(CONFIG_BT_CONN) #if defined(CONFIG_BT_CENTRAL) static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[]) @@ -4015,6 +4192,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds, cmd_default_handler), SHELL_CMD_ARG(scan-verbose-output, NULL, "", cmd_scan_verbose_output, 2, 0), #endif /* CONFIG_BT_OBSERVER */ +#if defined(CONFIG_BT_TRANSMIT_POWER_CONTROL) + SHELL_CMD_ARG(read-remote-tx-power, NULL, HELP_NONE, cmd_read_remote_tx_power, 2, 0), + SHELL_CMD_ARG(read-local-tx-power, NULL, HELP_NONE, cmd_read_local_tx_power, 2, 0), + SHELL_CMD_ARG(set-power-report-enable, NULL, HELP_NONE, cmd_set_power_report_enable, 3, 0), +#endif #if defined(CONFIG_BT_BROADCASTER) SHELL_CMD_ARG(advertise, NULL, " [mode: discov, non_discov] " @@ -4104,7 +4286,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(bt_cmds, SHELL_CMD_ARG(phy-update, NULL, " [rx_phy] [s2] [s8]", cmd_conn_phy_update, 2, 3), #endif -#if defined(CONFIG_BT_CENTRAL) +#if defined(CONFIG_BT_CENTRAL) || defined(CONFIG_BT_BROADCASTER) SHELL_CMD_ARG(channel-map, NULL, " (36-0)", cmd_chan_map, 2, 1), #endif /* CONFIG_BT_CENTRAL */ 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/fs/nvs/Kconfig b/subsys/fs/nvs/Kconfig index de4f282ee98..df0329a7c41 100644 --- a/subsys/fs/nvs/Kconfig +++ b/subsys/fs/nvs/Kconfig @@ -27,6 +27,15 @@ config NVS_LOOKUP_CACHE_SIZE Number of entries in Non-volatile Storage lookup cache. It is recommended that it be a power of 2. +config NVS_LOOKUP_CACHE_FOR_SETTINGS + bool "Non-volatile Storage lookup cache optimized for settings" + depends on NVS_LOOKUP_CACHE + help + Use the lookup cache hash function that results in the least number of + collissions and, in turn, the best NVS performance provided that the NVS + is used as the settings backend only. This option should NOT be enabled + if the NVS is also written to directly, outside the settings layer. + module = NVS module-str = nvs source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 8c4575700a8..14a4db5e347 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -13,6 +13,11 @@ #include #include "nvs_priv.h" +#ifdef CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS +#include +#include +#endif + #include LOG_MODULE_REGISTER(fs_nvs, CONFIG_NVS_LOG_LEVEL); @@ -21,6 +26,45 @@ static int nvs_ate_valid(struct nvs_fs *fs, const struct nvs_ate *entry); #ifdef CONFIG_NVS_LOOKUP_CACHE +#ifdef CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS + +static inline size_t nvs_lookup_cache_pos(uint16_t id) +{ + /* + * 1. The NVS settings backend uses up to (NVS_NAME_ID_OFFSET - 1) NVS IDs to + store keys and equal number of NVS IDs to store values. + * 2. For each key-value pair, the value is stored at NVS ID greater by exactly + * NVS_NAME_ID_OFFSET than NVS ID that holds the key. + * 3. The backend tries to minimize the range of NVS IDs used to store keys. + * That is, NVS IDs are allocated sequentially, and freed NVS IDs are reused + * before allocating new ones. + * + * Therefore, to assure the least number of collisions in the lookup cache, + * the least significant bit of the hash indicates whether the given NVS ID + * represents a key or a value, and remaining bits of the hash are set to + * the ordinal number of the key-value pair. Consequently, the hash function + * provides the following mapping: + * + * 1st settings key => hash 0 + * 1st settings value => hash 1 + * 2nd settings key => hash 2 + * 2nd settings value => hash 3 + * ... + */ + BUILD_ASSERT(IS_POWER_OF_TWO(NVS_NAMECNT_ID), "NVS_NAMECNT_ID is not power of 2"); + BUILD_ASSERT(IS_POWER_OF_TWO(NVS_NAME_ID_OFFSET), "NVS_NAME_ID_OFFSET is not power of 2"); + + uint16_t key_value_bit; + uint16_t key_value_ord; + + key_value_bit = (id >> LOG2(NVS_NAME_ID_OFFSET)) & 1; + key_value_ord = id & (NVS_NAME_ID_OFFSET - 1); + + return ((key_value_ord << 1) | key_value_bit) % CONFIG_NVS_LOOKUP_CACHE_SIZE; +} + +#else /* CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS */ + static inline size_t nvs_lookup_cache_pos(uint16_t id) { uint16_t hash; @@ -36,6 +80,8 @@ static inline size_t nvs_lookup_cache_pos(uint16_t id) return hash % CONFIG_NVS_LOOKUP_CACHE_SIZE; } +#endif /* CONFIG_NVS_LOOKUP_CACHE_FOR_SETTINGS */ + static int nvs_lookup_cache_rebuild(struct nvs_fs *fs) { int rc; 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 dcbff7b360c..5478ece7ee3 100644 --- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c +++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c @@ -456,6 +456,7 @@ static int deregister_ept(const struct device *instance, void *token) { struct backend_data_t *data = instance->data; struct ipc_rpmsg_ept *rpmsg_ept; + static struct k_work_sync sync; /* Instance is not ready */ if (atomic_get(&data->state) != STATE_INITED) { @@ -469,6 +470,13 @@ static int deregister_ept(const struct device *instance, void *token) return -ENOENT; } + /* Drain pending work items before tearing down channel. + * + * Note: `k_work_flush` Faults on Cortex-M33 with "illegal use of EPSR" + * if `sync` is not declared static. + */ + k_work_flush(&data->mbox_work, &sync); + rpmsg_destroy_ept(&rpmsg_ept->ep); memset(rpmsg_ept, 0, sizeof(struct ipc_rpmsg_ept)); 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 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/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 3d99c8af4fa..8dd5801bc95 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) @@ -261,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; @@ -446,6 +428,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 +567,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", @@ -583,7 +671,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) { @@ -591,7 +679,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; @@ -704,10 +793,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; 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, 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; +} 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 3458c3d6f8b..ae75aea9140 100644 --- a/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/fs_mgmt/src/fs_mgmt.c @@ -783,7 +783,7 @@ static int fs_mgmt_file_hash_checksum(struct smp_streamer *ctxt) } ok &= zcbor_tstr_put_lit(zse, "type") && - zcbor_tstr_put_term(zse, type_arr); + zcbor_tstr_put_term(zse, type_arr, sizeof(type_arr)); if (off != 0) { ok &= zcbor_tstr_put_lit(zse, "off") && 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 300948d5c88..305cad41c44 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -33,6 +33,23 @@ #include #endif +#if USE_PARTITION_MANAGER +#include + +#ifdef PM_MCUBOOT_SECONDARY_PAD_SIZE +BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); +#endif + +#if CONFIG_BUILD_WITH_TFM + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE + PM_TFM_SIZE) +#else + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE) +#endif + +#define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ + (FIXED_PARTITION_OFFSET(label) == (PM_ADDRESS - PM_ADDRESS_OFFSET)) + +#else /* ! USE_PARTITION_MANAGER */ #ifndef CONFIG_FLASH_LOAD_OFFSET #error MCUmgr requires application to be built with CONFIG_FLASH_LOAD_OFFSET set \ to be able to figure out application running slot. @@ -40,6 +57,7 @@ #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ (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"); 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..edfe26e452f 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; } @@ -442,11 +443,11 @@ static bool img_mgmt_state_encode_slot(zcbor_state_t *zse, uint32_t slot, int st ok = zcbor_tstr_put_lit(zse, "<\?\?\?>"); } else { vers_str[sizeof(vers_str) - 1] = '\0'; - ok = zcbor_tstr_put_term(zse, vers_str); + ok = zcbor_tstr_put_term(zse, vers_str, sizeof(vers_str)); } } - ok = ok && zcbor_tstr_put_term(zse, "hash") && + ok = ok && zcbor_tstr_put_lit(zse, "hash") && zcbor_bstr_encode(zse, &zhash) && ZCBOR_ENCODE_FLAG(zse, "bootable", !(flags & IMAGE_F_NON_BOOTABLE)) && ZCBOR_ENCODE_FLAG(zse, "pending", state_flags & REPORT_SLOT_PENDING) && 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..b8cbc38b275 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 @@ -74,7 +74,7 @@ static int image_state_res_fn(struct net_buf *nb, void *user_data) goto out; } - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_start_decode(zsd); if (!ok) { @@ -201,7 +201,7 @@ static int image_upload_res_fn(struct net_buf *nb, void *user_data) goto end; } - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1, NULL, 0); rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); if (rc || image_upload_buf->image_upload_offset == SIZE_MAX) { @@ -233,7 +233,7 @@ static int erase_res_fn(struct net_buf *nb, void *user_data) goto end; } - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1, NULL, 0); rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); if (rc) { 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 13de45f02a9..d5244cb07d8 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt/src/os_mgmt.c @@ -207,7 +207,7 @@ os_mgmt_taskstat_encode_thread_name(zcbor_state_t *zse, int idx, snprintf(thread_name, sizeof(thread_name) - 1, "%d", idx); thread_name[sizeof(thread_name) - 1] = 0; - return zcbor_tstr_put_term(zse, thread_name); + return zcbor_tstr_put_term(zse, thread_name, sizeof(thread_name)); } #endif diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c index 2bd804494c4..0bd174d1c97 100644 --- a/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c @@ -104,7 +104,7 @@ static int echo_res_fn(struct net_buf *nb, void *user_data) } /* Init ZCOR decoder state */ - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, echo_response, ARRAY_SIZE(echo_response), &decoded) == 0; @@ -119,7 +119,7 @@ static int echo_res_fn(struct net_buf *nb, void *user_data) return rc; } -int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string) +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string, size_t max_len) { struct net_buf *nb; int rc; @@ -138,7 +138,8 @@ int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string) zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); ok = zcbor_map_start_encode(zse, 2) && - zcbor_tstr_put_lit(zse, "d") && zcbor_tstr_put_term(zse, echo_string) && + zcbor_tstr_put_lit(zse, "d") && + zcbor_tstr_put_term(zse, echo_string, max_len) && zcbor_map_end_encode(zse, 2); if (!ok) { diff --git a/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig index 757d290d10d..1ab882c33ee 100644 --- a/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/stat_mgmt/Kconfig @@ -28,9 +28,12 @@ config MCUMGR_GRP_STAT_MAX_NAME_LEN depends on MCUMGR_GRP_STAT help Limits the maximum stat group name length in MCUmgr requests, in bytes. - A buffer of this size gets allocated on the stack during handling of all - stat read commands. If a stat group's name exceeds this limit, it will - be impossible to retrieve its values with a stat show command. + For stat group names. a buffer of this size gets allocated on the stack + during handling of all stat read commands. If a stat group's name + exceeds this limit, it will be impossible to retrieve its values with + a stat show command. + For stat names s_name and snm_name, this is the maximum length when + encoding the name to cbor. module = MCUMGR_GRP_STAT module-str = mcumgr_grp_stat diff --git a/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c b/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c index 4740073cf01..29e546bdb86 100644 --- a/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/stat_mgmt/src/stat_mgmt.c @@ -110,7 +110,7 @@ stat_mgmt_foreach_entry(zcbor_state_t *zse, const char *group_name, stat_mgmt_fo static int stat_mgmt_cb_encode(zcbor_state_t *zse, struct stat_mgmt_entry *entry) { - bool ok = zcbor_tstr_put_term(zse, entry->name) && + bool ok = zcbor_tstr_put_term(zse, entry->name, CONFIG_MCUMGR_GRP_STAT_MAX_NAME_LEN) && zcbor_uint32_put(zse, entry->value); return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; @@ -215,7 +215,8 @@ stat_mgmt_list(struct smp_streamer *ctxt) do { cur = stats_group_get_next(cur); if (cur != NULL) { - ok = zcbor_tstr_put_term(zse, cur->s_name); + ok = zcbor_tstr_put_term(zse, cur->s_name, + CONFIG_MCUMGR_GRP_STAT_MAX_NAME_LEN); } } while (ok && cur != NULL); diff --git a/subsys/mgmt/mcumgr/smp/src/smp.c b/subsys/mgmt/mcumgr/smp/src/smp.c index a97beebddaa..902979d9faf 100644 --- a/subsys/mgmt/mcumgr/smp/src/smp.c +++ b/subsys/mgmt/mcumgr/smp/src/smp.c @@ -53,7 +53,7 @@ static void cbor_nb_reader_init(struct cbor_nb_reader *cnr, struct net_buf *nb) { cnr->nb = nb; zcbor_new_decode_state(cnr->zs, ARRAY_SIZE(cnr->zs), nb->data, - nb->len, 1); + nb->len, 1, NULL, 0); } static void cbor_nb_writer_init(struct cbor_nb_writer *cnw, struct net_buf *nb) @@ -125,7 +125,7 @@ static int smp_build_err_rsp(struct smp_streamer *streamer, const struct smp_hdr #ifdef CONFIG_MCUMGR_SMP_VERBOSE_ERR_RESPONSE if (ok && rc_rsn != NULL) { ok = zcbor_tstr_put_lit(zsp, "rsn") && - zcbor_tstr_put_term(zsp, rc_rsn); + zcbor_tstr_put_term(zsp, rc_rsn, CONFIG_ZCBOR_MAX_STR_LEN); } #else ARG_UNUSED(rc_rsn); diff --git a/subsys/modem/backends/modem_backend_tty.c b/subsys/modem/backends/modem_backend_tty.c index b8864fc3d91..e511150ae9d 100644 --- a/subsys/modem/backends/modem_backend_tty.c +++ b/subsys/modem/backends/modem_backend_tty.c @@ -7,7 +7,7 @@ #include #include -LOG_MODULE_REGISTER(modem_backend_tty); +LOG_MODULE_REGISTER(modem_backend_tty, CONFIG_MODEM_MODULES_LOG_LEVEL); #include #include @@ -73,8 +73,11 @@ static int modem_backend_tty_open(void *data) static int modem_backend_tty_transmit(void *data, const uint8_t *buf, size_t size) { struct modem_backend_tty *backend = (struct modem_backend_tty *)data; + int ret; - return write(backend->tty_fd, buf, size); + ret = write(backend->tty_fd, buf, size); + modem_pipe_notify_transmit_idle(&backend->pipe); + return ret; } static int modem_backend_tty_receive(void *data, uint8_t *buf, size_t size) diff --git a/subsys/modem/backends/modem_backend_uart.c b/subsys/modem/backends/modem_backend_uart.c index b4b0b81c291..b77a7331899 100644 --- a/subsys/modem/backends/modem_backend_uart.c +++ b/subsys/modem/backends/modem_backend_uart.c @@ -10,7 +10,7 @@ #include #include -LOG_MODULE_REGISTER(modem_backend_uart); +LOG_MODULE_REGISTER(modem_backend_uart, CONFIG_MODEM_MODULES_LOG_LEVEL); #include @@ -22,6 +22,14 @@ static void modem_backend_uart_receive_ready_handler(struct k_work *item) modem_pipe_notify_receive_ready(&backend->pipe); } +static void modem_backend_uart_transmit_idle_handler(struct k_work *item) +{ + struct modem_backend_uart *backend = + CONTAINER_OF(item, struct modem_backend_uart, transmit_idle_work); + + modem_pipe_notify_transmit_idle(&backend->pipe); +} + struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend, const struct modem_backend_uart_config *config) { @@ -35,6 +43,7 @@ struct modem_pipe *modem_backend_uart_init(struct modem_backend_uart *backend, memset(backend, 0x00, sizeof(*backend)); backend->uart = config->uart; k_work_init(&backend->receive_ready_work, modem_backend_uart_receive_ready_handler); + k_work_init(&backend->transmit_idle_work, modem_backend_uart_transmit_idle_handler); #ifdef CONFIG_MODEM_BACKEND_UART_ASYNC if (modem_backend_uart_async_is_supported(backend)) { diff --git a/subsys/modem/backends/modem_backend_uart_async.c b/subsys/modem/backends/modem_backend_uart_async.c index bd18edbd2f5..0fa3684780e 100644 --- a/subsys/modem/backends/modem_backend_uart_async.c +++ b/subsys/modem/backends/modem_backend_uart_async.c @@ -7,17 +7,20 @@ #include "modem_backend_uart_async.h" #include -LOG_MODULE_DECLARE(modem_backend_uart); +LOG_MODULE_DECLARE(modem_backend_uart, CONFIG_MODEM_MODULES_LOG_LEVEL); #include #include -#define MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT (0) -#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) +enum { + MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT, + MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT, + MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF0_USED_BIT, + MODEM_BACKEND_UART_ASYNC_STATE_RX_BUF1_USED_BIT, + MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT, +}; -static bool modem_backend_uart_async_is_closed(struct modem_backend_uart *backend) +static bool modem_backend_uart_async_is_uart_stopped(struct modem_backend_uart *backend) { if (!atomic_test_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT) && @@ -33,6 +36,12 @@ static bool modem_backend_uart_async_is_closed(struct modem_backend_uart *backen return false; } +static bool modem_backend_uart_async_is_open(struct modem_backend_uart *backend) +{ + return atomic_test_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT); +} + static void modem_backend_uart_async_event_handler(const struct device *dev, struct uart_event *evt, void *user_data) { @@ -44,13 +53,17 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, case UART_TX_DONE: atomic_clear_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT); + k_work_submit(&backend->transmit_idle_work); break; case UART_TX_ABORTED: - LOG_WRN("Transmit aborted"); + if (modem_backend_uart_async_is_open(backend)) { + LOG_WRN("Transmit aborted (%zu sent)", evt->data.tx.len); + } atomic_clear_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_TRANSMITTING_BIT); + k_work_submit(&backend->transmit_idle_work); break; @@ -101,7 +114,8 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, if (received < evt->data.rx.len) { ring_buf_reset(&backend->async.receive_rb); k_spin_unlock(&backend->async.receive_rb_lock, key); - LOG_WRN("Receive buffer overrun"); + LOG_WRN("Receive buffer overrun (%u/%u dropped)", + evt->data.rx.len - received, evt->data.rx.len); break; } @@ -122,7 +136,7 @@ static void modem_backend_uart_async_event_handler(const struct device *dev, break; } - if (modem_backend_uart_async_is_closed(backend)) { + if (modem_backend_uart_async_is_uart_stopped(backend)) { k_work_submit(&backend->async.rx_disabled_work); } } @@ -153,6 +167,8 @@ static int modem_backend_uart_async_open(void *data) atomic_set_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_RECEIVING_BIT); + atomic_set_bit(&backend->async.state, + MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT); modem_pipe_notify_opened(&backend->pipe); return 0; @@ -183,8 +199,9 @@ static int modem_backend_uart_async_transmit(void *data, const uint8_t *buf, siz ret = uart_tx(backend->uart, backend->async.transmit_buf, bytes_to_transmit, CONFIG_MODEM_BACKEND_UART_ASYNC_TRANSMIT_TIMEOUT_MS * 1000L); - if (ret < 0) { - LOG_WRN("Failed to start async transmit"); + if (ret != 0) { + LOG_ERR("Failed to %s %u bytes. (%d)", + "start async transmit for", bytes_to_transmit, ret); return ret; } @@ -214,6 +231,7 @@ static int modem_backend_uart_async_close(void *data) { struct modem_backend_uart *backend = (struct modem_backend_uart *)data; + atomic_clear_bit(&backend->async.state, MODEM_BACKEND_UART_ASYNC_STATE_OPEN_BIT); uart_tx_abort(backend->uart); uart_rx_disable(backend->uart); return 0; diff --git a/subsys/modem/backends/modem_backend_uart_isr.c b/subsys/modem/backends/modem_backend_uart_isr.c index 7c88cb4673c..9eed7913496 100644 --- a/subsys/modem/backends/modem_backend_uart_isr.c +++ b/subsys/modem/backends/modem_backend_uart_isr.c @@ -7,7 +7,7 @@ #include "modem_backend_uart_isr.h" #include -LOG_MODULE_DECLARE(modem_backend_uart); +LOG_MODULE_DECLARE(modem_backend_uart, CONFIG_MODEM_MODULES_LOG_LEVEL); #include @@ -56,6 +56,7 @@ static void modem_backend_uart_isr_irq_handler_transmit_ready(struct modem_backe if (ring_buf_is_empty(&backend->isr.transmit_rb) == true) { uart_irq_tx_disable(backend->uart); + k_work_submit(&backend->transmit_idle_work); return; } diff --git a/subsys/modem/modem_chat.c b/subsys/modem/modem_chat.c index 0ab1175f980..c689ff2e0ab 100644 --- a/subsys/modem/modem_chat.c +++ b/subsys/modem/modem_chat.c @@ -60,7 +60,7 @@ 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) { + if ((chat == NULL) || (chat->script == NULL)) { return; } @@ -78,6 +78,14 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri chat->script->callback(chat, result, chat->user_data); } + /* Clear parse_match in case it is stored in the script being stopped */ + if ((chat->parse_match != NULL) && + ((chat->parse_match_type == MODEM_CHAT_MATCHES_INDEX_ABORT) || + (chat->parse_match_type == MODEM_CHAT_MATCHES_INDEX_RESPONSE))) { + chat->parse_match = NULL; + chat->parse_match_len = 0; + } + /* Clear reference to script */ chat->script = NULL; @@ -87,8 +95,10 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = NULL; chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = 0; - /* Cancel timeout work */ + /* Cancel work */ k_work_cancel_delayable(&chat->script_timeout_work); + k_work_cancel(&chat->script_send_work); + k_work_cancel_delayable(&chat->script_send_timeout_work); /* Clear script running state */ atomic_clear_bit(&chat->script_state, MODEM_CHAT_SCRIPT_STATE_RUNNING_BIT); @@ -100,14 +110,32 @@ static void modem_chat_script_stop(struct modem_chat *chat, enum modem_chat_scri k_sem_give(&chat->script_stopped_sem); } +static void modem_chat_set_script_send_state(struct modem_chat *chat, + enum modem_chat_script_send_state state) +{ + chat->script_send_pos = 0; + chat->script_send_state = state; +} + static void modem_chat_script_send(struct modem_chat *chat) { - /* Initialize script send work */ - chat->script_send_request_pos = 0; - chat->script_send_delimiter_pos = 0; + modem_chat_set_script_send_state(chat, MODEM_CHAT_SCRIPT_SEND_STATE_REQUEST); + k_work_submit(&chat->script_send_work); +} + +static void modem_chat_script_set_response_matches(struct modem_chat *chat) +{ + const struct modem_chat_script_chat *script_chat = + &chat->script->script_chats[chat->script_chat_it]; - /* Schedule script send work */ - k_work_schedule(&chat->script_send_work, K_NO_WAIT); + chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = script_chat->response_matches; + chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = script_chat->response_matches_size; +} + +static void modem_chat_script_clear_response_matches(struct modem_chat *chat) +{ + chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = NULL; + chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = 0; } static void modem_chat_script_next(struct modem_chat *chat, bool initial) @@ -134,14 +162,13 @@ static void modem_chat_script_next(struct modem_chat *chat, bool initial) script_chat = &chat->script->script_chats[chat->script_chat_it]; - /* Set response command handlers */ - chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = script_chat->response_matches; - chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = script_chat->response_matches_size; - - /* Check if work must be sent */ + /* Check if request must be sent */ if (script_chat->request_size > 0) { LOG_DBG("sending: %.*s", script_chat->request_size, script_chat->request); + modem_chat_script_clear_response_matches(chat); modem_chat_script_send(chat); + } else { + modem_chat_script_set_response_matches(chat); } } @@ -195,125 +222,99 @@ static void modem_chat_script_abort_handler(struct k_work *item) modem_chat_script_stop(chat, MODEM_CHAT_SCRIPT_RESULT_ABORT); } -static bool modem_chat_script_send_request(struct modem_chat *chat) +static bool modem_chat_script_chat_is_no_response(struct modem_chat *chat) { const struct modem_chat_script_chat *script_chat = &chat->script->script_chats[chat->script_chat_it]; - 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) { - 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; - - /* Send data through pipe */ - ret = modem_pipe_transmit(chat->pipe, script_chat_request_start, - script_chat_request_remaining); - - /* Validate transmit successful */ - if (ret < 1) { - return false; - } - - /* Update script send position */ - chat->script_send_request_pos += (uint16_t)ret; + return (script_chat->response_matches_size == 0) ? true : false; +} - /* Check if data remains */ - if (chat->script_send_request_pos < script_chat->request_size) { - return false; - } +static uint16_t modem_chat_script_chat_get_send_timeout(struct modem_chat *chat) +{ + const struct modem_chat_script_chat *script_chat = + &chat->script->script_chats[chat->script_chat_it]; - return true; + return script_chat->timeout; } -static bool modem_chat_script_send_delimiter(struct modem_chat *chat) +/* Returns true when request part has been sent */ +static bool modem_chat_send_script_request_part(struct modem_chat *chat) { - uint8_t *script_chat_delimiter_start; - uint8_t script_chat_delimiter_remaining; - int ret; + const struct modem_chat_script_chat *script_chat = + &chat->script->script_chats[chat->script_chat_it]; - /* Validate data to send */ - if (chat->delimiter_size == chat->script_send_delimiter_pos) { - return true; - } + uint8_t *request_part; + uint16_t request_size; + uint16_t request_part_size; + int ret; - script_chat_delimiter_start = (uint8_t *)&chat->delimiter[chat->script_send_delimiter_pos]; - script_chat_delimiter_remaining = chat->delimiter_size - chat->script_send_delimiter_pos; + switch (chat->script_send_state) { + case MODEM_CHAT_SCRIPT_SEND_STATE_REQUEST: + request_part = (uint8_t *)(&script_chat->request[chat->script_send_pos]); + request_size = script_chat->request_size; + break; - /* Send data through pipe */ - ret = modem_pipe_transmit(chat->pipe, script_chat_delimiter_start, - script_chat_delimiter_remaining); + case MODEM_CHAT_SCRIPT_SEND_STATE_DELIMITER: + request_part = (uint8_t *)(&chat->delimiter[chat->script_send_pos]); + request_size = chat->delimiter_size; + break; - /* Validate transmit successful */ - if (ret < 1) { + default: return false; } - /* Update script send position */ - chat->script_send_delimiter_pos += (uint8_t)ret; - - /* Check if data remains */ - if (chat->script_send_delimiter_pos < chat->delimiter_size) { + request_part_size = request_size - chat->script_send_pos; + ret = modem_pipe_transmit(chat->pipe, request_part, request_part_size); + if (ret < 1) { return false; } - return true; -} + chat->script_send_pos += (uint16_t)ret; -static bool modem_chat_script_chat_is_no_response(struct modem_chat *chat) -{ - const struct modem_chat_script_chat *script_chat = - &chat->script->script_chats[chat->script_chat_it]; - - return (script_chat->response_matches_size == 0) ? true : false; -} - -static uint16_t modem_chat_script_chat_get_send_timeout(struct modem_chat *chat) -{ - const struct modem_chat_script_chat *script_chat = - &chat->script->script_chats[chat->script_chat_it]; - - return script_chat->timeout; + /* Return true if all data was sent */ + return request_size <= chat->script_send_pos; } static void modem_chat_script_send_handler(struct k_work *item) { - struct k_work_delayable *dwork = k_work_delayable_from_work(item); - struct modem_chat *chat = CONTAINER_OF(dwork, struct modem_chat, script_send_work); + struct modem_chat *chat = CONTAINER_OF(item, struct modem_chat, script_send_work); uint16_t timeout; - /* Validate script running */ if (chat->script == NULL) { return; } - /* Send request */ - if (modem_chat_script_send_request(chat) == false) { - k_work_schedule(&chat->script_send_work, chat->process_timeout); + switch (chat->script_send_state) { + case MODEM_CHAT_SCRIPT_SEND_STATE_IDLE: return; - } - /* Send delimiter */ - if (modem_chat_script_send_delimiter(chat) == false) { - k_work_schedule(&chat->script_send_work, chat->process_timeout); - return; + case MODEM_CHAT_SCRIPT_SEND_STATE_REQUEST: + if (!modem_chat_send_script_request_part(chat)) { + return; + } + + modem_chat_set_script_send_state(chat, MODEM_CHAT_SCRIPT_SEND_STATE_DELIMITER); + __fallthrough; + + case MODEM_CHAT_SCRIPT_SEND_STATE_DELIMITER: + if (!modem_chat_send_script_request_part(chat)) { + return; + } + + modem_chat_set_script_send_state(chat, MODEM_CHAT_SCRIPT_SEND_STATE_IDLE); + break; } - /* Check if script command is no response */ if (modem_chat_script_chat_is_no_response(chat)) { timeout = modem_chat_script_chat_get_send_timeout(chat); - if (timeout == 0) { modem_chat_script_next(chat, false); } else { k_work_schedule(&chat->script_send_timeout_work, K_MSEC(timeout)); } + } else { + modem_chat_script_set_response_matches(chat); } } @@ -661,8 +662,7 @@ static void modem_chat_process_bytes(struct modem_chat *chat) static void modem_chat_process_handler(struct k_work *item) { - struct k_work_delayable *dwork = k_work_delayable_from_work(item); - struct modem_chat *chat = CONTAINER_OF(dwork, struct modem_chat, process_work); + struct modem_chat *chat = CONTAINER_OF(item, struct modem_chat, receive_work); int ret; /* Fill work buffer */ @@ -676,7 +676,7 @@ static void modem_chat_process_handler(struct k_work *item) /* Process data */ modem_chat_process_bytes(chat); - k_work_schedule(&chat->process_work, K_NO_WAIT); + k_work_submit(&chat->receive_work); } static void modem_chat_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_event event, @@ -684,8 +684,17 @@ static void modem_chat_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_ev { struct modem_chat *chat = (struct modem_chat *)user_data; - if (event == MODEM_PIPE_EVENT_RECEIVE_READY) { - k_work_schedule(&chat->process_work, chat->process_timeout); + switch (event) { + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_work_submit(&chat->receive_work); + break; + + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + k_work_submit(&chat->script_send_work); + break; + + default: + break; } } @@ -699,7 +708,7 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con __ASSERT_NO_MSG(config->argv_size > 0); __ASSERT_NO_MSG(config->delimiter != NULL); __ASSERT_NO_MSG(config->delimiter_size > 0); - __ASSERT_NO_MSG(!((config->filter == NULL) && (config->filter > 0))); + __ASSERT_NO_MSG(!((config->filter == NULL) && (config->filter_size > 0))); __ASSERT_NO_MSG(!((config->unsol_matches == NULL) && (config->unsol_matches_size > 0))); memset(chat, 0x00, sizeof(*chat)); @@ -715,14 +724,13 @@ int modem_chat_init(struct modem_chat *chat, const struct modem_chat_config *con chat->filter_size = config->filter_size; chat->matches[MODEM_CHAT_MATCHES_INDEX_UNSOL] = config->unsol_matches; 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->receive_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); k_work_init(&chat->script_abort_work, modem_chat_script_abort_handler); - k_work_init_delayable(&chat->script_send_work, modem_chat_script_send_handler); + k_work_init(&chat->script_send_work, modem_chat_script_send_handler); k_work_init_delayable(&chat->script_send_timeout_work, modem_chat_script_send_timeout_handler); @@ -805,8 +813,8 @@ void modem_chat_release(struct modem_chat *chat) k_work_cancel_sync(&chat->script_run_work, &sync); k_work_cancel_sync(&chat->script_abort_work, &sync); - k_work_cancel_delayable_sync(&chat->process_work, &sync); - k_work_cancel_delayable_sync(&chat->script_send_work, &sync); + k_work_cancel_sync(&chat->receive_work, &sync); + k_work_cancel_sync(&chat->script_send_work, &sync); chat->pipe = NULL; chat->receive_buf_len = 0; @@ -817,9 +825,13 @@ void modem_chat_release(struct modem_chat *chat) 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->script_send_state = MODEM_CHAT_SCRIPT_SEND_STATE_IDLE; + chat->script_send_pos = 0; chat->parse_match = NULL; chat->parse_match_len = 0; chat->parse_arg_len = 0; + chat->matches[MODEM_CHAT_MATCHES_INDEX_ABORT] = NULL; + chat->matches_size[MODEM_CHAT_MATCHES_INDEX_ABORT] = 0; + chat->matches[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = NULL; + chat->matches_size[MODEM_CHAT_MATCHES_INDEX_RESPONSE] = 0; } diff --git a/subsys/modem/modem_cmux.c b/subsys/modem/modem_cmux.c index 9c95e124fc2..67190934c45 100644 --- a/subsys/modem/modem_cmux.c +++ b/subsys/modem/modem_cmux.c @@ -197,65 +197,72 @@ static void modem_cmux_bus_callback(struct modem_pipe *pipe, enum modem_pipe_eve { struct modem_cmux *cmux = (struct modem_cmux *)user_data; - if (event == MODEM_PIPE_EVENT_RECEIVE_READY) { + switch (event) { + case MODEM_PIPE_EVENT_RECEIVE_READY: k_work_schedule(&cmux->receive_work, K_NO_WAIT); + break; + + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + k_work_schedule(&cmux->transmit_work, K_NO_WAIT); + break; + + default: + break; } } static uint16_t modem_cmux_transmit_frame(struct modem_cmux *cmux, const struct modem_cmux_frame *frame) { - uint8_t byte; + uint8_t buf[MODEM_CMUX_FRAME_SIZE_MAX]; uint8_t fcs; uint16_t space; uint16_t data_len; + uint16_t buf_idx; space = ring_buf_space_get(&cmux->transmit_rb) - MODEM_CMUX_FRAME_SIZE_MAX; - data_len = (space < frame->data_len) ? space : frame->data_len; + data_len = MIN(space, frame->data_len); /* SOF */ - byte = 0xF9; - ring_buf_put(&cmux->transmit_rb, &byte, 1); + buf[0] = 0xF9; /* DLCI Address (Max 63) */ - byte = 0x01 | (frame->cr << 1) | (frame->dlci_address << 2); - fcs = crc8(&byte, 1, MODEM_CMUX_FCS_POLYNOMIAL, MODEM_CMUX_FCS_INIT_VALUE, true); - ring_buf_put(&cmux->transmit_rb, &byte, 1); + buf[1] = 0x01 | (frame->cr << 1) | (frame->dlci_address << 2); /* Frame type and poll/final */ - byte = frame->type | (frame->pf << 4); - fcs = crc8(&byte, 1, MODEM_CMUX_FCS_POLYNOMIAL, fcs, true); - ring_buf_put(&cmux->transmit_rb, &byte, 1); + buf[2] = frame->type | (frame->pf << 4); /* Data length */ if (data_len > 127) { - byte = data_len << 1; - fcs = crc8(&byte, 1, MODEM_CMUX_FCS_POLYNOMIAL, fcs, true); - ring_buf_put(&cmux->transmit_rb, &byte, 1); - byte = 0x01 | (data_len >> 7); - ring_buf_put(&cmux->transmit_rb, &byte, 1); + buf[3] = data_len << 1; + buf[4] = data_len >> 7; + buf_idx = 5; } else { - byte = 0x01 | (data_len << 1); - ring_buf_put(&cmux->transmit_rb, &byte, 1); + buf[3] = 0x01 | (data_len << 1); + buf_idx = 4; } + /* Compute FCS for the header (exclude SOF) */ + fcs = crc8(&buf[1], (buf_idx - 1), MODEM_CMUX_FCS_POLYNOMIAL, MODEM_CMUX_FCS_INIT_VALUE, + true); + /* FCS final */ if (frame->type == MODEM_CMUX_FRAME_TYPE_UIH) { - fcs = 0xFF - crc8(&byte, 1, MODEM_CMUX_FCS_POLYNOMIAL, fcs, true); + fcs = 0xFF - fcs; } else { - fcs = crc8(&byte, 1, MODEM_CMUX_FCS_POLYNOMIAL, fcs, true); fcs = 0xFF - crc8(frame->data, data_len, MODEM_CMUX_FCS_POLYNOMIAL, fcs, true); } + /* Frame header */ + ring_buf_put(&cmux->transmit_rb, buf, buf_idx); + /* Data */ ring_buf_put(&cmux->transmit_rb, frame->data, data_len); - /* FCS */ - ring_buf_put(&cmux->transmit_rb, &fcs, 1); - - /* EOF */ - byte = 0xF9; - ring_buf_put(&cmux->transmit_rb, &byte, 1); + /* FCS and EOF will be put on the same call */ + buf[0] = fcs; + buf[1] = 0xF9; + ring_buf_put(&cmux->transmit_rb, buf, 2); k_work_schedule(&cmux->transmit_work, K_NO_WAIT); return data_len; } @@ -340,9 +347,11 @@ static void modem_cmux_acknowledge_received_frame(struct modem_cmux *cmux) } } -static void modem_cmux_on_msc_command(struct modem_cmux *cmux) +static void modem_cmux_on_msc_command(struct modem_cmux *cmux, struct modem_cmux_command *command) { - modem_cmux_acknowledge_received_frame(cmux); + if (command->type.cr) { + modem_cmux_acknowledge_received_frame(cmux); + } } static void modem_cmux_on_fcon_command(struct modem_cmux *cmux) @@ -361,17 +370,27 @@ static void modem_cmux_on_fcoff_command(struct modem_cmux *cmux) modem_cmux_acknowledge_received_frame(cmux); } -static void modem_cmux_on_cld_command(struct modem_cmux *cmux) +static void modem_cmux_on_cld_command(struct modem_cmux *cmux, struct modem_cmux_command *command) { - if (cmux->state != MODEM_CMUX_STATE_DISCONNECTING) { + if (command->type.cr) { + modem_cmux_acknowledge_received_frame(cmux); + } + + if (cmux->state != MODEM_CMUX_STATE_DISCONNECTING && + cmux->state != MODEM_CMUX_STATE_CONNECTED) { LOG_WRN("Unexpected close down"); + return; + } + + if (cmux->state == MODEM_CMUX_STATE_DISCONNECTING) { + k_work_cancel_delayable(&cmux->disconnect_work); } cmux->state = MODEM_CMUX_STATE_DISCONNECTED; k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); cmux->flow_control_on = false; k_mutex_unlock(&cmux->transmit_rb_lock); - k_work_cancel_delayable(&cmux->disconnect_work); + modem_cmux_raise_event(cmux, MODEM_CMUX_EVENT_DISCONNECTED); k_event_clear(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT); k_event_post(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT); @@ -381,7 +400,6 @@ static void modem_cmux_on_control_frame_ua(struct modem_cmux *cmux) { if (cmux->state != MODEM_CMUX_STATE_CONNECTING) { LOG_DBG("Unexpected UA frame"); - return; } @@ -414,11 +432,11 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux) switch (command->type.value) { case MODEM_CMUX_COMMAND_CLD: - modem_cmux_on_cld_command(cmux); + modem_cmux_on_cld_command(cmux, command); break; case MODEM_CMUX_COMMAND_MSC: - modem_cmux_on_msc_command(cmux); + modem_cmux_on_msc_command(cmux, command); break; case MODEM_CMUX_COMMAND_FCON: @@ -435,6 +453,40 @@ static void modem_cmux_on_control_frame_uih(struct modem_cmux *cmux) } } +static void modem_cmux_connect_response_transmit(struct modem_cmux *cmux) +{ + struct modem_cmux_frame frame = { + .dlci_address = cmux->frame.dlci_address, + .cr = cmux->frame.cr, + .pf = cmux->frame.pf, + .type = MODEM_CMUX_FRAME_TYPE_UA, + .data = NULL, + .data_len = 0, + }; + + LOG_DBG("SABM/DISC request state send ack"); + modem_cmux_transmit_cmd_frame(cmux, &frame); +} + +static void modem_cmux_on_control_frame_sabm(struct modem_cmux *cmux) +{ + modem_cmux_connect_response_transmit(cmux); + + if ((cmux->state == MODEM_CMUX_STATE_CONNECTED) || + (cmux->state == MODEM_CMUX_STATE_DISCONNECTING)) { + LOG_DBG("Connect request not accepted"); + return; + } + + cmux->state = MODEM_CMUX_STATE_CONNECTED; + k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); + cmux->flow_control_on = true; + k_mutex_unlock(&cmux->transmit_rb_lock); + modem_cmux_raise_event(cmux, MODEM_CMUX_EVENT_CONNECTED); + k_event_clear(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT); + k_event_post(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT); +} + static void modem_cmux_on_control_frame(struct modem_cmux *cmux) { modem_cmux_log_received_frame(&cmux->frame); @@ -448,6 +500,10 @@ static void modem_cmux_on_control_frame(struct modem_cmux *cmux) modem_cmux_on_control_frame_uih(cmux); break; + case MODEM_CMUX_FRAME_TYPE_SABM: + modem_cmux_on_control_frame_sabm(cmux); + break; + default: LOG_WRN("Unknown %s frame type", "control"); break; @@ -497,6 +553,7 @@ static void modem_cmux_on_dlci_frame_ua(struct modem_cmux_dlci *dlci) static void modem_cmux_on_dlci_frame_uih(struct modem_cmux_dlci *dlci) { struct modem_cmux *cmux = dlci->cmux; + uint32_t written; if (dlci->state != MODEM_CMUX_DLCI_STATE_OPEN) { LOG_DBG("Unexpected UIH frame"); @@ -504,25 +561,61 @@ static void modem_cmux_on_dlci_frame_uih(struct modem_cmux_dlci *dlci) } k_mutex_lock(&dlci->receive_rb_lock, K_FOREVER); - ring_buf_put(&dlci->receive_rb, cmux->frame.data, cmux->frame.data_len); + written = ring_buf_put(&dlci->receive_rb, cmux->frame.data, cmux->frame.data_len); k_mutex_unlock(&dlci->receive_rb_lock); + if (written != cmux->frame.data_len) { + LOG_WRN("DLCI %u receive buffer overrun (dropped %u out of %u bytes)", + dlci->dlci_address, cmux->frame.data_len - written, cmux->frame.data_len); + } modem_pipe_notify_receive_ready(&dlci->pipe); } -static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) +static void modem_cmux_on_dlci_frame_sabm(struct modem_cmux_dlci *dlci) { - struct modem_cmux_dlci *dlci; + struct modem_cmux *cmux = dlci->cmux; - dlci = modem_cmux_find_dlci(cmux); + modem_cmux_connect_response_transmit(cmux); - if (dlci == NULL) { - LOG_WRN("Could not find DLCI: %u", cmux->frame.dlci_address); + if (dlci->state == MODEM_CMUX_DLCI_STATE_OPEN) { + LOG_DBG("Unexpected SABM frame"); + return; + } + + dlci->state = MODEM_CMUX_DLCI_STATE_OPEN; + modem_pipe_notify_opened(&dlci->pipe); + k_mutex_lock(&dlci->receive_rb_lock, K_FOREVER); + ring_buf_reset(&dlci->receive_rb); + k_mutex_unlock(&dlci->receive_rb_lock); +} + +static void modem_cmux_on_dlci_frame_disc(struct modem_cmux_dlci *dlci) +{ + struct modem_cmux *cmux = dlci->cmux; + + modem_cmux_connect_response_transmit(cmux); + if (dlci->state != MODEM_CMUX_DLCI_STATE_OPEN) { + LOG_DBG("Unexpected Disc frame"); return; } + dlci->state = MODEM_CMUX_DLCI_STATE_CLOSED; + modem_pipe_notify_closed(&dlci->pipe); +} + +static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) +{ + struct modem_cmux_dlci *dlci; + modem_cmux_log_received_frame(&cmux->frame); + dlci = modem_cmux_find_dlci(cmux); + if (dlci == NULL) { + LOG_WRN("Ignoring frame intended for unconfigured DLCI %u.", + cmux->frame.dlci_address); + return; + } + switch (cmux->frame.type) { case MODEM_CMUX_FRAME_TYPE_UA: modem_cmux_on_dlci_frame_ua(dlci); @@ -532,6 +625,14 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux) modem_cmux_on_dlci_frame_uih(dlci); break; + case MODEM_CMUX_FRAME_TYPE_SABM: + modem_cmux_on_dlci_frame_sabm(dlci); + break; + + case MODEM_CMUX_FRAME_TYPE_DISC: + modem_cmux_on_dlci_frame_disc(dlci); + break; + default: LOG_WRN("Unknown %s frame type", "DLCI"); break; @@ -542,61 +643,35 @@ static void modem_cmux_on_frame(struct modem_cmux *cmux) { if (cmux->frame.dlci_address == 0) { modem_cmux_on_control_frame(cmux); - return; + } else { + modem_cmux_on_dlci_frame(cmux); } - - modem_cmux_on_dlci_frame(cmux); } static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t byte) { uint8_t fcs; - static const uint8_t resync[3] = {0xF9, 0xF9, 0xF9}; switch (cmux->receive_state) { case MODEM_CMUX_RECEIVE_STATE_SOF: if (byte == 0xF9) { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_ADDRESS; + cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC; break; } - /* Send resync flags */ - modem_pipe_transmit(cmux->pipe, resync, sizeof(resync)); - - /* Await resync flags */ - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_0; break; - case MODEM_CMUX_RECEIVE_STATE_RESYNC_0: - if (byte == 0xF9) { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_1; - } - - break; - - case MODEM_CMUX_RECEIVE_STATE_RESYNC_1: - if (byte == 0xF9) { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_2; - } else { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_0; - } - - break; - - case MODEM_CMUX_RECEIVE_STATE_RESYNC_2: - if (byte == 0xF9) { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_3; - } else { - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_RESYNC_0; - } - - break; - - case MODEM_CMUX_RECEIVE_STATE_RESYNC_3: + case MODEM_CMUX_RECEIVE_STATE_RESYNC: + /* + * Allow any number of consequtive flags (0xF9). + * 0xF9 could also be a valid address field for DLCI 62. + */ if (byte == 0xF9) { break; } + __fallthrough; + case MODEM_CMUX_RECEIVE_STATE_ADDRESS: /* Initialize */ cmux->receive_buf_len = 0; @@ -671,28 +746,27 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by case MODEM_CMUX_RECEIVE_STATE_DATA: /* Copy byte to data */ - cmux->receive_buf[cmux->receive_buf_len] = byte; + if (cmux->receive_buf_len < cmux->receive_buf_size) { + cmux->receive_buf[cmux->receive_buf_len] = byte; + } cmux->receive_buf_len++; /* Check if datalen reached */ if (cmux->frame.data_len == cmux->receive_buf_len) { /* Await FCS */ cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_FCS; - break; } - /* Check if receive buffer overrun */ - if (cmux->receive_buf_len == cmux->receive_buf_size) { - LOG_WRN("Receive buf overrun"); + break; - /* Drop frame */ - cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_EOF; + case MODEM_CMUX_RECEIVE_STATE_FCS: + if (cmux->receive_buf_len > cmux->receive_buf_size) { + LOG_WRN("Receive buffer overrun (%u > %u)", + cmux->receive_buf_len, cmux->receive_buf_size); + cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_DROP; break; } - break; - - case MODEM_CMUX_RECEIVE_STATE_FCS: /* Compute FCS */ if (cmux->frame.type == MODEM_CMUX_FRAME_TYPE_UIH) { fcs = 0xFF - crc8(cmux->frame_header, cmux->frame_header_len, @@ -754,6 +828,9 @@ static void modem_cmux_receive_handler(struct k_work *item) /* Receive data from pipe */ ret = modem_pipe_receive(cmux->pipe, buf, sizeof(buf)); if (ret < 1) { + if (ret < 0) { + LOG_ERR("Pipe receiving error: %d", ret); + } return; } @@ -766,6 +843,17 @@ static void modem_cmux_receive_handler(struct k_work *item) k_work_schedule(&cmux->receive_work, K_NO_WAIT); } +static void modem_cmux_dlci_notify_transmit_idle(struct modem_cmux *cmux) +{ + sys_snode_t *node; + struct modem_cmux_dlci *dlci; + + SYS_SLIST_FOR_EACH_NODE(&cmux->dlcis, node) { + dlci = (struct modem_cmux_dlci *)node; + modem_pipe_notify_transmit_idle(&dlci->pipe); + } +} + static void modem_cmux_transmit_handler(struct k_work *item) { struct k_work_delayable *dwork = k_work_delayable_from_work(item); @@ -773,31 +861,42 @@ static void modem_cmux_transmit_handler(struct k_work *item) uint8_t *reserved; uint32_t reserved_size; int ret; + bool transmit_rb_empty; k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER); - /* Reserve data to transmit from transmit ring buffer */ - reserved_size = ring_buf_get_claim(&cmux->transmit_rb, &reserved, UINT32_MAX); + while (true) { + transmit_rb_empty = ring_buf_is_empty(&cmux->transmit_rb); - /* Transmit reserved data */ - ret = modem_pipe_transmit(cmux->pipe, reserved, reserved_size); - if (ret < 1) { - ring_buf_get_finish(&cmux->transmit_rb, 0); - k_mutex_unlock(&cmux->transmit_rb_lock); - k_work_schedule(&cmux->transmit_work, K_NO_WAIT); + if (transmit_rb_empty) { + break; + } - return; - } + reserved_size = ring_buf_get_claim(&cmux->transmit_rb, &reserved, UINT32_MAX); - /* Release remaining reserved data */ - ring_buf_get_finish(&cmux->transmit_rb, ret); + ret = modem_pipe_transmit(cmux->pipe, reserved, reserved_size); + if (ret < 0) { + ring_buf_get_finish(&cmux->transmit_rb, 0); + if (ret != -EPERM) { + LOG_ERR("Failed to %s %u bytes. (%d)", + "transmit", reserved_size, ret); + } + break; + } - /* Resubmit transmit work if data remains */ - if (ring_buf_is_empty(&cmux->transmit_rb) == false) { - k_work_schedule(&cmux->transmit_work, K_NO_WAIT); + ring_buf_get_finish(&cmux->transmit_rb, (uint32_t)ret); + + if (ret < reserved_size) { + LOG_DBG("Transmitted only %u out of %u bytes at once.", ret, reserved_size); + break; + } } k_mutex_unlock(&cmux->transmit_rb_lock); + + if (transmit_rb_empty) { + modem_cmux_dlci_notify_transmit_idle(cmux); + } } static void modem_cmux_connect_handler(struct k_work *item) @@ -996,6 +1095,7 @@ void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *co k_work_init_delayable(&cmux->connect_work, modem_cmux_connect_handler); k_work_init_delayable(&cmux->disconnect_work, modem_cmux_disconnect_handler); k_event_init(&cmux->event); + k_event_clear(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT); k_event_post(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT); } @@ -1071,7 +1171,6 @@ int modem_cmux_disconnect(struct modem_cmux *cmux) if (ret < 0) { return ret; } - if (k_event_wait(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT, false, MODEM_CMUX_T2_TIMEOUT) == 0) { return -EAGAIN; diff --git a/subsys/modem/modem_pipe.c b/subsys/modem/modem_pipe.c index 01bdac50d3a..b0088fdefed 100644 --- a/subsys/modem/modem_pipe.c +++ b/subsys/modem/modem_pipe.c @@ -21,6 +21,7 @@ void modem_pipe_init(struct modem_pipe *pipe, void *data, struct modem_pipe_api pipe->user_data = NULL; pipe->state = MODEM_PIPE_STATE_CLOSED; pipe->receive_ready_pending = false; + pipe->transmit_idle_pending = true; k_mutex_init(&pipe->lock); k_condvar_init(&pipe->condvar); @@ -82,6 +83,10 @@ void modem_pipe_attach(struct modem_pipe *pipe, modem_pipe_api_callback callback pipe->callback(pipe, MODEM_PIPE_EVENT_RECEIVE_READY, pipe->user_data); } + if (pipe->transmit_idle_pending && (pipe->callback != NULL)) { + pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data); + } + k_mutex_unlock(&pipe->lock); } @@ -97,6 +102,7 @@ int modem_pipe_transmit(struct modem_pipe *pipe, const uint8_t *buf, size_t size } ret = pipe->api->transmit(pipe->data, buf, size); + pipe->transmit_idle_pending = false; k_mutex_unlock(&pipe->lock); return ret; } @@ -179,6 +185,7 @@ void modem_pipe_notify_opened(struct modem_pipe *pipe) if (pipe->callback != NULL) { pipe->callback(pipe, MODEM_PIPE_EVENT_OPENED, pipe->user_data); + pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data); } k_condvar_signal(&pipe->condvar); @@ -190,6 +197,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; + pipe->transmit_idle_pending = true; if (pipe->callback != NULL) { pipe->callback(pipe, MODEM_PIPE_EVENT_CLOSED, pipe->user_data); @@ -211,3 +219,16 @@ void modem_pipe_notify_receive_ready(struct modem_pipe *pipe) k_mutex_unlock(&pipe->lock); } + +void modem_pipe_notify_transmit_idle(struct modem_pipe *pipe) +{ + k_mutex_lock(&pipe->lock, K_FOREVER); + + pipe->transmit_idle_pending = true; + + if (pipe->callback != NULL) { + pipe->callback(pipe, MODEM_PIPE_EVENT_TRANSMIT_IDLE, pipe->user_data); + } + + k_mutex_unlock(&pipe->lock); +} diff --git a/subsys/modem/modem_ppp.c b/subsys/modem/modem_ppp.c index 476926f4db3..91085317d99 100644 --- a/subsys/modem/modem_ppp.c +++ b/subsys/modem/modem_ppp.c @@ -192,40 +192,45 @@ static uint8_t modem_ppp_wrap_net_pkt_byte(struct modem_ppp *ppp) return 0; } +static bool modem_ppp_is_byte_expected(uint8_t byte, uint8_t expected_byte) +{ + if (byte == expected_byte) { + return true; + } + LOG_DBG("Dropping byte 0x%02hhx because 0x%02hhx was expected.", byte, expected_byte); + return false; +} + static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) { switch (ppp->receive_state) { case MODEM_PPP_RECEIVE_STATE_HDR_SOF: - if (byte == MODEM_PPP_CODE_DELIMITER) { + if (modem_ppp_is_byte_expected(byte, MODEM_PPP_CODE_DELIMITER)) { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_FF; } - break; case MODEM_PPP_RECEIVE_STATE_HDR_FF: if (byte == MODEM_PPP_CODE_DELIMITER) { break; } - - if (byte == 0xFF) { + if (modem_ppp_is_byte_expected(byte, 0xFF)) { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_7D; } else { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; } - break; case MODEM_PPP_RECEIVE_STATE_HDR_7D: - if (byte == MODEM_PPP_CODE_ESCAPE) { + if (modem_ppp_is_byte_expected(byte, MODEM_PPP_CODE_ESCAPE)) { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_23; } else { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; } - break; case MODEM_PPP_RECEIVE_STATE_HDR_23: - if (byte == 0x23) { + if (modem_ppp_is_byte_expected(byte, 0x23)) { ppp->rx_pkt = net_pkt_rx_alloc_with_buffer(ppp->iface, CONFIG_MODEM_PPP_NET_BUF_FRAG_SIZE, AF_UNSPEC, 0, K_NO_WAIT); @@ -238,7 +243,6 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) LOG_DBG("Receiving PPP frame"); ppp->receive_state = MODEM_PPP_RECEIVE_STATE_WRITING; net_pkt_cursor_init(ppp->rx_pkt); - } else { ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; } @@ -247,11 +251,10 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) case MODEM_PPP_RECEIVE_STATE_WRITING: if (byte == MODEM_PPP_CODE_DELIMITER) { - LOG_DBG("Received PPP frame"); + LOG_DBG("Received PPP frame (len %zu)", net_pkt_get_len(ppp->rx_pkt)); /* Remove FCS */ net_pkt_remove_tail(ppp->rx_pkt, MODEM_PPP_FRAME_TAIL_SIZE); - net_pkt_cursor_init(ppp->rx_pkt); net_pkt_set_ppp(ppp->rx_pkt, true); if (net_recv_data(ppp->iface, ppp->rx_pkt) < 0) { @@ -260,7 +263,8 @@ static void modem_ppp_process_received_byte(struct modem_ppp *ppp, uint8_t byte) } ppp->rx_pkt = NULL; - ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_SOF; + /* Skip SOF because the delimiter may be omitted for successive frames. */ + ppp->receive_state = MODEM_PPP_RECEIVE_STATE_HDR_FF; break; } @@ -314,8 +318,18 @@ static void modem_ppp_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_eve { struct modem_ppp *ppp = (struct modem_ppp *)user_data; - if (event == MODEM_PIPE_EVENT_RECEIVE_READY) { + switch (event) { + case MODEM_PIPE_EVENT_RECEIVE_READY: k_work_submit(&ppp->process_work); + break; + + case MODEM_PIPE_EVENT_OPENED: + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + k_work_submit(&ppp->send_work); + break; + + default: + break; } } @@ -351,22 +365,20 @@ static void modem_ppp_send_handler(struct k_work *item) } } - reserved_size = ring_buf_get_claim(&ppp->transmit_rb, &reserved, UINT32_MAX); - if (reserved_size == 0) { - ring_buf_get_finish(&ppp->transmit_rb, 0); - return; - } + while (!ring_buf_is_empty(&ppp->transmit_rb)) { + reserved_size = ring_buf_get_claim(&ppp->transmit_rb, &reserved, UINT32_MAX); + + ret = modem_pipe_transmit(ppp->pipe, reserved, reserved_size); + if (ret < 0) { + ring_buf_get_finish(&ppp->transmit_rb, 0); + break; + } - ret = modem_pipe_transmit(ppp->pipe, reserved, reserved_size); - if (ret < 0) { - ring_buf_get_finish(&ppp->transmit_rb, 0); - } else { ring_buf_get_finish(&ppp->transmit_rb, (uint32_t)ret); - } - /* Resubmit send work if data remains */ - if ((ring_buf_is_empty(&ppp->transmit_rb) == false) || (ppp->tx_pkt != NULL)) { - k_work_submit(&ppp->send_work); + if (ret < reserved_size) { + break; + } } } @@ -460,12 +472,14 @@ const struct ppp_api modem_ppp_ppp_api = { int modem_ppp_attach(struct modem_ppp *ppp, struct modem_pipe *pipe) { - if (atomic_test_and_set_bit(&ppp->state, MODEM_PPP_STATE_ATTACHED_BIT) == true) { + if (atomic_test_bit(&ppp->state, MODEM_PPP_STATE_ATTACHED_BIT) == true) { return 0; } - modem_pipe_attach(pipe, modem_ppp_pipe_callback, ppp); ppp->pipe = pipe; + modem_pipe_attach(pipe, modem_ppp_pipe_callback, ppp); + + atomic_set_bit(&ppp->state, MODEM_PPP_STATE_ATTACHED_BIT); return 0; } diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index e72e614d54c..05686a663eb 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -24,6 +24,7 @@ source "subsys/net/Kconfig.template.log_config.net" config NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE int "Size of the stack allocated for the conn_mgr_monitor thread" + default 8192 if WPA_SUPP default 512 help Sets the stack size which will be used by the connection manager for connectivity monitoring. diff --git a/subsys/net/ip/CMakeLists.txt b/subsys/net/ip/CMakeLists.txt index b9493b894a7..3a93e5020d4 100644 --- a/subsys/net/ip/CMakeLists.txt +++ b/subsys/net/ip/CMakeLists.txt @@ -45,7 +45,6 @@ zephyr_library_sources_ifdef(CONFIG_NET_ROUTE route.c) zephyr_library_sources_ifdef(CONFIG_NET_STATISTICS net_stats.c) zephyr_library_sources_ifdef(CONFIG_NET_TCP tcp.c) zephyr_library_sources_ifdef(CONFIG_NET_TEST_PROTOCOL tp.c) -zephyr_library_sources_ifdef(CONFIG_NET_TRICKLE trickle.c) zephyr_library_sources_ifdef(CONFIG_NET_UDP udp.c) zephyr_library_sources_ifdef(CONFIG_NET_PROMISCUOUS_MODE promiscuous.c) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index fffa028b628..a5a6b7ba01e 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -758,20 +758,6 @@ config NET_SLIP_TAP communicate via the SLIP driver. See net-tools project at https://github.com/zephyrproject-rtos/net-tools for more details. -config NET_TRICKLE - bool "Trickle library" - help - Normally this is enabled automatically if needed, - so say 'n' if unsure. - -if NET_TRICKLE -module = NET_TRICKLE -module-dep = NET_LOG -module-str = Log level for Trickle algorithm -module-help = Enables Trickle library output debug messages -source "subsys/net/Kconfig.template.log_config.net" -endif # NET_TRICKLE - endif # NET_RAW_MODE config NET_PKT_RX_COUNT diff --git a/subsys/net/ip/dhcpv4.h b/subsys/net/ip/dhcpv4.h index a274e3a6aea..712d361ac80 100644 --- a/subsys/net/ip/dhcpv4.h +++ b/subsys/net/ip/dhcpv4.h @@ -62,6 +62,7 @@ struct dhcp_msg { #define DHCPV4_OPTIONS_REQ_LIST 55 #define DHCPV4_OPTIONS_RENEWAL 58 #define DHCPV4_OPTIONS_REBINDING 59 +#define DHCPV4_OPTIONS_CLIENT_ID 61 #define DHCPV4_OPTIONS_END 255 /* Useful size macros */ @@ -142,4 +143,14 @@ static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt) #endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */ +#if defined(CONFIG_NET_DHCPV4_SERVER) + +void net_dhcpv4_server_init(void); + +#else + +#define net_dhcpv4_server_init() + +#endif /* CONFIG_NET_DHCPV4_SERVER */ + #endif /* __INTERNAL_DHCPV4_H */ diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index baa8cd695c5..3187b40a66b 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -495,6 +495,8 @@ static inline int services_init(void) return status; } + net_dhcpv4_server_init(); + dns_init_resolver(); websocket_init(); diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 00c9c74495d..1a8199ad62c 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -3532,6 +3532,27 @@ static inline int z_vrfy_net_if_ipv4_addr_lookup_by_index( #include #endif +struct in_addr net_if_ipv4_get_netmask(struct net_if *iface) +{ + struct in_addr netmask = { 0 }; + + net_if_lock(iface); + + if (net_if_config_ipv4_get(iface, NULL) < 0) { + goto out; + } + + if (!iface->config.ip.ipv4) { + goto out; + } + + netmask = iface->config.ip.ipv4->netmask; +out: + net_if_unlock(iface); + + return netmask; +} + void net_if_ipv4_set_netmask(struct net_if *iface, const struct in_addr *netmask) { diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 39a06ed64a0..6be7255b19b 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -457,11 +457,11 @@ static void arp_gratuitous(struct net_if *iface, } } -static void arp_update(struct net_if *iface, - struct in_addr *src, - struct net_eth_addr *hwaddr, - bool gratuitous, - bool force) +void net_arp_update(struct net_if *iface, + struct in_addr *src, + struct net_eth_addr *hwaddr, + bool gratuitous, + bool force) { struct arp_entry *entry; struct net_pkt *pkt; @@ -647,10 +647,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, /* If the IP address is in our cache, * then update it here. */ - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - true, false); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + true, false); break; } } @@ -689,10 +689,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, net_sprint_ll_addr((uint8_t *)&arp_hdr->src_hwaddr, arp_hdr->hwlen)); - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - false, true); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + false, true); dst_hw_addr = &arp_hdr->src_hwaddr; } else { @@ -711,10 +711,10 @@ enum net_verdict net_arp_input(struct net_pkt *pkt, case NET_ARP_REPLY: if (net_ipv4_is_my_addr((struct in_addr *)arp_hdr->dst_ipaddr)) { - arp_update(net_pkt_iface(pkt), - (struct in_addr *)arp_hdr->src_ipaddr, - &arp_hdr->src_hwaddr, - false, false); + net_arp_update(net_pkt_iface(pkt), + (struct in_addr *)arp_hdr->src_ipaddr, + &arp_hdr->src_hwaddr, + false, false); } break; diff --git a/subsys/net/l2/ethernet/arp.h b/subsys/net/l2/ethernet/arp.h index 28cafe5f20a..46589cbc1f7 100644 --- a/subsys/net/l2/ethernet/arp.h +++ b/subsys/net/l2/ethernet/arp.h @@ -67,6 +67,9 @@ int net_arp_foreach(net_arp_cb_t cb, void *user_data); void net_arp_clear_cache(struct net_if *iface); void net_arp_init(void); +void net_arp_update(struct net_if *iface, struct in_addr *src, + struct net_eth_addr *hwaddr, bool gratuitous, + bool force); /** * @} @@ -83,6 +86,7 @@ void net_arp_init(void); #define net_arp_foreach(...) 0 #define net_arp_init(...) #define net_arp_clear_pending(...) 0 +#define net_arp_update(...) #endif /* CONFIG_NET_ARP */ diff --git a/subsys/net/l2/ethernet/ethernet.c b/subsys/net/l2/ethernet/ethernet.c index 2be3c5f2820..8e73e8bcd43 100644 --- a/subsys/net/l2/ethernet/ethernet.c +++ b/subsys/net/l2/ethernet/ethernet.c @@ -1197,6 +1197,20 @@ int net_eth_promisc_mode(struct net_if *iface, bool enable) } #endif/* CONFIG_NET_PROMISCUOUS_MODE */ +int net_eth_txinjection_mode(struct net_if *iface, bool enable) +{ + struct ethernet_req_params params; + + if (!(net_eth_get_hw_capabilities(iface) & ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + params.txinjection_mode = enable; + + return net_mgmt(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE, iface, + ¶ms, sizeof(struct ethernet_req_params)); +} + void ethernet_init(struct net_if *iface) { struct ethernet_context *ctx = net_if_l2_data(iface); diff --git a/subsys/net/l2/ethernet/ethernet_mgmt.c b/subsys/net/l2/ethernet/ethernet_mgmt.c index e7fcae8ac99..899aa7a9516 100644 --- a/subsys/net/l2/ethernet/ethernet_mgmt.c +++ b/subsys/net/l2/ethernet/ethernet_mgmt.c @@ -192,6 +192,21 @@ static int ethernet_set_config(uint32_t mgmt_request, config.promisc_mode = params->promisc_mode; type = ETHERNET_CONFIG_TYPE_PROMISC_MODE; + } else if (mgmt_request == NET_REQUEST_ETHERNET_SET_T1S_PARAM) { + if (net_if_is_up(iface)) { + return -EACCES; + } + + memcpy(&config.t1s_param, ¶ms->t1s_param, + sizeof(struct ethernet_t1s_param)); + type = ETHERNET_CONFIG_TYPE_T1S_PARAM; + } else if (mgmt_request == NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE) { + if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + config.txinjection_mode = params->txinjection_mode; + type = ETHERNET_CONFIG_TYPE_TXINJECTION_MODE; } else { return -EINVAL; } @@ -226,6 +241,12 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXTIME_PARAM, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_PROMISC_MODE, ethernet_set_config); +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_T1S_PARAM, + ethernet_set_config); + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE, + ethernet_set_config); + static int ethernet_get_config(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) @@ -419,6 +440,19 @@ static int ethernet_get_config(uint32_t mgmt_request, config.txtime_param.enable_txtime; break; } + } else if (mgmt_request == NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE) { + if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) { + return -ENOTSUP; + } + + type = ETHERNET_CONFIG_TYPE_TXINJECTION_MODE; + + ret = api->get_config(dev, type, &config); + if (ret) { + return ret; + } + + params->txinjection_mode = config.txinjection_mode; } else { return -EINVAL; } @@ -444,6 +478,9 @@ NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBU_PARAM, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXTIME_PARAM, ethernet_get_config); +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE, + ethernet_get_config); + void ethernet_mgmt_raise_carrier_on_event(struct net_if *iface) { net_mgmt_event_notify(NET_EVENT_ETHERNET_CARRIER_ON, iface); diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index 98113975797..aa7e03b8204 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -324,21 +324,15 @@ config OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE config OPENTHREAD_CRYPTO_PSA bool "ARM PSA crypto API" depends on MBEDTLS_PSA_CRYPTO_C || BUILD_WITH_TFM - select OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE + select OPENTHREAD_PLATFORM_KEY_REF select OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE help Enable crypto backend library implementation based on ARM PSA crypto API instead of the default, using mbedTLS. -config OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE - bool "Cryptographic key reference support" - help - Enable usage of cryptographic key references instead of literal keys - This requires a crypto backend library that supports key references. - config OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE bool "Make MAC keys exportable" - depends on OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE + depends on OPENTHREAD_PLATFORM_KEY_REF help Enable the creation of exportable MAC keys in the OpenThread Key Manager. diff --git a/subsys/net/l2/wifi/CMakeLists.txt b/subsys/net/l2/wifi/CMakeLists.txt index 445eb56c0a7..aaf825599f0 100644 --- a/subsys/net/l2/wifi/CMakeLists.txt +++ b/subsys/net/l2/wifi/CMakeLists.txt @@ -2,6 +2,9 @@ zephyr_library() zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) +zephyr_library_include_directories_ifdef( + CONFIG_NET_L2_WIFI_SHELL ${ZEPHYR_BASE}/subsys/net/lib/shell + ) zephyr_library_compile_definitions_ifdef( CONFIG_NEWLIB_LIBC __LINUX_ERRNO_EXTENSIONS__ ) 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_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 6eb8a6682c2..bc844016fa5 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -274,6 +274,7 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, (params->ssid_length > WIFI_SSID_MAX_LEN) || (params->ssid_length == 0U) || ((params->security == WIFI_SECURITY_TYPE_PSK || + params->security == WIFI_SECURITY_TYPE_WPA_PSK || params->security == WIFI_SECURITY_TYPE_PSK_SHA256) && ((params->psk_length < 8) || (params->psk_length > 64) || (params->psk_length == 0U) || !params->psk)) || @@ -409,6 +410,30 @@ static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable); +static int wifi_ap_sta_disconnect(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); + uint8_t *mac = data; + + if (dev == NULL) { + return -ENODEV; + } + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_sta_disconnect == NULL) { + return -ENOTSUP; + } + + if (!data || len != sizeof(uint8_t) * WIFI_MAC_ADDR_LEN) { + return -EINVAL; + } + + return wifi_mgmt_api->ap_sta_disconnect(dev, mac); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_STA_DISCONNECT, wifi_ap_sta_disconnect); + static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { @@ -678,6 +703,22 @@ static int wifi_channel(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CHANNEL, wifi_channel); +static int wifi_get_version(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_version *ver_params = data; + + if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_version == NULL) { + return -ENOTSUP; + } + + return wifi_mgmt_api->get_version(dev, ver_params); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION, wifi_get_version); + #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) @@ -706,3 +747,43 @@ 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)); +} + +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 ed85b015971..71f3cec7c10 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -15,6 +15,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include #include #include @@ -24,52 +25,55 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include -#include "net_private.h" +#include "net_shell_private.h" #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 |\ + NET_EVENT_WIFI_AP_ENABLE_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 (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 */ +#define MAX_BANDS_STR_LEN 64 + static struct { const struct shell *sh; + uint32_t scan_result; union { struct { - uint8_t connecting : 1; - uint8_t disconnecting : 1; - uint8_t _unused : 6; + uint8_t connecting: 1; + uint8_t disconnecting: 1; + uint8_t _unused: 6; }; uint8_t all; }; } context; -static uint32_t scan_result; - static struct net_mgmt_event_callback wifi_shell_mgmt_cb; +static struct wifi_reg_chan_info chan_info[MAX_REG_CHAN_NUM]; -#define print(sh, level, fmt, ...) \ - do { \ - if (sh) { \ - shell_fprintf(sh, level, fmt, ##__VA_ARGS__); \ - } else { \ - printk(fmt, ##__VA_ARGS__); \ - } \ - } while (false) +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]; static bool parse_number(const struct shell *sh, long *param, char *str, long min, long max) { @@ -85,12 +89,12 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi } if (*endptr != '\0') { - print(sh, SHELL_ERROR, "Invalid number: %s", str_tmp); + PR_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); + PR_WARNING("Value out of range: %s, (%ld-%ld)", str_tmp, min, max); return false; } *param = num; @@ -102,29 +106,31 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) const struct wifi_scan_result *entry = (const struct wifi_scan_result *)cb->info; uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + const struct shell *sh = context.sh; + uint8_t ssid_print[WIFI_SSID_MAX_LEN + 1]; + + context.scan_result++; + + if (context.scan_result == 1U) { + PR("\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %-17s | %-8s\n", + "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID", "MFP"); + } - scan_result++; - - if (scan_result == 1U) { - print(context.sh, SHELL_NORMAL, - "\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %-17s | %-8s\n", - "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID", "MFP"); - } - - print(context.sh, SHELL_NORMAL, - "%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %-17s | %-8s\n", - scan_result, entry->ssid, entry->ssid_length, entry->channel, - wifi_band_txt(entry->band), - entry->rssi, - wifi_security_txt(entry->security), - ((entry->mac_length) ? - net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, - mac_string_buf, - sizeof(mac_string_buf)) : ""), - wifi_mfp_txt(entry->mfp)); + strncpy(ssid_print, entry->ssid, sizeof(ssid_print) - 1); + ssid_print[sizeof(ssid_print) - 1] = '\0'; + + PR("%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %-17s | %-8s\n", + context.scan_result, ssid_print, entry->ssid_length, entry->channel, + wifi_band_txt(entry->band), + entry->rssi, + wifi_security_txt(entry->security), + ((entry->mac_length) ? + net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf)) : ""), + wifi_mfp_txt(entry->mfp)); } -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS static int wifi_freq_to_channel(int frequency) { int channel = 0; @@ -146,13 +152,14 @@ static int wifi_freq_to_channel(int frequency) return channel; } +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS static enum wifi_frequency_bands wifi_freq_to_band(int frequency) { enum wifi_frequency_bands band = WIFI_FREQ_BAND_2_4_GHZ; - if ((frequency >= 2401) && (frequency <= 2495)) { + if ((frequency >= 2401) && (frequency <= 2495)) { band = WIFI_FREQ_BAND_2_4_GHZ; - } else if ((frequency >= 5170) && (frequency <= 5895)) { + } else if ((frequency >= 5170) && (frequency <= 5895)) { band = WIFI_FREQ_BAND_5_GHZ; } else { band = WIFI_FREQ_BAND_6_GHZ; @@ -170,32 +177,32 @@ static void handle_wifi_raw_scan_result(struct net_mgmt_event_callback *cb) int rssi; int i = 0; uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + const struct shell *sh = context.sh; - scan_result++; + context.scan_result++; - if (scan_result == 1U) { - print(context.sh, SHELL_NORMAL, - "\n%-4s | %-13s | %-4s | %-15s | %-15s | %-32s\n", - "Num", "Channel (Band)", "RSSI", "BSSID", "Frame length", "Frame Body"); + if (context.scan_result == 1U) { + PR("\n%-4s | %-13s | %-4s | %-15s | %-15s | %-32s\n", + "Num", "Channel (Band)", "RSSI", "BSSID", "Frame length", "Frame Body"); } rssi = raw->rssi; channel = wifi_freq_to_channel(raw->frequency); band = wifi_freq_to_band(raw->frequency); - print(context.sh, SHELL_NORMAL, "%-4d | %-4u (%-6s) | %-4d | %s | %-4d ", - scan_result, - channel, - wifi_band_txt(band), - rssi, - net_sprint_ll_addr_buf(raw->data + 10, WIFI_MAC_ADDR_LEN, mac_string_buf, - sizeof(mac_string_buf)), raw->frame_length); + PR("%-4d | %-4u (%-6s) | %-4d | %s | %-4d ", + context.scan_result, + channel, + wifi_band_txt(band), + rssi, + net_sprint_ll_addr_buf(raw->data + 10, WIFI_MAC_ADDR_LEN, mac_string_buf, + sizeof(mac_string_buf)), raw->frame_length); for (i = 0; i < 32; i++) { - print(context.sh, SHELL_NORMAL, "%02X ", *(raw->data + i)); + PR("%02X ", *(raw->data + i)); } - print(context.sh, SHELL_NORMAL, "\n"); + PR("\n"); } #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ @@ -203,27 +210,27 @@ static void handle_wifi_scan_done(struct net_mgmt_event_callback *cb) { const struct wifi_status *status = (const struct wifi_status *)cb->info; + const struct shell *sh = context.sh; if (status->status) { - print(context.sh, SHELL_WARNING, - "Scan request failed (%d)\n", status->status); + PR_WARNING("Scan request failed (%d)\n", status->status); } else { - print(context.sh, SHELL_NORMAL, "Scan request done\n"); + PR("Scan request done\n"); } - scan_result = 0U; + context.scan_result = 0U; } static void handle_wifi_connect_result(struct net_mgmt_event_callback *cb) { const struct wifi_status *status = (const struct wifi_status *) cb->info; + const struct shell *sh = context.sh; if (status->status) { - print(context.sh, SHELL_WARNING, - "Connection request failed (%d)\n", status->status); + PR_WARNING("Connection request failed (%d)\n", status->status); } else { - print(context.sh, SHELL_NORMAL, "Connected\n"); + PR("Connected\n"); } context.connecting = false; @@ -233,16 +240,17 @@ static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb) { const struct wifi_status *status = (const struct wifi_status *) cb->info; + const struct shell *sh = context.sh; if (context.disconnecting) { - print(context.sh, - status->status ? SHELL_WARNING : SHELL_NORMAL, - "Disconnection request %s (%d)\n", - status->status ? "failed" : "done", - status->status); + if (status->status) { + PR_WARNING("Disconnection request failed (%d)\n", status->status); + } else { + PR("Disconnection request done (%d)\n", status->status); + } context.disconnecting = false; } else { - print(context.sh, SHELL_NORMAL, "Disconnected\n"); + PR("Disconnected\n"); } } @@ -252,42 +260,50 @@ static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, bool trigger, uint32_t twt_wake_interval, uint64_t twt_interval) { - print(context.sh, SHELL_NORMAL, "TWT Dialog token: %d\n", + const struct shell *sh = context.sh; + + PR("TWT Dialog token: %d\n", dialog_token); - print(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", + PR("TWT flow ID: %d\n", flow_id); - print(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", + PR("TWT negotiation type: %s\n", wifi_twt_negotiation_type_txt(negotiation_type)); - print(context.sh, SHELL_NORMAL, "TWT responder: %s\n", + PR("TWT responder: %s\n", responder ? "true" : "false"); - print(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", + PR("TWT implicit: %s\n", implicit ? "true" : "false"); - print(context.sh, SHELL_NORMAL, "TWT announce: %s\n", + PR("TWT announce: %s\n", announce ? "true" : "false"); - print(context.sh, SHELL_NORMAL, "TWT trigger: %s\n", + PR("TWT trigger: %s\n", trigger ? "true" : "false"); - print(context.sh, SHELL_NORMAL, "TWT wake interval: %d us\n", + PR("TWT wake interval: %d us\n", twt_wake_interval); - print(context.sh, SHELL_NORMAL, "TWT interval: %lld us\n", + PR("TWT interval: %lld us\n", twt_interval); - print(context.sh, SHELL_NORMAL, "========================\n"); + PR("========================\n"); } static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) { const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; + const struct shell *sh = context.sh; if (resp->operation == WIFI_TWT_TEARDOWN) { - print(context.sh, SHELL_NORMAL, "TWT teardown received for flow ID %d\n", - resp->flow_id); + if (resp->teardown_status == WIFI_TWT_TEARDOWN_SUCCESS) { + PR("TWT teardown succeeded for flow ID %d\n", + resp->flow_id); + } else { + PR("TWT teardown failed for flow ID %d\n", + resp->flow_id); + } return; } if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { - print(context.sh, SHELL_NORMAL, "TWT response: %s\n", + PR("TWT response: %s\n", wifi_twt_setup_cmd_txt(resp->setup_cmd)); - print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); + PR("== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, resp->negotiation_type, @@ -298,8 +314,91 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) resp->setup.twt_wake_interval, resp->setup.twt_interval); } else { - print(context.sh, SHELL_NORMAL, "TWT response timed out\n"); + PR("TWT response timed out\n"); + } +} + +static void handle_wifi_ap_enable_result(struct net_mgmt_event_callback *cb) +{ + const struct wifi_status *status = + (const struct wifi_status *)cb->info; + const struct shell *sh = context.sh; + + if (status->status) { + PR_WARNING("AP enable request failed (%d)\n", status->status); + } else { + PR("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; + const struct shell *sh = context.sh; + + if (status->status) { + PR_WARNING("AP disable request failed (%d)\n", status->status); + } else { + PR("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) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + const struct shell *sh = context.sh; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + int i; + + PR("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) { + PR_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) +{ + const struct wifi_ap_sta_info *sta_info = + (const struct wifi_ap_sta_info *)cb->info; + const struct shell *sh = context.sh; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + PR("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, @@ -326,20 +425,30 @@ 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; + 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; } } static int __wifi_args_to_params(size_t argc, char *argv[], - struct wifi_connect_req_params *params) + struct wifi_connect_req_params *params, + enum wifi_iface_mode iface_mode) { char *endptr; int idx = 1; - - if (argc < 1) { - return -EINVAL; - } + const struct shell *sh = context.sh; /* Defaults */ params->band = WIFI_FREQ_BAND_UNKNOWN; @@ -350,20 +459,85 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->ssid = argv[0]; params->ssid_length = strlen(params->ssid); if (params->ssid_length > WIFI_SSID_MAX_LEN) { + PR_WARNING("SSID too long (max %d characters)\n", + WIFI_SSID_MAX_LEN); return -EINVAL; } - /* Channel (optional) */ + /* Channel (optional: STA, mandatory: AP) */ if ((idx < argc) && (strlen(argv[idx]) <= 3)) { - params->channel = strtol(argv[idx], &endptr, 10); + uint8_t band; + long channel = strtol(argv[idx], &endptr, 10); + const uint8_t all_bands[] = {WIFI_FREQ_BAND_2_4_GHZ, + WIFI_FREQ_BAND_5_GHZ, + WIFI_FREQ_BAND_6_GHZ}; + bool found = false; + char bands_str[MAX_BANDS_STR_LEN] = {0}; + size_t offset = 0; + if (*endptr != '\0') { + PR_ERROR("Failed to parse channel: %s: endp: %s, err: %s\n", + argv[idx], + endptr, + strerror(errno)); return -EINVAL; } - if (params->channel == 0U) { - params->channel = WIFI_CHANNEL_ANY; + if (iface_mode == WIFI_MODE_INFRA) { + if (channel < 0) { + /* Negative channel means band */ + switch (-channel) { + case 2: + params->band = WIFI_FREQ_BAND_2_4_GHZ; + break; + case 5: + params->band = WIFI_FREQ_BAND_5_GHZ; + break; + case 6: + params->band = WIFI_FREQ_BAND_6_GHZ; + break; + default: + PR_ERROR("Invalid band: %ld\n", channel); + return -EINVAL; + } + } + } else { + if (channel < 0) { + PR_ERROR("Invalid channel: %ld\n", channel); + return -EINVAL; + } } + if (channel > 0) { + for (band = 0; band < ARRAY_SIZE(all_bands); band++) { + offset += snprintf(bands_str + offset, + sizeof(bands_str) - offset, + "%s%s", + band ? "," : "", + wifi_band_txt(all_bands[band])); + if (offset >= sizeof(bands_str)) { + PR_ERROR("Failed to parse channel: %s: " + "band string too long\n", + argv[idx]); + return -EINVAL; + } + + if (wifi_utils_validate_chan(all_bands[band], + channel)) { + found = true; + break; + } + } + + if (!found) { + PR_ERROR("Invalid channel: %ld, checked bands: %s\n", + channel, + bands_str); + return -EINVAL; + } + + params->channel = channel; + } idx++; } @@ -389,6 +563,13 @@ static int __wifi_args_to_params(size_t argc, char *argv[], if (idx < argc) { unsigned int mfp = strtol(argv[idx], &endptr, 10); + if (security == WIFI_SECURITY_TYPE_NONE || + security == WIFI_SECURITY_TYPE_WPA_PSK) { + PR_ERROR("MFP not supported for security type %s\n", + wifi_security_txt(security)); + return -EINVAL; + } + if (mfp <= WIFI_MFP_REQUIRED) { params->mfp = mfp; } @@ -401,11 +582,13 @@ static int __wifi_args_to_params(size_t argc, char *argv[], params->psk_length > WIFI_PSK_MAX_LEN) || (params->security == WIFI_SECURITY_TYPE_SAE && params->psk_length > WIFI_SAE_PSWD_MAX_LEN)) { + PR_ERROR("Invalid PSK length (%d) for security type %s\n", + params->psk_length, + wifi_security_txt(params->security)); return -EINVAL; } } - return 0; } @@ -415,24 +598,23 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc, struct net_if *iface = net_if_get_first_wifi(); struct wifi_connect_req_params cnx_params = { 0 }; - if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params)) { + context.sh = sh; + if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params, WIFI_MODE_INFRA)) { shell_help(sh); return -ENOEXEC; } context.connecting = true; - context.sh = sh; if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params, sizeof(struct wifi_connect_req_params))) { - shell_fprintf(sh, SHELL_WARNING, - "Connection request failed\n"); + PR_WARNING("Connection request failed\n"); context.connecting = false; return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "Connection requested\n"); + PR("Connection requested\n"); return 0; } @@ -452,23 +634,18 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, context.disconnecting = false; if (status == -EALREADY) { - shell_fprintf(sh, SHELL_INFO, - "Already disconnected\n"); + PR_INFO("Already disconnected\n"); } else { - shell_fprintf(sh, SHELL_WARNING, - "Disconnect request failed\n"); + PR_WARNING("Disconnect request failed\n"); return -ENOEXEC; } } else { - shell_fprintf(sh, SHELL_NORMAL, - "Disconnect requested\n"); + PR("Disconnect requested\n"); } return 0; } - - static int wifi_scan_args_to_params(const struct shell *sh, size_t argc, char *argv[], @@ -496,12 +673,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, state = getopt_state_get(); switch (opt) { case 't': - if (!strcmp(optarg, "passive")) { + if (!strncasecmp(optarg, "passive", 7)) { params->scan_type = WIFI_SCAN_TYPE_PASSIVE; - } else if (!strcmp(optarg, "active")) { + } else if (!strncasecmp(optarg, "active", 6)) { params->scan_type = WIFI_SCAN_TYPE_ACTIVE; } else { - shell_fprintf(sh, SHELL_ERROR, "Invalid scan type %s\n", optarg); + PR_ERROR("Invalid scan type %s\n", optarg); return -ENOEXEC; } @@ -509,7 +686,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, break; case 'b': if (wifi_utils_parse_scan_bands(optarg, ¶ms->bands)) { - shell_fprintf(sh, SHELL_ERROR, "Invalid band value(s)\n"); + PR_ERROR("Invalid band value(s)\n"); return -ENOEXEC; } @@ -519,7 +696,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, val = atoi(optarg); if ((val < 5) || (val > 1000)) { - shell_fprintf(sh, SHELL_ERROR, "Invalid dwell_time_active val\n"); + PR_ERROR("Invalid dwell_time_active val\n"); return -ENOEXEC; } @@ -530,7 +707,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, val = atoi(optarg); if ((val < 10) || (val > 1000)) { - shell_fprintf(sh, SHELL_ERROR, "Invalid dwell_time_passive val\n"); + PR_ERROR("Invalid dwell_time_passive val\n"); return -ENOEXEC; } @@ -541,7 +718,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, if (wifi_utils_parse_scan_ssids(optarg, params->ssids, ARRAY_SIZE(params->ssids))) { - shell_fprintf(sh, SHELL_ERROR, "Invalid SSID(s)\n"); + PR_ERROR("Invalid SSID(s)\n"); return -ENOEXEC; } @@ -551,7 +728,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, val = atoi(optarg); if ((val < 0) || (val > 65535)) { - shell_fprintf(sh, SHELL_ERROR, "Invalid max_bss val\n"); + PR_ERROR("Invalid max_bss val\n"); return -ENOEXEC; } @@ -562,9 +739,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, 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"); + PR_ERROR("Invalid band or channel value(s)\n"); return -ENOEXEC; } @@ -577,8 +752,8 @@ static int wifi_scan_args_to_params(const struct shell *sh, break; case '?': default: - shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", - argv[opt_index + 1]); + PR_ERROR("Invalid option or option usage: %s\n", + argv[opt_index + 1]); return -ENOEXEC; } } @@ -602,23 +777,23 @@ static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) shell_help(sh); return -ENOEXEC; } else if (!opt_num) { - shell_fprintf(sh, SHELL_WARNING, "No valid option(s) found\n"); + PR_WARNING("No valid option(s) found\n"); do_scan = false; } } if (do_scan) { if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); + PR_WARNING("Scan request failed\n"); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "Scan requested\n"); + PR("Scan requested\n"); return 0; } - shell_fprintf(sh, SHELL_WARNING, "Scan not initiated\n"); + PR_WARNING("Scan not initiated\n"); return -ENOEXEC; } @@ -630,41 +805,37 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) context.sh = sh; if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status, - sizeof(struct wifi_iface_status))) { - shell_fprintf(sh, SHELL_WARNING, "Status request failed\n"); + sizeof(struct wifi_iface_status))) { + PR_WARNING("Status request failed\n"); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "Status: successful\n"); - shell_fprintf(sh, SHELL_NORMAL, "==================\n"); - shell_fprintf(sh, SHELL_NORMAL, "State: %s\n", wifi_state_txt(status.state)); + PR("Status: successful\n"); + PR("==================\n"); + PR("State: %s\n", wifi_state_txt(status.state)); if (status.state >= WIFI_STATE_ASSOCIATED) { uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - shell_fprintf(sh, SHELL_NORMAL, "Interface Mode: %s\n", - wifi_mode_txt(status.iface_mode)); - shell_fprintf(sh, SHELL_NORMAL, "Link Mode: %s\n", - wifi_link_mode_txt(status.link_mode)); - shell_fprintf(sh, SHELL_NORMAL, "SSID: %-32s\n", status.ssid); - shell_fprintf(sh, SHELL_NORMAL, "BSSID: %s\n", - net_sprint_ll_addr_buf(status.bssid, + PR("Interface Mode: %s\n", wifi_mode_txt(status.iface_mode)); + PR("Link Mode: %s\n", wifi_link_mode_txt(status.link_mode)); + PR("SSID: %.32s\n", status.ssid); + PR("BSSID: %s\n", + net_sprint_ll_addr_buf(status.bssid, WIFI_MAC_ADDR_LEN, mac_string_buf, - sizeof(mac_string_buf)) - ); - shell_fprintf(sh, SHELL_NORMAL, "Band: %s\n", - wifi_band_txt(status.band)); - shell_fprintf(sh, SHELL_NORMAL, "Channel: %d\n", status.channel); - shell_fprintf(sh, SHELL_NORMAL, "Security: %s\n", - 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); - 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", - status.twt_capable ? "Supported" : "Not supported"); + sizeof(mac_string_buf))); + PR("Band: %s\n", wifi_band_txt(status.band)); + PR("Channel: %d\n", status.channel); + PR("Security: %s\n", wifi_security_txt(status.security)); + PR("MFP: %s\n", wifi_mfp_txt(status.mfp)); + if (status.iface_mode == WIFI_MODE_INFRA) { + PR("RSSI: %d\n", status.rssi); + } + PR("Beacon Interval: %d\n", status.beacon_interval); + PR("DTIM: %d\n", status.dtim_period); + PR("TWT: %s\n", + status.twt_capable ? "Supported" : "Not supported"); } return 0; @@ -673,24 +844,23 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) #if defined(CONFIG_NET_STATISTICS_WIFI) && \ defined(CONFIG_NET_STATISTICS_USER_API) static void print_wifi_stats(struct net_if *iface, struct net_stats_wifi *data, - const struct shell *sh) + const struct shell *sh) { - shell_fprintf(sh, SHELL_NORMAL, "Statistics for Wi-Fi interface %p [%d]\n", iface, - net_if_get_by_iface(iface)); - - shell_fprintf(sh, SHELL_NORMAL, "Bytes received : %u\n", data->bytes.received); - shell_fprintf(sh, SHELL_NORMAL, "Bytes sent : %u\n", data->bytes.sent); - shell_fprintf(sh, SHELL_NORMAL, "Packets received : %u\n", data->pkts.rx); - shell_fprintf(sh, SHELL_NORMAL, "Packets sent : %u\n", data->pkts.tx); - shell_fprintf(sh, SHELL_NORMAL, "Receive errors : %u\n", data->errors.rx); - shell_fprintf(sh, SHELL_NORMAL, "Send errors : %u\n", data->errors.tx); - shell_fprintf(sh, SHELL_NORMAL, "Bcast received : %u\n", data->broadcast.rx); - shell_fprintf(sh, SHELL_NORMAL, "Bcast sent : %u\n", data->broadcast.tx); - shell_fprintf(sh, SHELL_NORMAL, "Mcast received : %u\n", data->multicast.rx); - shell_fprintf(sh, SHELL_NORMAL, "Mcast sent : %u\n", data->multicast.tx); - shell_fprintf(sh, SHELL_NORMAL, "Beacons received : %u\n", data->sta_mgmt.beacons_rx); - shell_fprintf(sh, SHELL_NORMAL, "Beacons missed : %u\n", - data->sta_mgmt.beacons_miss); + PR("Statistics for Wi-Fi 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("Receive errors : %u\n", data->errors.rx); + PR("Send errors : %u\n", data->errors.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("Beacons received : %u\n", data->sta_mgmt.beacons_rx); + PR("Beacons missed : %u\n", data->sta_mgmt.beacons_miss); } #endif /* CONFIG_NET_STATISTICS_WIFI && CONFIG_NET_STATISTICS_USER_API */ @@ -711,7 +881,7 @@ static int cmd_wifi_stats(const struct shell *sh, size_t argc, char *argv[]) ARG_UNUSED(argc); ARG_UNUSED(argv); - shell_fprintf(sh, SHELL_INFO, "Set %s to enable %s support.\n", + PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_STATISTICS_WIFI and CONFIG_NET_STATISTICS_USER_API", "statistics"); #endif /* CONFIG_NET_STATISTICS_WIFI && CONFIG_NET_STATISTICS_USER_API */ @@ -727,7 +897,7 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) context.sh = sh; if (argc > 2) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + PR_WARNING("Invalid number of arguments\n"); return -ENOEXEC; } @@ -736,33 +906,32 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) if (net_mgmt(NET_REQUEST_WIFI_PS_CONFIG, iface, &config, sizeof(config))) { - shell_fprintf(sh, SHELL_WARNING, "Failed to get PS config\n"); + PR_WARNING("Failed to get PS config\n"); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", - wifi_ps_txt(config.ps_params.enabled)); + PR("PS status: %s\n", + wifi_ps_txt(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)); + PR("PS mode: %s\n", + wifi_ps_mode_txt(config.ps_params.mode)); } - shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", - config.ps_params.listen_interval); + PR("PS listen_interval: %d\n", + config.ps_params.listen_interval); - shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", - config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); + PR("PS wake up mode: %s\n", + config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); if (config.ps_params.timeout_ms) { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", - config.ps_params.timeout_ms); + PR("PS timeout: %d ms\n", + config.ps_params.timeout_ms); } else { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + PR("PS timeout: disabled\n"); } - if (config.num_twt_flows == 0) { - shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); + PR("No TWT flows\n"); } else { for (int i = 0; i < config.num_twt_flows; i++) { print_twt_params( @@ -775,31 +944,32 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) config.twt_flows[i].trigger, config.twt_flows[i].twt_wake_interval, config.twt_flows[i].twt_interval); + PR("TWT Wake ahead duration : %d us\n", + config.twt_flows[i].twt_wake_ahead_duration); } } return 0; } - if (!strncmp(argv[1], "on", 2)) { + if (!strncasecmp(argv[1], "on", 2)) { params.enabled = WIFI_PS_ENABLED; - } else if (!strncmp(argv[1], "off", 3)) { + } else if (!strncasecmp(argv[1], "off", 3)) { params.enabled = WIFI_PS_DISABLED; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); + PR_WARNING("Invalid argument\n"); return -ENOEXEC; } params.type = WIFI_PS_PARAM_STATE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "PS %s failed. Reason: %s\n", - params.enabled ? "enable" : "disable", - wifi_ps_get_config_err_code_str(params.fail_reason)); + PR_WARNING("PS %s failed. Reason: %s\n", + params.enabled ? "enable" : "disable", + wifi_ps_get_config_err_code_str(params.fail_reason)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", wifi_ps_txt(params.enabled)); + PR("%s\n", wifi_ps_txt(params.enabled)); return 0; } @@ -811,25 +981,25 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) context.sh = sh; - if (!strncmp(argv[1], "legacy", 6)) { + if (!strncasecmp(argv[1], "legacy", 6)) { params.mode = WIFI_PS_MODE_LEGACY; - } else if (!strncmp(argv[1], "wmm", 3)) { + } else if (!strncasecmp(argv[1], "WMM", 3)) { params.mode = WIFI_PS_MODE_WMM; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid PS mode\n"); + PR_WARNING("Invalid PS mode\n"); return -ENOEXEC; } params.type = WIFI_PS_PARAM_MODE; 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_get_config_err_code_str(params.fail_reason)); + PR_WARNING("%s failed Reason : %s\n", + 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_mode_txt(params.mode)); + PR("%s\n", wifi_ps_mode_txt(params.mode)); return 0; } @@ -854,23 +1024,22 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] params.type = WIFI_PS_PARAM_TIMEOUT; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "Setting PS timeout failed. Reason : %s\n", - wifi_ps_get_config_err_code_str(params.fail_reason)); + PR_WARNING("Setting PS timeout failed. Reason : %s\n", + wifi_ps_get_config_err_code_str(params.fail_reason)); return -ENOEXEC; } if (params.timeout_ms) { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", params.timeout_ms); + PR("PS timeout: %d ms\n", params.timeout_ms); } else { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + PR("PS timeout: disabled\n"); } return 0; } static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, - char *argv[]) + char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; @@ -879,12 +1048,6 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, context.sh = sh; - if (argc != 3) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); - shell_help(sh); - return -ENOEXEC; - } - /* Sensible defaults */ params.operation = WIFI_TWT_SETUP; params.negotiation_type = WIFI_TWT_INDIVIDUAL; @@ -907,22 +1070,21 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.setup.twt_interval = (uint64_t)value; 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_get_err_code_str(params.fail_reason)); + PR_WARNING("%s with %s failed, reason : %s\n", + 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_operation_txt(params.operation), - params.dialog_token, params.flow_id); + PR("TWT operation %s with dg: %d, flow_id: %d requested\n", + wifi_twt_operation_txt(params.operation), + params.dialog_token, params.flow_id); return 0; } - static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, char *argv[]) { @@ -933,12 +1095,6 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, context.sh = sh; - if (argc != 11) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); - shell_help(sh); - return -ENOEXEC; - } - params.operation = WIFI_TWT_SETUP; if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_INDIVIDUAL, @@ -993,24 +1149,29 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, } params.setup.twt_interval = (uint64_t)value; + if (!parse_number(sh, &value, argv[idx++], 0, WIFI_MAX_TWT_WAKE_AHEAD_DURATION_US)) { + return -EINVAL; + } + params.setup.twt_wake_ahead_duration = (uint32_t)value; + 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_get_err_code_str(params.fail_reason)); + PR_WARNING("%s with %s failed. reason : %s\n", + 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_operation_txt(params.operation), - params.dialog_token, params.flow_id); + PR("TWT operation %s with dg: %d, flow_id: %d requested\n", + wifi_twt_operation_txt(params.operation), + params.dialog_token, params.flow_id); return 0; } static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, - char *argv[]) + char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; @@ -1019,12 +1180,6 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, context.sh = sh; int idx = 1; - if (argc != 5) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); - shell_help(sh); - return -ENOEXEC; - } - params.operation = WIFI_TWT_TEARDOWN; if (!parse_number(sh, &value, argv[idx++], WIFI_TWT_INDIVIDUAL, @@ -1050,23 +1205,23 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, params.flow_id = (uint8_t)value; 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_get_err_code_str(params.fail_reason)); + PR_WARNING("%s with %s failed, reason : %s\n", + 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_operation_txt(params.operation), - params.dialog_token, params.flow_id); + PR("TWT operation %s with dg: %d, flow_id: %d success\n", + wifi_twt_operation_txt(params.operation), + params.dialog_token, params.flow_id); return 0; } static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, - char *argv[]) + char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; @@ -1077,16 +1232,16 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, params.teardown.teardown_all = 1; 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_get_err_code_str(params.fail_reason)); + PR_WARNING("%s with %s failed, reason : %s\n", + 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_operation_txt(params.operation)); + PR("TWT operation %s all flows success\n", + wifi_twt_operation_txt(params.operation)); return 0; } @@ -1098,21 +1253,22 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, static struct wifi_connect_req_params cnx_params; int ret; - if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params)) { + context.sh = sh; + if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params, WIFI_MODE_AP)) { shell_help(sh); return -ENOEXEC; } - 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)); + sizeof(struct wifi_connect_req_params)); if (ret) { - shell_fprintf(sh, SHELL_WARNING, "AP mode enable failed: %s\n", strerror(-ret)); + PR_WARNING("AP mode enable failed: %s\n", strerror(-ret)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode enabled\n"); + PR("AP mode enable requested\n"); return 0; } @@ -1125,30 +1281,100 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, ret = net_mgmt(NET_REQUEST_WIFI_AP_DISABLE, iface, NULL, 0); if (ret) { - shell_fprintf(sh, SHELL_WARNING, "AP mode disable failed: %s\n", strerror(-ret)); + PR_WARNING("AP mode disable failed: %s\n", strerror(-ret)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "AP mode disabled\n"); + PR("AP mode disable requested\n"); + 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); + + PR("AP stations:\n"); + PR("============\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; + + PR("Station %zu:\n", id++); + PR("==========\n"); + PR("MAC: %s\n", + net_sprint_ll_addr_buf(sta->mac, + WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf))); + PR("Link mode: %s\n", + wifi_link_mode_txt(sta->link_mode)); + PR("TWT: %s\n", + sta->twt_capable ? "Supported" : "Not supported"); + } + + if (id == 1) { + PR("No stations connected\n"); + } + k_mutex_unlock(&wifi_ap_sta_list_lock); return 0; } +static int cmd_wifi_ap_sta_disconnect(const struct shell *sh, size_t argc, + char *argv[]) +{ + struct net_if *iface = net_if_get_first_wifi(); + uint8_t mac[6]; + int ret; + + if (argc != 2) { + shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + shell_help(sh); + return -ENOEXEC; + } + + if (net_bytes_from_str(mac, sizeof(mac), argv[1]) < 0) { + PR_WARNING("Invalid MAC address\n"); + return -ENOEXEC; + } + + ret = net_mgmt(NET_REQUEST_WIFI_AP_STA_DISCONNECT, iface, mac, sizeof(mac)); + if (ret) { + PR_WARNING("AP station disconnect failed: %s\n", + strerror(-ret)); + return -ENOEXEC; + } + + PR("AP station disconnect requested\n"); + return 0; +} static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_reg_domain regd = {0}; - int ret; + int ret, chan_idx = 0; if (argc == 1) { + (®d)->chan_info = &chan_info[0]; regd.oper = WIFI_MGMT_GET; } else if (argc >= 2 && argc <= 3) { regd.oper = WIFI_MGMT_SET; if (strlen(argv[1]) != 2) { - shell_fprintf(sh, SHELL_WARNING, - "Invalid reg domain: Length should be two letters/digits\n"); + PR_WARNING("Invalid reg domain: Length should be two letters/digits\n"); return -ENOEXEC; } @@ -1156,8 +1382,7 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, if (((argv[1][0] < 'A' || argv[1][0] > 'Z') || (argv[1][1] < 'A' || argv[1][1] > 'Z')) && (argv[1][0] != '0' || argv[1][1] != '0')) { - shell_fprintf(sh, SHELL_WARNING, "Invalid reg domain %c%c\n", argv[1][0], - argv[1][1]); + PR_WARNING("Invalid reg domain %c%c\n", argv[1][0], argv[1][1]); return -ENOEXEC; } regd.country_code[0] = argv[1][0]; @@ -1167,7 +1392,7 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, if (strncmp(argv[2], "-f", 2) == 0) { regd.force = true; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid option %s\n", argv[2]); + PR_WARNING("Invalid option %s\n", argv[2]); return -ENOEXEC; } } @@ -1179,17 +1404,28 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, ret = net_mgmt(NET_REQUEST_WIFI_REG_DOMAIN, iface, ®d, sizeof(regd)); if (ret) { - shell_fprintf(sh, SHELL_WARNING, "Cannot %s Regulatory domain: %d\n", - regd.oper == WIFI_MGMT_GET ? "get" : "set", ret); + PR_WARNING("Cannot %s Regulatory domain: %d\n", + regd.oper == WIFI_MGMT_GET ? "get" : "set", ret); return -ENOEXEC; } if (regd.oper == WIFI_MGMT_GET) { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi Regulatory domain is: %c%c\n", - regd.country_code[0], regd.country_code[1]); + PR("Wi-Fi Regulatory domain is: %c%c\n", + regd.country_code[0], regd.country_code[1]); + PR("\t
\t\t" + "\t\t\n"); + for (chan_idx = 0; chan_idx < regd.num_channels; chan_idx++) { + PR(" %d\t\t\t\%d\t\t\t\%s\t\t\t%d\t\t\t%s\t\t\t\t%s\n", + wifi_freq_to_channel(chan_info[chan_idx].center_frequency), + chan_info[chan_idx].center_frequency, + chan_info[chan_idx].supported ? "y" : "n", + chan_info[chan_idx].max_power, + chan_info[chan_idx].passive_only ? "y" : "n", + chan_info[chan_idx].dfs ? "y" : "n"); + } } else { - shell_fprintf(sh, SHELL_NORMAL, "Wi-Fi Regulatory domain set to: %c%c\n", - regd.country_code[0], regd.country_code[1]); + PR("Wi-Fi Regulatory domain set to: %c%c\n", + regd.country_code[0], regd.country_code[1]); } return 0; @@ -1215,21 +1451,17 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { if (params.fail_reason == WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID) { - shell_fprintf(sh, SHELL_WARNING, - "Setting listen interval failed. Reason :%s\n", - wifi_ps_get_config_err_code_str(params.fail_reason)); - shell_fprintf(sh, SHELL_WARNING, - "Hardware support valid range : 3 - 65535\n"); - } else { - shell_fprintf(sh, SHELL_WARNING, - "Setting listen interval failed. Reason :%s\n", - wifi_ps_get_config_err_code_str(params.fail_reason)); + PR_WARNING("Setting listen interval failed. Reason :%s\n", + wifi_ps_get_config_err_code_str(params.fail_reason)); + PR_WARNING("Hardware support valid range : 3 - 65535\n"); + } else { + PR_WARNING("Setting listen interval failed. Reason :%s\n", + wifi_ps_get_config_err_code_str(params.fail_reason)); } return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, - "Listen interval %hu\n", params.listen_interval); + PR("Listen interval %hu\n", params.listen_interval); return 0; } @@ -1241,29 +1473,26 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar context.sh = sh; - if (!strncmp(argv[1], "dtim", 4)) { + if (!strncasecmp(argv[1], "dtim", 4)) { params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM; - } else if (!strncmp(argv[1], "listen_interval", 15)) { + } else if (!strncasecmp(argv[1], "listen_interval", 15)) { params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); - shell_fprintf(sh, SHELL_INFO, - "Valid argument : / \n"); + PR_WARNING("Invalid argument\n"); + PR_INFO("Valid argument : / \n"); return -ENOEXEC; } params.type = WIFI_PS_PARAM_WAKEUP_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "Setting PS wake up mode to %s failed..Reason :%s\n", - params.wakeup_mode ? "Listen interval" : "DTIM interval", - wifi_ps_get_config_err_code_str(params.fail_reason)); + PR_WARNING("Setting PS wake up mode to %s failed..Reason :%s\n", + params.wakeup_mode ? "Listen interval" : "DTIM interval", + wifi_ps_get_config_err_code_str(params.fail_reason)); return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "%s\n", - wifi_ps_wakeup_mode_txt(params.wakeup_mode)); + PR("%s\n", wifi_ps_wakeup_mode_txt(params.wakeup_mode)); return 0; } @@ -1275,11 +1504,9 @@ 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'}, - {"promiscuous", no_argument, 0, 'p'}, {"ap", no_argument, 0, 'a'}, {"softap", no_argument, 0, 'k'}, {"get", no_argument, 0, 'g'}, @@ -1294,12 +1521,6 @@ void parse_mode_args_to_params(const struct shell *sh, int argc, 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; @@ -1334,7 +1555,7 @@ static int cmd_wifi_mode(const struct shell *sh, size_t argc, char *argv[]) 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"); + PR_ERROR("Invalid number of arguments\n"); return -EINVAL; } @@ -1345,17 +1566,15 @@ static int cmd_wifi_mode(const struct shell *sh, size_t argc, char *argv[]) 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"); + PR_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); + PR_ERROR("Cannot find interface for if_index %d\n", + mode_info.if_index); return -ENOEXEC; } } @@ -1363,16 +1582,15 @@ static int cmd_wifi_mode(const struct shell *sh, size_t argc, char *argv[]) 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); + PR_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); + PR("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); + PR("Wi-Fi mode set to %x\n", mode_info.mode); } } return 0; @@ -1385,13 +1603,13 @@ 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'}, {0, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "i:c:gh", long_options, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "i:c:gh", long_options, &option_index)) != -1) { switch (opt) { case 'c': channel->channel = (uint16_t)atoi(optarg); @@ -1420,13 +1638,8 @@ static int cmd_wifi_channel(const struct shell *sh, size_t argc, char *argv[]) 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; - } + channel_info.oper = WIFI_MGMT_SET; + parse_channel_args_to_params(sh, argc, argv, &channel_info, &do_channel_oper); if (do_channel_oper) { /* @@ -1439,17 +1652,15 @@ static int cmd_wifi_channel(const struct shell *sh, size_t argc, char *argv[]) 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"); + PR_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); + PR_ERROR("Cannot find interface for if_index %d\n", + channel_info.if_index); return -ENOEXEC; } } @@ -1457,28 +1668,24 @@ static int cmd_wifi_channel(const struct shell *sh, size_t argc, char *argv[]) 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"); + PR_ERROR("Invalid channel number. Range is (1-233)\n"); return -ENOEXEC; } } - ret = net_mgmt(NET_REQUEST_WIFI_CHANNEL, iface, - &channel_info, sizeof(channel_info)); + 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); + PR_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); + PR("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); + PR("Wi-Fi channel set to %d\n", channel_info.channel); } } return 0; @@ -1491,8 +1698,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'}, @@ -1501,7 +1708,7 @@ void parse_filter_args_to_params(const struct shell *sh, int argc, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((opt = getopt_long(argc, argv, "i:b:amcdgh", long_options, &option_index)) != -1) { + while ((opt = getopt_long(argc, argv, "i:b:amcdgh", long_options, &option_index)) != -1) { switch (opt) { case 'a': filter->filter |= WIFI_PACKET_FILTER_ALL; @@ -1542,13 +1749,8 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg 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; - } + packet_filter.oper = WIFI_MGMT_SET; + parse_filter_args_to_params(sh, argc, argv, &packet_filter, &do_filter_oper); if (do_filter_oper) { /* @@ -1561,180 +1763,226 @@ static int cmd_wifi_packet_filter(const struct shell *sh, size_t argc, char *arg 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"); + PR_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); + PR_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)); + 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); + PR_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); + PR("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); + PR("Wi-Fi mode packet filter set to %d\n", + packet_filter.filter); } } return 0; } +static int cmd_wifi_version(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_first_wifi(); + struct wifi_version version = {0}; + + if (argc > 1) { + PR_WARNING("Invalid number of arguments\n"); + return -ENOEXEC; + } + + if (net_mgmt(NET_REQUEST_WIFI_VERSION, iface, &version, sizeof(version))) { + PR_WARNING("Failed to get Wi-Fi versions\n"); + return -ENOEXEC; + } + + PR("Wi-Fi Driver Version: %s\n", version.drv_version); + PR("Wi-Fi Firmware Version: %s\n", version.fw_version); + + return 0; +} + SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, - SHELL_CMD(disable, NULL, - "Disable Access Point mode", - cmd_wifi_ap_disable), - SHELL_CMD(enable, NULL, " [channel] [PSK]", - cmd_wifi_ap_enable), + SHELL_CMD_ARG(disable, NULL, + "Disable Access Point mode.\n", + cmd_wifi_ap_disable, + 1, 0), + SHELL_CMD_ARG(enable, NULL, + "\"\"\n" + "\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.\n", + cmd_wifi_ap_enable, + 3, 3), + SHELL_CMD_ARG(stations, NULL, + "List stations connected to the AP", + cmd_wifi_ap_stations, + 1, 0), + SHELL_CMD_ARG(disconnect, NULL, + "Disconnect a station from the AP\n" + "\n", + cmd_wifi_ap_sta_disconnect, + 2, 0), SHELL_SUBCMD_SET_END ); SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, - SHELL_CMD(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" + SHELL_CMD_ARG(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" "\n" "\n" " " - " \n", - cmd_wifi_twt_setup), - SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" + " .\n" + ": 0us-2^31us>\n", + cmd_wifi_twt_setup, + 12, 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), + " .\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), 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(version, NULL, "Print Wi-Fi Driver and Firmware versions\n", + cmd_wifi_version, + 1, 0), + 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" - "\n" - "\n" - "\n" - "0:None, 1:PSK, 2:PSK-256, 3:SAE\n" - "\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), + "[channel number/band: > 0:Channel, 0:any channel,\n" + "< 0:band (-2:2.4GHz, -5:5GHz, -6:6GHz]\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.\n", + cmd_wifi_connect, + 2, 4), + 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", + cmd_wifi_ps, + 1, 1), SHELL_CMD_ARG(ps_mode, NULL, - "\n" - "", + ".\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" - "[-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.", - 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(reg_domain, NULL, + "[-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_5:36 or 2:1,6-11,14_5:36,163-177,52. Care should be taken to ensure that configured channels don't exceed CONFIG_WIFI_MGMT_SCAN_CHAN_MAX_MANUAL\n" + "[-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.\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" - "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" + "[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", + 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" - "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" + "[-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", - cmd_wifi_mode), - SHELL_CMD(packet_filter, NULL, "mode filter setting\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" - "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" - "wifi packet_filter -i1 -md\n", - cmd_wifi_packet_filter), - SHELL_CMD(channel, NULL, "wifi channel setting\n" + "wifi packet_filter -i1 -md.\n", + cmd_wifi_packet_filter, + 2, 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" - "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" - "wifi -i1 -c5\n", - cmd_wifi_channel), + "wifi -i1 -c5.\n", + cmd_wifi_channel, + 2, 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, - " : 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), @@ -1748,7 +1996,7 @@ static int wifi_shell_init(void) context.sh = NULL; context.all = 0U; - scan_result = 0U; + context.scan_result = 0U; net_mgmt_init_event_callback(&wifi_shell_mgmt_cb, wifi_mgmt_event_handler, diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 52d25d90566..01c4bf1ea81 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -44,7 +44,7 @@ static enum wifi_frequency_bands wifi_utils_map_band_str_to_idx(char *band_str) } -static bool wifi_utils_validate_chan_2g(uint16_t chan) +bool wifi_utils_validate_chan_2g(uint16_t chan) { if ((chan >= 1) && (chan <= 14)) { return true; @@ -54,7 +54,7 @@ static bool wifi_utils_validate_chan_2g(uint16_t chan) } -static bool wifi_utils_validate_chan_5g(uint16_t chan) +bool wifi_utils_validate_chan_5g(uint16_t chan) { uint16_t i; @@ -68,7 +68,7 @@ static bool wifi_utils_validate_chan_5g(uint16_t chan) } -static bool wifi_utils_validate_chan_6g(uint16_t chan) +bool wifi_utils_validate_chan_6g(uint16_t chan) { if (((chan >= 1) && (chan <= 233) && (!((chan - 1)%4))) || (chan == 2)) { @@ -79,7 +79,7 @@ static bool wifi_utils_validate_chan_6g(uint16_t chan) } -static bool wifi_utils_validate_chan(uint8_t band, +bool wifi_utils_validate_chan(uint8_t band, uint16_t chan) { bool result = false; @@ -241,8 +241,7 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) return -EINVAL; } - strncpy(parse_str, scan_bands_str, len); - parse_str[len] = '\0'; + strncpy(parse_str, scan_bands_str, sizeof(parse_str)); band_str = strtok_r(parse_str, ",", &ctx); @@ -368,7 +367,7 @@ 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) { + if ((chan_idx + (chan_val - chan_start)) > max_channels) { NET_ERR("Too many channels specified (%d)", max_channels); return -EINVAL; } diff --git a/subsys/net/lib/CMakeLists.txt b/subsys/net/lib/CMakeLists.txt index 756adb41341..e3319f6cd8d 100644 --- a/subsys/net/lib/CMakeLists.txt +++ b/subsys/net/lib/CMakeLists.txt @@ -14,6 +14,8 @@ 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) +add_subdirectory_ifdef(CONFIG_NET_TRICKLE trickle) +add_subdirectory_ifdef(CONFIG_NET_DHCPV4_SERVER dhcpv4) if (CONFIG_DNS_RESOLVER OR CONFIG_MDNS_RESPONDER diff --git a/subsys/net/lib/Kconfig b/subsys/net/lib/Kconfig index 5df4a445885..6cfa0445241 100644 --- a/subsys/net/lib/Kconfig +++ b/subsys/net/lib/Kconfig @@ -39,6 +39,10 @@ menu "Network additional services" source "subsys/net/lib/capture/Kconfig" +source "subsys/net/lib/dhcpv4/Kconfig" + +source "subsys/net/lib/trickle/Kconfig" + source "subsys/net/lib/zperf/Kconfig" endmenu diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 8e62983ea72..63396bb0518 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -82,6 +82,13 @@ config COAP_MAX_RETRANSMIT default 4 range 1 10 +config COAP_BACKOFF_PERCENT + int "Retransmission backoff factor for ACK timeout described as percentage" + default 200 + help + Factor described as percentage to extend CoAP ACK timeout for retransmissions. + A value of 200 means a factor of 2.0. + config COAP_URI_WILDCARD bool "Wildcards in CoAP resource path" default y @@ -89,12 +96,6 @@ 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 @@ -201,12 +202,6 @@ config COAP_SERVICE_PENDING_MESSAGES 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 diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index 9fe62730b47..d22ee29bea7 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL); #include #include #include +#include #define COAP_PATH_ELEM_DELIM '/' #define COAP_PATH_ELEM_QUERY '?' @@ -53,6 +54,12 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL); /* The CoAP message ID that is incremented each time coap_next_id() is called. */ static uint16_t message_id; +static struct coap_transmission_parameters coap_transmission_params = { + .max_retransmission = CONFIG_COAP_MAX_RETRANSMIT, + .ack_timeout = CONFIG_COAP_INIT_ACK_TIMEOUT_MS, + .coap_backoff_percent = CONFIG_COAP_BACKOFF_PERCENT +}; + static int insert_option(struct coap_packet *cpkt, uint16_t code, const uint8_t *value, uint16_t len); @@ -1546,7 +1553,7 @@ size_t coap_next_block(const struct coap_packet *cpkt, int coap_pending_init(struct coap_pending *pending, const struct coap_packet *request, const struct sockaddr *addr, - uint8_t retries) + const struct coap_transmission_parameters *params) { memset(pending, 0, sizeof(*pending)); @@ -1554,10 +1561,16 @@ int coap_pending_init(struct coap_pending *pending, memcpy(&pending->addr, addr, sizeof(*addr)); + if (params) { + pending->params = *params; + } else { + pending->params = coap_transmission_params; + } + pending->data = request->data; pending->len = request->offset; pending->t0 = k_uptime_get(); - pending->retries = retries; + pending->retries = pending->params.max_retransmission; return 0; } @@ -1669,12 +1682,12 @@ struct coap_pending *coap_pending_next_to_expire( return found; } -static uint32_t init_ack_timeout(void) +static uint32_t init_ack_timeout(const struct coap_transmission_parameters *params) { #if defined(CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT) - const uint32_t max_ack = CONFIG_COAP_INIT_ACK_TIMEOUT_MS * + const uint32_t max_ack = params->ack_timeout * CONFIG_COAP_ACK_RANDOM_PERCENT / 100; - const uint32_t min_ack = CONFIG_COAP_INIT_ACK_TIMEOUT_MS; + const uint32_t min_ack = params->ack_timeout; /* Randomly generated initial ACK timeout * ACK_TIMEOUT < INIT_ACK_TIMEOUT < ACK_TIMEOUT * ACK_RANDOM_FACTOR @@ -1682,7 +1695,7 @@ static uint32_t init_ack_timeout(void) */ return min_ack + (sys_rand32_get() % (max_ack - min_ack)); #else - return CONFIG_COAP_INIT_ACK_TIMEOUT_MS; + return params->ack_timeout; #endif /* defined(CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT) */ } @@ -1690,8 +1703,7 @@ bool coap_pending_cycle(struct coap_pending *pending) { if (pending->timeout == 0) { /* Initial transmission. */ - pending->timeout = init_ack_timeout(); - + pending->timeout = init_ack_timeout(&pending->params); return true; } @@ -1700,7 +1712,7 @@ bool coap_pending_cycle(struct coap_pending *pending) } pending->t0 += pending->timeout; - pending->timeout = pending->timeout << 1; + pending->timeout = pending->timeout * pending->params.coap_backoff_percent / 100; pending->retries--; return true; @@ -1722,6 +1734,19 @@ void coap_pendings_clear(struct coap_pending *pendings, size_t len) } } +size_t coap_pendings_count(struct coap_pending *pendings, size_t len) +{ + struct coap_pending *p = pendings; + size_t c = 0; + + for (size_t i = 0; i < len && p; i++, p++) { + if (p->timeout) { + c++; + } + } + return c; +} + /* Reordering according to RFC7641 section 3.4 but without timestamp comparison */ static inline bool is_newer(int v1, int v2) { @@ -1844,6 +1869,25 @@ void coap_observer_init(struct coap_observer *observer, net_ipaddr_copy(&observer->addr, addr); } +static inline void coap_observer_raise_event(struct coap_resource *resource, + struct coap_observer *observer, + uint32_t mgmt_event) +{ +#ifdef CONFIG_NET_MGMT_EVENT_INFO + const struct net_event_coap_observer net_event = { + .resource = resource, + .observer = observer, + }; + + net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event)); +#else + ARG_UNUSED(resource); + ARG_UNUSED(observer); + + net_mgmt_event_notify(mgmt_event, NULL); +#endif +} + bool coap_register_observer(struct coap_resource *resource, struct coap_observer *observer) { @@ -1856,11 +1900,7 @@ 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 + coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_ADDED); return first; } @@ -1872,11 +1912,8 @@ bool coap_remove_observer(struct coap_resource *resource, return false; } -#ifdef CONFIG_COAP_OBSERVER_EVENTS - if (resource->observer_event_handler) { - resource->observer_event_handler(resource, observer, COAP_OBSERVER_REMOVED); - } -#endif + coap_observer_raise_event(resource, observer, NET_EVENT_COAP_OBSERVER_REMOVED); + return true; } @@ -1993,3 +2030,13 @@ uint16_t coap_next_id(void) { return message_id++; } + +struct coap_transmission_parameters coap_get_transmission_parameters(void) +{ + return coap_transmission_params; +} + +void coap_set_transmission_parameters(const struct coap_transmission_parameters *params) +{ + coap_transmission_params = *params; +} diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index a947b15ae8e..4bdf387a242 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -16,7 +16,6 @@ LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); #define COAP_VERSION 1 #define COAP_SEPARATE_TIMEOUT 6000 #define COAP_PERIODIC_TIMEOUT 500 -#define DEFAULT_RETRY_AMOUNT 5 #define BLOCK1_OPTION_SIZE 4 #define PAYLOAD_MARKER_SIZE 1 @@ -60,7 +59,6 @@ static void reset_internal_request(struct coap_client_internal_request *request) { request->offset = 0; request->last_id = 0; - request->retry_count = 0; reset_block_contexts(request); } @@ -277,7 +275,7 @@ static int coap_client_init_request(struct coap_client *client, } int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries) + struct coap_client_request *req, struct coap_transmission_parameters *params) { int ret; @@ -352,14 +350,8 @@ int coap_client_req(struct coap_client *client, int sock, const struct sockaddr /* 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); + &client->address, params); if (ret < 0) { LOG_ERR("Failed to initialize pending struct"); @@ -692,9 +684,11 @@ static int handle_response(struct coap_client *client, const struct coap_packet } if (coap_header_get_type(&internal_req->request) == COAP_TYPE_CON) { + struct coap_transmission_parameters params = + internal_req->pending.params; ret = coap_pending_init(&internal_req->pending, &internal_req->request, &client->address, - internal_req->retry_count); + ¶ms); if (ret < 0) { LOG_ERR("Error creating pending"); k_mutex_unlock(&client->send_mutex); @@ -793,8 +787,9 @@ static int handle_response(struct coap_client *client, const struct coap_packet goto fail; } + struct coap_transmission_parameters params = internal_req->pending.params; ret = coap_pending_init(&internal_req->pending, &internal_req->request, - &client->address, internal_req->retry_count); + &client->address, ¶ms); if (ret < 0) { LOG_ERR("Error creating pending"); k_mutex_unlock(&client->send_mutex); diff --git a/subsys/net/lib/coap/coap_server.c b/subsys/net/lib/coap/coap_server.c index 4b4f1719f46..28d5b8de47f 100644 --- a/subsys/net/lib/coap/coap_server.c +++ b/subsys/net/lib/coap/coap_server.c @@ -14,6 +14,7 @@ LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); #include #include #include +#include #include #ifdef CONFIG_ARCH_POSIX #include @@ -214,12 +215,25 @@ static int coap_server_process(int sock_fd) goto unlock; } - ret = coap_service_send(service, &response, &client_addr, client_addr_len); + ret = coap_service_send(service, &response, &client_addr, client_addr_len, NULL); } else { ret = coap_handle_request_len(&request, service->res_begin, COAP_SERVICE_RESOURCE_COUNT(service), options, opt_num, &client_addr, client_addr_len); + /* Translate errors to response codes */ + switch (ret) { + case -ENOENT: + ret = COAP_RESPONSE_CODE_NOT_FOUND; + break; + case -ENOTSUP: + ret = COAP_RESPONSE_CODE_BAD_REQUEST; + break; + case -EPERM: + ret = COAP_RESPONSE_CODE_NOT_ALLOWED; + break; + } + /* Shortcut for replying a code without a body */ if (ret > 0 && type == COAP_TYPE_CON) { /* Minimal sized ack buffer */ @@ -232,7 +246,7 @@ static int coap_server_process(int sock_fd) goto unlock; } - ret = coap_service_send(service, &ack, &client_addr, client_addr_len); + ret = coap_service_send(service, &ack, &client_addr, client_addr_len, NULL); } } @@ -332,6 +346,21 @@ static inline bool coap_service_in_section(const struct coap_service *service) STRUCT_SECTION_END(coap_service) > service; } +static inline void coap_service_raise_event(const struct coap_service *service, uint32_t mgmt_event) +{ +#if defined(CONFIG_NET_MGMT_EVENT_INFO) + const struct net_event_coap_service net_event = { + .service = service, + }; + + net_mgmt_event_notify_with_info(mgmt_event, NULL, (void *)&net_event, sizeof(net_event)); +#else + ARG_UNUSED(service); + + net_mgmt_event_notify(mgmt_event, NULL); +#endif +} + int coap_service_start(const struct coap_service *service) { int ret; @@ -433,6 +462,8 @@ int coap_service_start(const struct coap_service *service) coap_server_update_services(); + coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STARTED); + return ret; close: @@ -456,22 +487,42 @@ int coap_service_stop(const struct coap_service *service) k_mutex_lock(&lock, K_FOREVER); if (service->data->sock_fd < 0) { - ret = -EALREADY; - goto end; + k_mutex_unlock(&lock); + return -EALREADY; } /* 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); + + coap_service_raise_event(service, NET_EVENT_COAP_SERVICE_STOPPED); + + return ret; +} + +int coap_service_is_running(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); + + ret = (service->data->sock_fd < 0) ? 0 : 1; + 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) + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params) { int ret; @@ -500,8 +551,7 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack goto send; } - ret = coap_pending_init(pending, cpkt, addr, - CONFIG_COAP_SERVICE_PENDING_RETRANSMITS); + ret = coap_pending_init(pending, cpkt, addr, params); if (ret < 0) { LOG_WRN("Failed to init pending message for %s (%d)", service->name, ret); goto send; @@ -536,12 +586,13 @@ int coap_service_send(const struct coap_service *service, const struct coap_pack } int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt, - const struct sockaddr *addr, socklen_t addr_len) + const struct sockaddr *addr, socklen_t addr_len, + const struct coap_transmission_parameters *params) { /* Find owning service */ COAP_SERVICE_FOREACH(svc) { if (COAP_SERVICE_HAS_RESOURCE(svc, resource)) { - return coap_service_send(svc, cpkt, addr, addr_len); + return coap_service_send(svc, cpkt, addr, addr_len, params); } } @@ -694,9 +745,6 @@ static void coap_server_thread(void *p1, void *p2, void *p3) } 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) { diff --git a/subsys/net/lib/dhcpv4/CMakeLists.txt b/subsys/net/lib/dhcpv4/CMakeLists.txt new file mode 100644 index 00000000000..348b6c99bb7 --- /dev/null +++ b/subsys/net/lib/dhcpv4/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip) + +zephyr_library_sources( + dhcpv4_server.c + ) diff --git a/subsys/net/lib/dhcpv4/Kconfig b/subsys/net/lib/dhcpv4/Kconfig new file mode 100644 index 00000000000..34125b6066c --- /dev/null +++ b/subsys/net/lib/dhcpv4/Kconfig @@ -0,0 +1,68 @@ +# DHCPv4 server implementation for Zephyr + +# Copyright (c) 2024 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +config NET_DHCPV4_SERVER + bool "DHCPv4 server" + depends on NET_IPV4 && NET_UDP + select NET_SOCKETS + select NET_SOCKETS_SERVICE + +if NET_DHCPV4_SERVER + +module = NET_DHCPV4_SERVER +module-dep = NET_LOG +module-str = Log level for DHCPv4 server +module-help = Enables DHCPv4 server output debug messages +source "subsys/net/Kconfig.template.log_config.net" + +config NET_DHCPV4_SERVER_INSTANCES + int "Maximum number of DHCPv4 server instances" + default 1 + help + Maximum number of DHCPv4 server instances supported by the system. + Each network interface that wants to act as a DHCPv4 server requires + a separate instance. + +config NET_DHCPV4_SERVER_ADDR_COUNT + int "Number of IPv4 addresses that can be assigned by the server" + default 4 + help + Maximum number of IPv4 addresses that can be assigned by the DHCPv4 + server instance. The base IPv4 address in the address pool is provided + at runtime, during server initialization. Consecutive addresses in the + pool have the lowest address octet incremented. + +config NET_DHCPV4_SERVER_ADDR_LEASE_TIME + int "Lease time for IPv4 addresses assigned by the server (seconds)" + range 0 4294967295 + default 86400 + help + Lease time in seconds for IPv4 addresses assigned by the server. + The lease time determines when the IPv4 address lease expires if the + client does not renew it. + +config NET_DHCPV4_SERVER_ADDR_DECLINE_TIME + int "The time IPv4 addresses remains blocked after conflict detection (seconds)" + range 0 4294967295 + default 86400 + help + In case IPv4 address becomes blocked (either because of receiving + Decline message or due to ICMP probe detecting conflict), the address + can no longer be assigned. This timeout specifies how long the address + remains in the Declined state. + Note, that the server may try to reuse the oldest declined address in + case it runs out of free addresses to assign. + +config NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT + int "Timeout for ICMP probes sent by the server (miliseconds)" + range 0 60000 + default 1000 + help + DHCPv4 server will probe the offered IP address (send ICMP echo + request) and wait for the time specific by this config before offering + the address. If set to 0, ICMP probing will be disabled. + +endif # NET_DHCPV4_SERVER diff --git a/subsys/net/lib/dhcpv4/dhcpv4_server.c b/subsys/net/lib/dhcpv4/dhcpv4_server.c new file mode 100644 index 00000000000..fdaab75c950 --- /dev/null +++ b/subsys/net/lib/dhcpv4/dhcpv4_server.c @@ -0,0 +1,1691 @@ +/** @file + * @brief DHCPv4 server implementation + */ + +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(net_dhcpv4_server, CONFIG_NET_DHCPV4_SERVER_LOG_LEVEL); + +#include "dhcpv4.h" +#include "net_private.h" +#include "../../l2/ethernet/arp.h" + +#define DHCPV4_OPTIONS_MSG_TYPE_SIZE 3 +#define DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE 6 +#define DHCPV4_OPTIONS_SERVER_ID_SIZE 6 +#define DHCPV4_OPTIONS_SUBNET_MASK_SIZE 6 +#define DHCPV4_OPTIONS_CLIENT_ID_MIN_SIZE 2 + +#define ADDRESS_RESERVED_TIMEOUT K_SECONDS(5) +#define ADDRESS_PROBE_TIMEOUT K_MSEC(CONFIG_NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT) +#define ADDRESS_DECLINED_TIMEOUT K_SECONDS(CONFIG_NET_DHCPV4_SERVER_ADDR_DECLINE_TIME) + +#if (CONFIG_NET_DHCPV4_SERVER_ICMP_PROBE_TIMEOUT > 0) +#define DHCPV4_SERVER_ICMP_PROBE 1 +#endif + +/* RFC 1497 [17] */ +static const uint8_t magic_cookie[4] = { 0x63, 0x82, 0x53, 0x63 }; + +#define DHCPV4_MAX_PARAMETERS_REQUEST_LEN 16 + +struct dhcpv4_parameter_request_list { + uint8_t list[DHCPV4_MAX_PARAMETERS_REQUEST_LEN]; + uint8_t count; +}; + +struct dhcpv4_server_probe_ctx { + struct net_icmp_ctx icmp_ctx; + struct dhcp_msg discovery; + struct dhcpv4_parameter_request_list params; + struct dhcpv4_addr_slot *slot; +}; + +struct dhcpv4_server_ctx { + struct net_if *iface; + int sock; + struct k_work_delayable timeout_work; + struct dhcpv4_addr_slot addr_pool[CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT]; + struct in_addr server_addr; + struct in_addr netmask; +#if defined(DHCPV4_SERVER_ICMP_PROBE) + struct dhcpv4_server_probe_ctx probe_ctx; +#endif +}; + +static struct dhcpv4_server_ctx server_ctx[CONFIG_NET_DHCPV4_SERVER_INSTANCES]; +static struct zsock_pollfd fds[CONFIG_NET_DHCPV4_SERVER_INSTANCES]; +static K_MUTEX_DEFINE(server_lock); + +static void dhcpv4_server_timeout_recalc(struct dhcpv4_server_ctx *ctx) +{ + k_timepoint_t next = sys_timepoint_calc(K_FOREVER); + k_timeout_t timeout; + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED || + slot->state == DHCPV4_SERVER_ADDR_DECLINED) { + if (sys_timepoint_cmp(slot->expiry, next) < 0) { + next = slot->expiry; + } + } + } + + timeout = sys_timepoint_timeout(next); + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + LOG_DBG("No more addresses, canceling timer"); + k_work_cancel_delayable(&ctx->timeout_work); + } else { + k_work_reschedule(&ctx->timeout_work, timeout); + } +} + +/* Option parsing. */ + +static uint8_t *dhcpv4_find_option(uint8_t *data, size_t datalen, + uint8_t *optlen, uint8_t opt_code) +{ + uint8_t *opt = NULL; + + while (datalen > 0) { + uint8_t code; + uint8_t len; + + code = *data; + + /* Two special cases (fixed sized options) */ + if (code == 0) { + data++; + datalen--; + continue; + } + + if (code == DHCPV4_OPTIONS_END) { + break; + } + + /* Length field should now follow. */ + if (datalen < 2) { + break; + } + + len = *(data + 1); + + if (datalen < len + 2) { + break; + } + + if (code == opt_code) { + /* Found the option. */ + opt = data + 2; + *optlen = len; + break; + } + + data += len + 2; + datalen -= len + 2; + } + + return opt; +} + +static int dhcpv4_find_message_type_option(uint8_t *data, size_t datalen, + uint8_t *msgtype) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_MSG_TYPE); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != 1) { + return -EINVAL; + } + + *msgtype = *opt; + + return 0; +} + +static int dhcpv4_find_server_id_option(uint8_t *data, size_t datalen, + struct in_addr *server_id) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_SERVER_ID); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(struct in_addr)) { + return -EINVAL; + } + + memcpy(server_id, opt, sizeof(struct in_addr)); + + return 0; +} + +static int dhcpv4_find_client_id_option(uint8_t *data, size_t datalen, + uint8_t *client_id, uint8_t *len) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_CLIENT_ID); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen < DHCPV4_OPTIONS_CLIENT_ID_MIN_SIZE) { + return -EINVAL; + } + + if (optlen > *len) { + LOG_ERR("Not enough memory for DHCPv4 client identifier."); + return -ENOMEM; + } + + memcpy(client_id, opt, optlen); + *len = optlen; + + return 0; +} + +static int dhcpv4_find_requested_ip_option(uint8_t *data, size_t datalen, + struct in_addr *requested_ip) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_REQ_IPADDR); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(struct in_addr)) { + return -EINVAL; + } + + memcpy(requested_ip, opt, sizeof(struct in_addr)); + + return 0; +} + +static int dhcpv4_find_ip_lease_time_option(uint8_t *data, size_t datalen, + uint32_t *lease_time) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_LEASE_TIME); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen != sizeof(uint32_t)) { + return -EINVAL; + } + + *lease_time = sys_get_be32(opt); + + return 0; +} + +static int dhcpv4_find_parameter_request_list_option( + uint8_t *data, size_t datalen, + struct dhcpv4_parameter_request_list *params) +{ + uint8_t *opt; + uint8_t optlen; + + opt = dhcpv4_find_option(data, datalen, &optlen, + DHCPV4_OPTIONS_REQ_LIST); + if (opt == NULL) { + return -ENOENT; + } + + if (optlen > sizeof(params->list)) { + /* Best effort here, copy as much as we can. */ + optlen = sizeof(params->list); + } + + memcpy(params->list, opt, optlen); + params->count = optlen; + + return 0; +} + +/* Option encoding. */ + +static uint8_t *dhcpv4_encode_magic_cookie(uint8_t *buf, size_t *buflen) +{ + if (buf == NULL || *buflen < SIZE_OF_MAGIC_COOKIE) { + return NULL; + } + + memcpy(buf, magic_cookie, SIZE_OF_MAGIC_COOKIE); + + *buflen -= SIZE_OF_MAGIC_COOKIE; + + return buf + SIZE_OF_MAGIC_COOKIE; +} + +static uint8_t *dhcpv4_encode_ip_lease_time_option(uint8_t *buf, size_t *buflen, + uint32_t lease_time) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_LEASE_TIME; + buf[1] = sizeof(lease_time); + sys_put_be32(lease_time, &buf[2]); + + *buflen -= DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE; + + return buf + DHCPV4_OPTIONS_IP_LEASE_TIME_SIZE; +} + +static uint8_t *dhcpv4_encode_message_type_option(uint8_t *buf, size_t *buflen, + uint8_t msgtype) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_MSG_TYPE_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_MSG_TYPE; + buf[1] = 1; + buf[2] = msgtype; + + *buflen -= DHCPV4_OPTIONS_MSG_TYPE_SIZE; + + return buf + DHCPV4_OPTIONS_MSG_TYPE_SIZE; +} + +static uint8_t *dhcpv4_encode_server_id_option(uint8_t *buf, size_t *buflen, + struct in_addr *server_id) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_SERVER_ID_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_SERVER_ID; + buf[1] = sizeof(struct in_addr); + memcpy(&buf[2], server_id->s4_addr, sizeof(struct in_addr)); + + *buflen -= DHCPV4_OPTIONS_SERVER_ID_SIZE; + + return buf + DHCPV4_OPTIONS_SERVER_ID_SIZE; +} + +static uint8_t *dhcpv4_encode_subnet_mask_option(uint8_t *buf, size_t *buflen, + struct in_addr *mask) +{ + if (buf == NULL || *buflen < DHCPV4_OPTIONS_SUBNET_MASK_SIZE) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_SUBNET_MASK; + buf[1] = sizeof(struct in_addr); + memcpy(&buf[2], mask->s4_addr, sizeof(struct in_addr)); + + *buflen -= DHCPV4_OPTIONS_SUBNET_MASK_SIZE; + + return buf + DHCPV4_OPTIONS_SUBNET_MASK_SIZE; +} + +static uint8_t *dhcpv4_encode_end_option(uint8_t *buf, size_t *buflen) +{ + if (buf == NULL || *buflen < 1) { + return NULL; + } + + buf[0] = DHCPV4_OPTIONS_END; + + *buflen -= 1; + + return buf + 1; +} + +/* Response handlers. */ + +static uint8_t *dhcpv4_encode_header(uint8_t *buf, size_t *buflen, + struct dhcp_msg *msg, + struct in_addr *yiaddr) +{ + struct dhcp_msg *reply_msg = (struct dhcp_msg *)buf; + + if (buf == NULL || *buflen < sizeof(struct dhcp_msg)) { + return NULL; + } + + reply_msg->op = DHCPV4_MSG_BOOT_REPLY; + reply_msg->htype = msg->htype; + reply_msg->hlen = msg->hlen; + reply_msg->hops = 0; + reply_msg->xid = msg->xid; + reply_msg->secs = 0; + reply_msg->flags = msg->flags; + memcpy(reply_msg->ciaddr, msg->ciaddr, sizeof(reply_msg->ciaddr)); + if (yiaddr != NULL) { + memcpy(reply_msg->yiaddr, yiaddr, sizeof(struct in_addr)); + } else { + memset(reply_msg->yiaddr, 0, sizeof(reply_msg->ciaddr)); + } + memset(reply_msg->siaddr, 0, sizeof(reply_msg->siaddr)); + memcpy(reply_msg->giaddr, msg->giaddr, sizeof(reply_msg->giaddr)); + memcpy(reply_msg->chaddr, msg->chaddr, sizeof(reply_msg->chaddr)); + + *buflen -= sizeof(struct dhcp_msg); + + return buf + sizeof(struct dhcp_msg); +} + +static uint8_t *dhcpv4_encode_string(uint8_t *buf, size_t *buflen, char *str, + size_t max_len) +{ + if (buf == NULL || *buflen < max_len) { + return NULL; + } + + memset(buf, 0, max_len); + + if (str == NULL) { + goto out; + } + + strncpy(buf, str, max_len - 1); + + out: + *buflen -= max_len; + + return buf + max_len; +} + +static uint8_t *dhcpv4_encode_sname(uint8_t *buf, size_t *buflen, char *sname) +{ + return dhcpv4_encode_string(buf, buflen, sname, SIZE_OF_SNAME); +} + +static uint8_t *dhcpv4_encode_file(uint8_t *buf, size_t *buflen, char *file) +{ + return dhcpv4_encode_string(buf, buflen, file, SIZE_OF_FILE); +} + +static uint8_t *dhcpv4_encode_requested_params( + uint8_t *buf, size_t *buflen, + struct dhcpv4_server_ctx *ctx, + struct dhcpv4_parameter_request_list *params) +{ + for (uint8_t i = 0; i < params->count; i++) { + switch (params->list[i]) { + case DHCPV4_OPTIONS_SUBNET_MASK: + buf = dhcpv4_encode_subnet_mask_option( + buf, buflen, &ctx->netmask); + if (buf == NULL) { + goto out; + } + break; + + /* Others - just ignore. */ + default: + break; + } + } + +out: + return buf; +} + +static int dhcpv4_send(struct dhcpv4_server_ctx *ctx, enum net_dhcpv4_msg_type type, + uint8_t *reply, size_t len, struct dhcp_msg *msg, + struct in_addr *yiaddr) +{ + struct sockaddr_in dst_addr = { + .sin_family = AF_INET, + .sin_port = htons(DHCPV4_CLIENT_PORT), + }; + struct in_addr giaddr; /* Relay agent address */ + struct in_addr ciaddr; /* Client address */ + int ret; + + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + + /* Select destination address as described in ch. 4.1. */ + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* If the 'giaddr' field in a DHCP message from a client is + * non-zero, the server sends any return messages to the + * 'DHCP server' port on the BOOTP relay agent whose address + * appears in 'giaddr'. + */ + dst_addr.sin_addr = giaddr; + dst_addr.sin_port = htons(DHCPV4_SERVER_PORT); + } else if (type == NET_DHCPV4_MSG_TYPE_NAK) { + /* In all cases, when 'giaddr' is zero, the server broadcasts + * any DHCPNAK messages to 0xffffffff. + */ + dst_addr.sin_addr = *net_ipv4_broadcast_address(); + } else if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* If the 'giaddr' field is zero and the 'ciaddr' field is + * nonzero, then the server unicasts DHCPOFFER and DHCPACK + * messages to the address in 'ciaddr'. + */ + dst_addr.sin_addr = ciaddr; + } else if (ntohs(msg->flags) & DHCPV4_MSG_BROADCAST) { + /* If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast + * bit is set, then the server broadcasts DHCPOFFER and DHCPACK + * messages to 0xffffffff. + */ + dst_addr.sin_addr = *net_ipv4_broadcast_address(); + } else if (yiaddr != NULL) { + /* If the broadcast bit is not set and 'giaddr' is zero and + * 'ciaddr' is zero, then the server unicasts DHCPOFFER and + * DHCPACK messages to the client's hardware address and 'yiaddr' + * address. + */ + struct net_eth_addr hwaddr; + + memcpy(&hwaddr, msg->chaddr, sizeof(hwaddr)); + net_arp_update(ctx->iface, yiaddr, &hwaddr, false, true); + dst_addr.sin_addr = *yiaddr; + } else { + NET_ERR("Unspecified destination address."); + return -EDESTADDRREQ; + } + + ret = zsock_sendto(ctx->sock, reply, len, 0, (struct sockaddr *)&dst_addr, + sizeof(dst_addr)); + if (ret < 0) { + return -errno; + } + + return 0; +} + +static int dhcpv4_send_offer(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg, + struct in_addr *addr, uint32_t lease_time, + struct dhcpv4_parameter_request_list *params) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, addr); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + buf = dhcpv4_encode_ip_lease_time_option(buf, &buflen, lease_time); + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_OFFER); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_requested_params(buf, &buflen, ctx, params); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "Offer"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_OFFER, reply, reply_len, + msg, addr); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "Offer", ret); + return ret; + } + + return 0; +} + +static int dhcpv4_send_ack(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg, + struct in_addr *addr, uint32_t lease_time, + struct dhcpv4_parameter_request_list *params, + bool inform) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, inform ? NULL : addr); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + if (!inform) { + buf = dhcpv4_encode_ip_lease_time_option(buf, &buflen, lease_time); + } + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_ACK); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_requested_params(buf, &buflen, ctx, params); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "ACK"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_ACK, reply, reply_len, msg, + addr); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "ACK", ret); + return ret; + } + + return 0; +} + +static int dhcpv4_send_nak(struct dhcpv4_server_ctx *ctx, struct dhcp_msg *msg) +{ + uint8_t reply[NET_IPV4_MTU]; + uint8_t *buf = reply; + size_t buflen = sizeof(reply); + size_t reply_len = 0; + int ret; + + buf = dhcpv4_encode_header(buf, &buflen, msg, NULL); + buf = dhcpv4_encode_sname(buf, &buflen, NULL); + buf = dhcpv4_encode_file(buf, &buflen, NULL); + buf = dhcpv4_encode_magic_cookie(buf, &buflen); + buf = dhcpv4_encode_message_type_option(buf, &buflen, + NET_DHCPV4_MSG_TYPE_NAK); + buf = dhcpv4_encode_server_id_option(buf, &buflen, &ctx->server_addr); + buf = dhcpv4_encode_end_option(buf, &buflen); + + if (buf == NULL) { + LOG_ERR("Failed to encode %s message", "NAK"); + return -ENOMEM; + } + + reply_len = sizeof(reply) - buflen; + + ret = dhcpv4_send(ctx, NET_DHCPV4_MSG_TYPE_NAK, reply, reply_len, msg, + NULL); + if (ret < 0) { + LOG_ERR("Failed to send %s message, %d", "NAK", ret); + return ret; + } + + return 0; +} + +/* Message handlers. */ + +static int dhcpv4_get_client_id(struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen, struct dhcpv4_client_id *client_id) +{ + int ret; + + client_id->len = sizeof(client_id->buf); + + ret = dhcpv4_find_client_id_option(options, optlen, client_id->buf, + &client_id->len); + if (ret == 0) { + return 0; + } + + /* No Client Id option or too long to use, fallback to hardware address. */ + if (msg->hlen > sizeof(msg->chaddr)) { + LOG_ERR("Malformed chaddr length."); + return -EINVAL; + } + + client_id->buf[0] = msg->htype; + client_id->buf[1] = msg->hlen; + memcpy(client_id->buf + 2, msg->chaddr, msg->hlen); + client_id->len = msg->hlen + 2; + + return 0; +} + +static uint32_t dhcpv4_get_lease_time(uint8_t *options, uint8_t optlen) +{ + uint32_t lease_time; + + if (dhcpv4_find_ip_lease_time_option(options, optlen, + &lease_time) == 0) { + return lease_time; + } + + return CONFIG_NET_DHCPV4_SERVER_ADDR_LEASE_TIME; +} + +#if defined(DHCPV4_SERVER_ICMP_PROBE) +static int dhcpv4_probe_address(struct dhcpv4_server_ctx *ctx, + struct dhcpv4_addr_slot *slot) +{ + struct sockaddr_in dest_addr = { + .sin_family = AF_INET, + .sin_addr = slot->addr, + }; + int ret; + + ret = net_icmp_send_echo_request(&ctx->probe_ctx.icmp_ctx, ctx->iface, + (struct sockaddr *)&dest_addr, + NULL, ctx); + if (ret < 0) { + LOG_ERR("Failed to send ICMP probe"); + } + + return ret; +} + +static int echo_reply_handler(struct net_icmp_ctx *icmp_ctx, + struct net_pkt *pkt, + struct net_icmp_ip_hdr *ip_hdr, + struct net_icmp_hdr *icmp_hdr, + void *user_data) +{ + struct dhcpv4_server_ctx *ctx = user_data; + struct dhcpv4_server_probe_ctx *probe_ctx = &ctx->probe_ctx; + struct dhcpv4_addr_slot *new_slot = NULL; + struct in_addr peer_addr; + + ARG_UNUSED(icmp_ctx); + ARG_UNUSED(pkt); + ARG_UNUSED(ip_hdr); + ARG_UNUSED(icmp_hdr); + + k_mutex_lock(&server_lock, K_FOREVER); + + if (probe_ctx->slot == NULL) { + goto out; + } + + if (ip_hdr->family != AF_INET) { + goto out; + } + + net_ipv4_addr_copy_raw((uint8_t *)&peer_addr, ip_hdr->ipv4->src); + if (!net_ipv4_addr_cmp(&peer_addr, &probe_ctx->slot->addr)) { + goto out; + } + + LOG_DBG("Got ICMP probe response, blocking address %s", + net_sprint_ipv4_addr(&probe_ctx->slot->addr)); + + probe_ctx->slot->state = DHCPV4_SERVER_ADDR_DECLINED; + probe_ctx->slot->expiry = sys_timepoint_calc(ADDRESS_DECLINED_TIMEOUT); + + /* Try to find next free address */ + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_FREE) { + new_slot = slot; + break; + } + } + + if (new_slot == NULL) { + LOG_DBG("No more free addresses to assign, ICMP probing stopped"); + probe_ctx->slot = NULL; + dhcpv4_server_timeout_recalc(ctx); + goto out; + } + + if (dhcpv4_probe_address(ctx, new_slot) < 0) { + probe_ctx->slot = NULL; + dhcpv4_server_timeout_recalc(ctx); + goto out; + } + + new_slot->state = DHCPV4_SERVER_ADDR_RESERVED; + new_slot->expiry = sys_timepoint_calc(ADDRESS_PROBE_TIMEOUT); + new_slot->client_id.len = probe_ctx->slot->client_id.len; + memcpy(new_slot->client_id.buf, probe_ctx->slot->client_id.buf, + new_slot->client_id.len); + new_slot->lease_time = probe_ctx->slot->lease_time; + + probe_ctx->slot = new_slot; + + dhcpv4_server_timeout_recalc(ctx); + +out: + k_mutex_unlock(&server_lock); + + return 0; +} + +static int dhcpv4_server_probing_init(struct dhcpv4_server_ctx *ctx) +{ + return net_icmp_init_ctx(&ctx->probe_ctx.icmp_ctx, + NET_ICMPV4_ECHO_REPLY, 0, + echo_reply_handler); +} + +static void dhcpv4_server_probing_deinit(struct dhcpv4_server_ctx *ctx) +{ + (void)net_icmp_cleanup_ctx(&ctx->probe_ctx.icmp_ctx); +} + +static int dhcpv4_server_probe_setup(struct dhcpv4_server_ctx *ctx, + struct dhcpv4_addr_slot *slot, + struct dhcp_msg *msg, + struct dhcpv4_parameter_request_list *params) +{ + int ret; + + if (ctx->probe_ctx.slot != NULL) { + return -EBUSY; + } + + ret = dhcpv4_probe_address(ctx, slot); + if (ret < 0) { + return ret; + } + + ctx->probe_ctx.slot = slot; + ctx->probe_ctx.discovery = *msg; + ctx->probe_ctx.params = *params; + + return 0; +} + +static void dhcpv4_server_probe_timeout(struct dhcpv4_server_ctx *ctx, + struct dhcpv4_addr_slot *slot) +{ + /* Probe timer expired, send offer. */ + ctx->probe_ctx.slot = NULL; + + (void)net_arp_clear_pending(ctx->iface, &slot->addr); + + if (dhcpv4_send_offer(ctx, &ctx->probe_ctx.discovery, &slot->addr, + slot->lease_time, &ctx->probe_ctx.params) < 0) { + slot->state = DHCPV4_SERVER_ADDR_FREE; + return; + } + + slot->expiry = sys_timepoint_calc(ADDRESS_RESERVED_TIMEOUT); +} + +static bool dhcpv4_server_is_slot_probed(struct dhcpv4_server_ctx *ctx, + struct dhcpv4_addr_slot *slot) +{ + return (ctx->probe_ctx.slot == slot); +} +#else /* defined(DHCPV4_SERVER_ICMP_PROBE) */ +#define dhcpv4_server_probing_init(...) (0) +#define dhcpv4_server_probing_deinit(...) +#define dhcpv4_server_probe_setup(...) (-ENOTSUP) +#define dhcpv4_server_probe_timeout(...) +#define dhcpv4_server_is_slot_probed(...) (false) +#endif /* defined(DHCPV4_SERVER_ICMP_PROBE) */ + +static void dhcpv4_handle_discover(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + struct dhcpv4_addr_slot *selected = NULL; + struct dhcpv4_client_id client_id; + bool probe = false; + int ret; + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + return; + } + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + + /* Address pool and address selection algorithm as + * described in 4.3.1 + */ + + /* 1. Check for current bindings */ + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if ((slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0) { + if (slot->state == DHCPV4_SERVER_ADDR_RESERVED && + dhcpv4_server_is_slot_probed(ctx, slot)) { + LOG_DBG("ICMP probing in progress, ignore Discovery"); + return; + } + + /* Got match in current bindings. */ + selected = slot; + break; + } + } + + /* 2. Skipped, for now expired/released entries are forgotten. */ + + /* 3. Check Requested IP Address option. */ + if (selected == NULL) { + struct in_addr requested_ip; + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret == 0) { + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = + &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, + &requested_ip) && + slot->state == DHCPV4_SERVER_ADDR_FREE) { + /* Requested address is free. */ + selected = slot; + probe = true; + break; + } + } + } + } + + /* 4. Allocate new address from pool, if available. */ + if (selected == NULL) { + struct in_addr giaddr; + + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* Only addresses in local subnet supproted for now. */ + return; + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state == DHCPV4_SERVER_ADDR_FREE) { + /* Requested address is free. */ + selected = slot; + probe = true; + break; + } + } + } + + /* In case no free address slot was found, as a last resort, try to + * reuse the oldest declined entry, if present. + */ + if (selected == NULL) { + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->state != DHCPV4_SERVER_ADDR_DECLINED) { + continue; + } + + /* Find first to expire (oldest) entry. */ + if ((selected == NULL) || + (sys_timepoint_cmp(slot->expiry, + selected->expiry) < 0)) { + selected = slot; + probe = true; + } + } + } + + if (selected == NULL) { + LOG_ERR("No free address found in address pool"); + } else { + uint32_t lease_time = dhcpv4_get_lease_time(options, optlen); + + if (IS_ENABLED(DHCPV4_SERVER_ICMP_PROBE) && probe) { + if (dhcpv4_server_probe_setup(ctx, selected, + msg, ¶ms) < 0) { + /* Probing context already in use or failed to + * send probe, ignore Discovery for now and wait + * for retransmission. + */ + return; + } + + selected->expiry = + sys_timepoint_calc(ADDRESS_PROBE_TIMEOUT); + } else { + if (dhcpv4_send_offer(ctx, msg, &selected->addr, + lease_time, ¶ms) < 0) { + return; + } + + selected->expiry = + sys_timepoint_calc(ADDRESS_RESERVED_TIMEOUT); + } + + LOG_DBG("DHCPv4 processing Discover - reserved %s", + net_sprint_ipv4_addr(&selected->addr)); + + selected->state = DHCPV4_SERVER_ADDR_RESERVED; + selected->client_id.len = client_id.len; + memcpy(selected->client_id.buf, client_id.buf, client_id.len); + selected->lease_time = lease_time; + dhcpv4_server_timeout_recalc(ctx); + } +} + +static void dhcpv4_handle_request(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + struct dhcpv4_addr_slot *selected = NULL; + struct dhcpv4_client_id client_id; + struct in_addr requested_ip, server_id, ciaddr, giaddr; + int ret; + + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + memcpy(&giaddr, msg->giaddr, sizeof(giaddr)); + + if (!net_ipv4_is_addr_unspecified(&giaddr)) { + /* Only addresses in local subnet supported for now. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret == 0) { + /* Server ID present, Request generated during SELECTING. */ + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret < 0) { + /* Requested IP missing, ignore. */ + return; + } + + if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* ciaddr MUST be zero */ + return; + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &requested_ip) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + slot->state == DHCPV4_SERVER_ADDR_RESERVED) { + selected = slot; + break; + } + } + + if (selected == NULL) { + LOG_ERR("No valid slot found for DHCPv4 Request"); + } else { + uint32_t lease_time = dhcpv4_get_lease_time(options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &selected->addr, lease_time, + ¶ms, false) < 0) { + return; + } + + LOG_DBG("DHCPv4 processing Request - allocated %s", + net_sprint_ipv4_addr(&selected->addr)); + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + selected->state = DHCPV4_SERVER_ADDR_ALLOCATED; + dhcpv4_server_timeout_recalc(ctx); + } + + return; + } + + /* No server ID option - check requested address. */ + ret = dhcpv4_find_requested_ip_option(options, optlen, &requested_ip); + if (ret == 0) { + /* Requested IP present, Request generated during INIT-REBOOT. */ + if (!net_ipv4_is_addr_unspecified(&ciaddr)) { + /* ciaddr MUST be zero */ + return; + } + + if (!net_if_ipv4_addr_mask_cmp(ctx->iface, &requested_ip)) { + /* Wrong subnet. */ + dhcpv4_send_nak(ctx, msg); + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + selected = slot; + break; + } + } + + if (selected != NULL) { + if (net_ipv4_addr_cmp(&selected->addr, &requested_ip)) { + uint32_t lease_time = dhcpv4_get_lease_time( + options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &selected->addr, + lease_time, ¶ms, + false) < 0) { + return; + } + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + dhcpv4_server_timeout_recalc(ctx); + } else { + dhcpv4_send_nak(ctx, msg); + } + } + + /* No notion of the client, remain silent. */ + return; + } + + /* Neither server ID or requested IP set, Request generated during + * RENEWING or REBINDING. + */ + + if (!net_if_ipv4_addr_mask_cmp(ctx->iface, &ciaddr)) { + /* Wrong subnet. */ + dhcpv4_send_nak(ctx, msg); + } + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &ciaddr)) { + selected = slot; + break; + } + } + + if (selected != NULL) { + if (selected->state == DHCPV4_SERVER_ADDR_ALLOCATED && + selected->client_id.len == client_id.len && + memcmp(selected->client_id.buf, client_id.buf, + client_id.len) == 0) { + uint32_t lease_time = dhcpv4_get_lease_time( + options, optlen); + + if (dhcpv4_send_ack(ctx, msg, &ciaddr, lease_time, + ¶ms, false) < 0) { + return; + } + + selected->lease_time = lease_time; + selected->expiry = sys_timepoint_calc( + K_SECONDS(lease_time)); + dhcpv4_server_timeout_recalc(ctx); + } else { + dhcpv4_send_nak(ctx, msg); + } + } +} + +static void dhcpv4_handle_decline(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_client_id client_id; + struct in_addr requested_ip, server_id; + int ret; + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret < 0) { + /* No server ID, ignore. */ + return; + } + + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + ret = dhcpv4_find_requested_ip_option(options, optlen, + &requested_ip); + if (ret < 0) { + /* Requested IP missing, ignore. */ + return; + } + + LOG_ERR("Received DHCPv4 Decline for %s (address already in use)", + net_sprint_ipv4_addr(&requested_ip)); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &requested_ip) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + slot->state = DHCPV4_SERVER_ADDR_DECLINED; + slot->expiry = + sys_timepoint_calc(ADDRESS_DECLINED_TIMEOUT); + dhcpv4_server_timeout_recalc(ctx); + break; + } + } +} + +static void dhcpv4_handle_release(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_client_id client_id; + struct in_addr ciaddr, server_id; + int ret; + + ret = dhcpv4_find_server_id_option(options, optlen, &server_id); + if (ret < 0) { + /* No server ID, ignore. */ + return; + } + + if (!net_ipv4_addr_cmp(&ctx->server_addr, &server_id)) { + /* Not for us, ignore. */ + return; + } + + ret = dhcpv4_get_client_id(msg, options, optlen, &client_id); + if (ret < 0) { + /* Failed to obtain Client ID, ignore. */ + return; + } + + memcpy(&ciaddr, msg->ciaddr, sizeof(ciaddr)); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if (net_ipv4_addr_cmp(&slot->addr, &ciaddr) && + slot->client_id.len == client_id.len && + memcmp(slot->client_id.buf, client_id.buf, + client_id.len) == 0 && + (slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED)) { + LOG_DBG("DHCPv4 processing Release - %s", + net_sprint_ipv4_addr(&slot->addr)); + + slot->state = DHCPV4_SERVER_ADDR_FREE; + slot->expiry = sys_timepoint_calc(K_FOREVER); + dhcpv4_server_timeout_recalc(ctx); + break; + } + } +} + +static void dhcpv4_handle_inform(struct dhcpv4_server_ctx *ctx, + struct dhcp_msg *msg, uint8_t *options, + uint8_t optlen) +{ + struct dhcpv4_parameter_request_list params = { 0 }; + + (void)dhcpv4_find_parameter_request_list_option(options, optlen, ¶ms); + (void)dhcpv4_send_ack(ctx, msg, (struct in_addr *)msg->ciaddr, 0, + ¶ms, true); +} + +/* Server core. */ + +static void dhcpv4_server_timeout(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct dhcpv4_server_ctx *ctx = + CONTAINER_OF(dwork, struct dhcpv4_server_ctx, timeout_work); + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *slot = &ctx->addr_pool[i]; + + if ((slot->state == DHCPV4_SERVER_ADDR_RESERVED || + slot->state == DHCPV4_SERVER_ADDR_ALLOCATED) && + sys_timepoint_expired(slot->expiry)) { + if (slot->state == DHCPV4_SERVER_ADDR_RESERVED && + dhcpv4_server_is_slot_probed(ctx, slot)) { + dhcpv4_server_probe_timeout(ctx, slot); + } else { + LOG_DBG("Address %s expired", + net_sprint_ipv4_addr(&slot->addr)); + slot->state = DHCPV4_SERVER_ADDR_FREE; + } + } + + if (slot->state == DHCPV4_SERVER_ADDR_DECLINED && + sys_timepoint_expired(slot->expiry)) { + slot->state = DHCPV4_SERVER_ADDR_FREE; + } + } + + dhcpv4_server_timeout_recalc(ctx); + + k_mutex_unlock(&server_lock); +} + +static void dhcpv4_process_data(struct dhcpv4_server_ctx *ctx, uint8_t *data, + size_t datalen) +{ + struct dhcp_msg *msg; + uint8_t msgtype; + int ret; + + if (datalen < sizeof(struct dhcp_msg)) { + LOG_DBG("DHCPv4 server malformed message"); + return; + } + + msg = (struct dhcp_msg *)data; + + if (msg->op != DHCPV4_MSG_BOOT_REQUEST) { + /* Silently drop messages other than BOOTREQUEST */ + return; + } + + data += sizeof(struct dhcp_msg); + datalen -= sizeof(struct dhcp_msg); + + /* Skip server hostname/filename/option cookie */ + if (datalen < (SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE)) { + return; + } + + data += SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE; + datalen -= SIZE_OF_SNAME + SIZE_OF_FILE + SIZE_OF_MAGIC_COOKIE; + + /* Search options for DHCP message type. */ + ret = dhcpv4_find_message_type_option(data, datalen, &msgtype); + if (ret < 0) { + LOG_ERR("No message type option"); + return; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + switch (msgtype) { + case NET_DHCPV4_MSG_TYPE_DISCOVER: + dhcpv4_handle_discover(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_REQUEST: + dhcpv4_handle_request(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_DECLINE: + dhcpv4_handle_decline(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_RELEASE: + dhcpv4_handle_release(ctx, msg, data, datalen); + break; + case NET_DHCPV4_MSG_TYPE_INFORM: + dhcpv4_handle_inform(ctx, msg, data, datalen); + break; + + case NET_DHCPV4_MSG_TYPE_OFFER: + case NET_DHCPV4_MSG_TYPE_ACK: + case NET_DHCPV4_MSG_TYPE_NAK: + default: + /* Ignore server initiated and unknown message types. */ + break; + } + + k_mutex_unlock(&server_lock); +} + +static void dhcpv4_server_cb(struct k_work *work) +{ + struct net_socket_service_event *evt = + CONTAINER_OF(work, struct net_socket_service_event, work); + struct dhcpv4_server_ctx *ctx = NULL; + uint8_t recv_buf[NET_IPV4_MTU]; + int ret; + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].sock == evt->event.fd) { + ctx = &server_ctx[i]; + break; + } + } + + if (ctx == NULL) { + LOG_ERR("No DHCPv4 server context found for given FD."); + return; + } + + if (evt->event.revents & ZSOCK_POLLERR) { + LOG_ERR("DHCPv4 server poll revents error"); + net_dhcpv4_server_stop(ctx->iface); + return; + } + + if (!(evt->event.revents & ZSOCK_POLLIN)) { + return; + } + + ret = zsock_recvfrom(evt->event.fd, recv_buf, sizeof(recv_buf), + ZSOCK_MSG_DONTWAIT, NULL, 0); + if (ret < 0) { + if (errno == EAGAIN) { + return; + } + + LOG_ERR("DHCPv4 server recv error, %d", errno); + net_dhcpv4_server_stop(ctx->iface); + return; + } + + dhcpv4_process_data(ctx, recv_buf, ret); +} + +NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(dhcpv4_server, NULL, dhcpv4_server_cb, + CONFIG_NET_DHCPV4_SERVER_INSTANCES); + +int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr = INADDR_ANY_INIT, + .sin_port = htons(DHCPV4_SERVER_PORT), + }; + struct ifreq ifreq = { 0 }; + int ret, sock = -1, slot = -1; + const struct in_addr *server_addr; + struct in_addr netmask; + + if (iface == NULL || base_addr == NULL) { + return -EINVAL; + } + + if (!net_if_ipv4_addr_mask_cmp(iface, base_addr)) { + LOG_ERR("Address pool does not belong to the interface subnet."); + return -EINVAL; + } + + server_addr = net_if_ipv4_select_src_addr(iface, base_addr); + if (server_addr == NULL) { + LOG_ERR("Failed to obtain a valid server address."); + return -EINVAL; + } + + if ((htonl(server_addr->s_addr) >= htonl(base_addr->s_addr)) && + (htonl(server_addr->s_addr) < + htonl(base_addr->s_addr) + CONFIG_NET_DHCPV4_SERVER_ADDR_COUNT)) { + LOG_ERR("Address pool overlaps with server address."); + return -EINVAL; + } + + netmask = net_if_ipv4_get_netmask(iface); + if (net_ipv4_is_addr_unspecified(&netmask)) { + LOG_ERR("Failed to obtain subnet mask."); + return -EINVAL; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface != NULL) { + if (server_ctx[i].iface == iface) { + LOG_ERR("DHCPv4 server instance already running."); + ret = -EALREADY; + goto error; + } + } else { + if (slot < 0) { + slot = i; + } + } + } + + if (slot < 0) { + LOG_ERR("No free DHCPv4 server intance."); + ret = -ENOMEM; + goto error; + } + + ret = net_if_get_name(iface, ifreq.ifr_name, sizeof(ifreq.ifr_name)); + if (ret < 0) { + LOG_ERR("Failed to obtain interface name."); + goto error; + } + + sock = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + ret = errno; + LOG_ERR("Failed to create DHCPv4 server socket, %d", ret); + goto error; + } + + ret = zsock_setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, + sizeof(ifreq)); + if (ret < 0) { + ret = errno; + LOG_ERR("Failed to bind DHCPv4 server socket with interface, %d", + ret); + goto error; + } + + ret = zsock_bind(sock, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + ret = errno; + LOG_ERR("Failed to bind DHCPv4 server socket, %d", ret); + goto error; + } + + fds[slot].fd = sock; + fds[slot].events = ZSOCK_POLLIN; + + server_ctx[slot].iface = iface; + server_ctx[slot].sock = sock; + server_ctx[slot].server_addr = *server_addr; + server_ctx[slot].netmask = netmask; + + k_work_init_delayable(&server_ctx[slot].timeout_work, + dhcpv4_server_timeout); + + LOG_DBG("Started DHCPv4 server, address pool:"); + for (int i = 0; i < ARRAY_SIZE(server_ctx[slot].addr_pool); i++) { + server_ctx[slot].addr_pool[i].state = DHCPV4_SERVER_ADDR_FREE; + server_ctx[slot].addr_pool[i].addr.s_addr = + htonl(ntohl(base_addr->s_addr) + i); + + LOG_DBG("\t%2d: %s", i, + net_sprint_ipv4_addr( + &server_ctx[slot].addr_pool[i].addr)); + } + + ret = dhcpv4_server_probing_init(&server_ctx[slot]); + if (ret < 0) { + LOG_ERR("Failed to register probe handler, %d", ret); + goto cleanup; + } + + ret = net_socket_service_register(&dhcpv4_server, fds, ARRAY_SIZE(fds), + NULL); + if (ret < 0) { + LOG_ERR("Failed to register socket service, %d", ret); + dhcpv4_server_probing_deinit(&server_ctx[slot]); + goto cleanup; + } + + k_mutex_unlock(&server_lock); + + return 0; + +cleanup: + memset(&server_ctx[slot], 0, sizeof(server_ctx[slot])); + fds[slot].fd = -1; + +error: + if (sock >= 0) { + (void)zsock_close(sock); + } + + k_mutex_unlock(&server_lock); + + return ret; +} + +int net_dhcpv4_server_stop(struct net_if *iface) +{ + struct k_work_sync sync; + int slot = -1; + int ret = 0; + bool service_stop = true; + + if (iface == NULL) { + return -EINVAL; + } + + k_mutex_lock(&server_lock, K_FOREVER); + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface == iface) { + slot = i; + break; + } + } + + if (slot < 0) { + ret = -ENOENT; + goto out; + } + + fds[slot].fd = -1; + (void)zsock_close(server_ctx[slot].sock); + + dhcpv4_server_probing_deinit(&server_ctx[slot]); + k_work_cancel_delayable_sync(&server_ctx[slot].timeout_work, &sync); + + memset(&server_ctx[slot], 0, sizeof(server_ctx[slot])); + + for (int i = 0; i < ARRAY_SIZE(fds); i++) { + if (fds[i].fd >= 0) { + service_stop = false; + break; + } + } + + if (service_stop) { + ret = net_socket_service_unregister(&dhcpv4_server); + } else { + ret = net_socket_service_register(&dhcpv4_server, fds, + ARRAY_SIZE(fds), NULL); + } + +out: + k_mutex_unlock(&server_lock); + + return ret; +} + +static void dhcpv4_server_foreach_lease_on_ctx(struct dhcpv4_server_ctx *ctx, + net_dhcpv4_lease_cb_t cb, + void *user_data) +{ + for (int i = 0; i < ARRAY_SIZE(ctx->addr_pool); i++) { + struct dhcpv4_addr_slot *addr = &ctx->addr_pool[i]; + + if (addr->state != DHCPV4_SERVER_ADDR_FREE) { + cb(ctx->iface, addr, user_data); + } + } +} + +int net_dhcpv4_server_foreach_lease(struct net_if *iface, + net_dhcpv4_lease_cb_t cb, + void *user_data) +{ + int slot = -1; + int ret = 0; + + k_mutex_lock(&server_lock, K_FOREVER); + + if (iface == NULL) { + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface != NULL) { + dhcpv4_server_foreach_lease_on_ctx( + &server_ctx[i], cb, user_data); + } + } + + return 0; + } + + for (int i = 0; i < ARRAY_SIZE(server_ctx); i++) { + if (server_ctx[i].iface == iface) { + slot = i; + break; + } + } + + if (slot < 0) { + ret = -ENOENT; + goto out; + } + + dhcpv4_server_foreach_lease_on_ctx(&server_ctx[slot], cb, user_data); + +out: + k_mutex_unlock(&server_lock); + + return ret; +} + +void net_dhcpv4_server_init(void) +{ + for (int i = 0; i < ARRAY_SIZE(fds); i++) { + fds[i].fd = -1; + } +} diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index dd3c0c45618..33a093308df 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -110,6 +110,13 @@ config LWM2M_QUEUE_MODE_UPTIME defaults to 93 seconds, see RFC 7252), it does not forbid other values though. +config LWM2M_QUEUE_MODE_NO_MSG_BUFFERING + bool "Disable buffering notifications and messages on queue mode" + select EXPERIMENTAL + help + Messages are sent right away instead of waiting for next registration update. + This might not be supported on all servers. + config LWM2M_TLS_SESSION_CACHING bool "TLS session caching" help @@ -392,6 +399,13 @@ config LWM2M_COMPOSITE_PATH_LIST_SIZE help Define path list size for Composite Read and send operation. +config LWM2M_DEVICE_ERROR_CODE_SETTINGS + bool "Use settings to store error codes across device resets" + depends on SETTINGS + help + Store the device error code list in settings. Ensures error list can + be transferred to LwM2M server even if the device is reset. + config LWM2M_DEVICE_PWRSRC_MAX int "Maximum # of device power source records" default 5 diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 45d3822bdbb..55f23f77692 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -197,6 +197,11 @@ int lwm2m_socket_suspend(struct lwm2m_ctx *client_ctx) lwm2m_close_socket(client_ctx); /* store back the socket handle */ client_ctx->sock_fd = socket_temp_id; + + if (client_ctx->set_socket_state) { + client_ctx->set_socket_state(client_ctx->sock_fd, + LWM2M_SOCKET_STATE_NO_DATA); + } } return ret; @@ -239,6 +244,7 @@ int lwm2m_push_queued_buffers(struct lwm2m_ctx *client_ctx) break; } msg = SYS_SLIST_CONTAINER(msg_node, msg, node); + msg->pending->t0 = k_uptime_get(); sys_slist_append(&msg->ctx->pending_sends, &msg->node); } #endif @@ -581,14 +587,24 @@ void lwm2m_socket_del(struct lwm2m_ctx *ctx) lwm2m_engine_wake_up(); } -static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) +/* Generate notify messages. Return timestamp of next Notify event */ +static int64_t check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) { struct observe_node *obs; int rc; + int64_t next = INT64_MAX; lwm2m_registry_lock(); SYS_SLIST_FOR_EACH_CONTAINER(&ctx->observer, obs, node) { - if (!obs->event_timestamp || timestamp < obs->event_timestamp) { + if (!obs->event_timestamp) { + continue; + } + + if (obs->event_timestamp < next) { + next = obs->event_timestamp; + } + + if (timestamp < obs->event_timestamp) { continue; } /* Check That There is not pending process*/ @@ -604,6 +620,7 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) obs->event_timestamp = engine_observe_shedule_next_event(obs, ctx->srv_obj_inst, timestamp); obs->last_timestamp = timestamp; + if (!rc) { /* create at most one notification */ goto cleanup; @@ -611,6 +628,51 @@ static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) } cleanup: lwm2m_registry_unlock(); + return next; +} + +/** + * @brief Check TX queue states as well as number or pending CoAP transmissions. + * + * If all queues are empty and there is no packet we are currently transmitting and no + * CoAP responses (pendings) we are waiting, inform the application by a callback + * that socket is in state LWM2M_SOCKET_STATE_NO_DATA. + * Otherwise, before sending a packet, depending on the state of the queues, inform with + * one of the ONGOING, ONE_RESPONSE or LAST indicators. + * + * @param ctx Client context. + * @param ongoing_tx Current packet to be transmitted or NULL. + */ +static void hint_socket_state(struct lwm2m_ctx *ctx, struct lwm2m_message *ongoing_tx) +{ + if (!ctx || !ctx->set_socket_state) { + return; + } + +#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) + bool empty = sys_slist_is_empty(&ctx->pending_sends) && + sys_slist_is_empty(&ctx->queued_messages); +#else + bool empty = sys_slist_is_empty(&ctx->pending_sends); +#endif + size_t pendings = coap_pendings_count(ctx->pendings, ARRAY_SIZE(ctx->pendings)); + + if (ongoing_tx) { + /* Check if more than current TX is in pendings list*/ + if (pendings > 1) { + empty = false; + } + + if (!empty) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONGOING); + } else if (ongoing_tx->type == COAP_TYPE_CON) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_ONE_RESPONSE); + } else { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_LAST); + } + } else if (empty && pendings == 0) { + ctx->set_socket_state(ctx->sock_fd, LWM2M_SOCKET_STATE_NO_DATA); + } } static int socket_recv_message(struct lwm2m_ctx *client_ctx) @@ -647,10 +709,10 @@ static int socket_recv_message(struct lwm2m_ctx *client_ctx) return 0; } -static int socket_send_message(struct lwm2m_ctx *client_ctx) +static int socket_send_message(struct lwm2m_ctx *ctx) { int rc; - sys_snode_t *msg_node = sys_slist_get(&client_ctx->pending_sends); + sys_snode_t *msg_node = sys_slist_get(&ctx->pending_sends); struct lwm2m_message *msg; if (!msg_node) { @@ -667,11 +729,15 @@ static int socket_send_message(struct lwm2m_ctx *client_ctx) coap_pending_cycle(msg->pending); } + hint_socket_state(ctx, msg); + rc = zsock_send(msg->ctx->sock_fd, msg->cpkt.data, msg->cpkt.offset, 0); if (rc < 0) { LOG_ERR("Failed to send packet, err %d", errno); rc = -errno; + } else { + engine_update_tx_time(); } if (msg->type != COAP_TYPE_CON) { @@ -704,7 +770,7 @@ static void socket_loop(void *p1, void *p2, void *p3) int i, rc; int64_t now, next; - int64_t timeout, next_retransmit; + int64_t timeout, next_tx; bool rd_client_paused; while (1) { @@ -741,12 +807,15 @@ static void socket_loop(void *p1, void *p2, void *p3) if (!sys_slist_is_empty(&sock_ctx[i]->pending_sends)) { continue; } - next_retransmit = retransmit_request(sock_ctx[i], now); - if (next_retransmit < next) { - next = next_retransmit; + next_tx = retransmit_request(sock_ctx[i], now); + if (next_tx < next) { + next = next_tx; } if (lwm2m_rd_client_is_registred(sock_ctx[i])) { - check_notifications(sock_ctx[i], now); + next_tx = check_notifications(sock_ctx[i], now); + if (next_tx < next) { + next = next_tx; + } } } @@ -799,6 +868,8 @@ static void socket_loop(void *p1, void *p2, void *p3) break; } } + + hint_socket_state(sock_ctx[i], NULL); } if (sock_fds[i].revents & ZSOCK_POLLOUT) { @@ -989,7 +1060,7 @@ int lwm2m_set_default_sockopt(struct lwm2m_ctx *ctx) } if (IS_ENABLED(CONFIG_LWM2M_DTLS_CID)) { /* Enable CID */ - int cid = TLS_DTLS_CID_ENABLED; + int cid = TLS_DTLS_CID_SUPPORTED; ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_CID, &cid, sizeof(cid)); @@ -1189,6 +1260,12 @@ int lwm2m_engine_pause(void) suspend_engine_thread = true; lwm2m_engine_wake_up(); + /* Check if pause requested within a engine thread, a callback for example. */ + if (engine_thread_id == k_current_get()) { + LOG_DBG("Pause requested"); + return 0; + } + while (active_engine_thread) { k_msleep(10); } @@ -1205,10 +1282,7 @@ int lwm2m_engine_resume(void) k_thread_resume(engine_thread_id); lwm2m_engine_wake_up(); - while (!active_engine_thread) { - k_msleep(10); - } - LOG_INF("LWM2M engine thread resume"); + return 0; } diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index 2306fced197..81b28395662 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -30,6 +30,7 @@ /* length of time in milliseconds to wait for buffer allocations */ #define BUF_ALLOC_TIMEOUT K_SECONDS(1) + /** * @brief Validates that writing is a legal operation on the field given by the object in * @p obj_inst and the resource id in @p msg. Returns the field to obj_field (if it exists). @@ -133,6 +134,14 @@ int lwm2m_engine_call_now(k_work_handler_t service); */ int lwm2m_security_inst_id_to_index(uint16_t obj_inst_id); +/** + * @brief Returns the object instance id of the security having ssid given by @p short_id. + * + * @param[in] short_id ssid of the security object + * @return Object instance id or negative in case not found + */ +int lwm2m_security_short_id_to_inst(uint16_t short_id); + /** * @brief Returns the object instance id of the security object instance at @p index * in the security object list. @@ -142,45 +151,6 @@ int lwm2m_security_inst_id_to_index(uint16_t obj_inst_id); */ int lwm2m_security_index_to_inst_id(int index); -/** - * @brief Returns the default minimum period for an observation set for the server - * with object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object instance - * @return int32_t pmin value - */ -int32_t lwm2m_server_get_pmin(uint16_t obj_inst_id); - -/** - * @brief Returns the default maximum period for an observation set for the server - * with object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object instance - * @return int32_t pmax value - */ -int32_t lwm2m_server_get_pmax(uint16_t obj_inst_id); - -/** - * @brief Returns the Short Server ID of the server object instance with - * object instance id given by @p obj_inst_id. - * - * @param[in] obj_inst_id Object instance id of the server object - * @return SSID or negative in case not found - */ -int lwm2m_server_get_ssid(uint16_t obj_inst_id); - -/** - * @brief Returns the object instance id of the server having ssid given by @p short_id. - * - * @param[in] short_id ssid of the server object - * @return Object instance id or negative in case not found - */ -int lwm2m_server_short_id_to_inst(uint16_t short_id); - -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) -bool lwm2m_server_get_mute_send(uint16_t obj_inst_id); -#endif - #if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT) /** * @brief Sets the update state (as specified in LWM2M SPEC E.6 regarding the firmware update) diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 6d006b4603e..19a2e1ccdd0 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -45,6 +45,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_engine.h" #include "lwm2m_object.h" #include "lwm2m_obj_access_control.h" +#include "lwm2m_obj_server.h" +#include "lwm2m_obj_gateway.h" #include "lwm2m_rw_link_format.h" #include "lwm2m_rw_oma_tlv.h" #include "lwm2m_rw_plain_text.h" @@ -478,7 +480,7 @@ void lwm2m_engine_context_init(struct lwm2m_ctx *client_ctx) } /* utility functions */ -static int coap_options_to_path(struct coap_option *opt, int options_count, +int coap_options_to_path(struct coap_option *opt, int options_count, struct lwm2m_obj_path *path) { uint16_t len, @@ -653,8 +655,7 @@ int lwm2m_init_message(struct lwm2m_message *msg) goto cleanup; } - r = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, - CONFIG_COAP_MAX_RETRANSMIT); + r = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, NULL); if (r < 0) { LOG_ERR("Unable to initialize a pending " "retransmission (err:%d).", @@ -725,6 +726,13 @@ int lwm2m_information_interface_send(struct lwm2m_message *msg) return ret; } + if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_NO_MSG_BUFFERING)) { + sys_slist_append(&msg->ctx->pending_sends, &msg->node); + lwm2m_engine_wake_up(); + lwm2m_engine_connection_resume(msg->ctx); + return 0; + } + if (msg->ctx->buffer_client_messages) { sys_slist_append(&msg->ctx->queued_messages, &msg->node); lwm2m_engine_wake_up(); @@ -2268,6 +2276,15 @@ static int handle_request(struct coap_packet *request, struct lwm2m_message *msg msg->token = token; } + if (IS_ENABLED(CONFIG_LWM2M_GATEWAY_OBJ_SUPPORT)) { + r = lwm2m_gw_handle_req(msg); + if (r == 0) { + return 0; + } else if (r != -ENOENT) { + goto error; + } + } + /* parse the URL path into components */ r = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options, ARRAY_SIZE(options)); if (r < 0) { @@ -2593,8 +2610,7 @@ static int lwm2m_response_promote_to_con(struct lwm2m_message *msg) return -ENOMEM; } - ret = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, - CONFIG_COAP_MAX_RETRANSMIT); + ret = coap_pending_init(msg->pending, &msg->cpkt, &msg->ctx->remote_addr, NULL); if (ret < 0) { LOG_ERR("Unable to initialize a pending " "retransmission (err:%d).", diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.h b/subsys/net/lib/lwm2m/lwm2m_message_handling.h index c41fbbac0ee..3ac014b5db8 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 +int coap_options_to_path(struct coap_option *opt, int options_count, + struct lwm2m_obj_path *path); /* 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); diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_device.c b/subsys/net/lib/lwm2m/lwm2m_obj_device.c index c17815795c2..f5399fefc1e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_device.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_device.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017 Linaro Limited * Copyright (c) 2018-2019 Foundries.io + * Copyright (c) 2023 FTP Technologies * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,6 +20,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include #include "lwm2m_object.h" #include "lwm2m_engine.h" @@ -89,7 +91,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); DEVICE_EXT_DEV_INFO_MAX) /* resource state variables */ -static uint8_t error_code_list[DEVICE_ERROR_CODE_MAX]; +static uint8_t error_code_list[DEVICE_ERROR_CODE_MAX] = { LWM2M_DEVICE_ERROR_NONE }; static time_t time_temp; static time_t time_offset; static uint8_t binding_mode[DEVICE_STRING_SHORT]; @@ -129,23 +131,46 @@ static struct lwm2m_engine_res_inst res_inst[RESOURCE_INSTANCE_COUNT]; /* save error code resource instance point so we can easily clear later */ static struct lwm2m_engine_res_inst *error_code_ri; +#define SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "lwm2m_obj_dev" +#define ERROR_LIST_KEY "err" + /* callbacks */ -static int reset_error_list_cb(uint16_t obj_inst_id, - uint8_t *args, uint16_t args_len) +static void reset_error_list(void) { int i; /* "delete" error codes */ for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) { - error_code_list[i] = 0; + error_code_list[i] = LWM2M_DEVICE_ERROR_NONE; error_code_ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED; } /* Default error code indicating no error */ error_code_ri[0].res_inst_id = 0; +} + +static int reset_error_list_cb(uint16_t obj_inst_id, + uint8_t *args, uint16_t args_len) +{ + int ret = 0; + + ARG_UNUSED(obj_inst_id); + ARG_UNUSED(args); + ARG_UNUSED(args_len); + + reset_error_list(); - return 0; + lwm2m_notify_observer(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_ERROR_CODE_ID); + + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_delete(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "/" ERROR_LIST_KEY); + if (ret != 0) { + LOG_ERR("Couldn't save error list: %d", ret); + } + } + + return ret; } static void *current_time_read_cb(uint16_t obj_inst_id, uint16_t res_id, @@ -182,13 +207,13 @@ static int current_time_post_write_cb(uint16_t obj_inst_id, uint16_t res_id, } /* error code function */ - int lwm2m_device_add_err(uint8_t error_code) { + int ret = 0; int i; for (i = 0; i < DEVICE_ERROR_CODE_MAX; i++) { - if (error_code_list[i] == 0) { + if (error_code_list[i] == LWM2M_DEVICE_ERROR_NONE) { break; } @@ -206,7 +231,15 @@ int lwm2m_device_add_err(uint8_t error_code) error_code_ri[i].res_inst_id = i; lwm2m_notify_observer(LWM2M_OBJECT_DEVICE_ID, 0, DEVICE_ERROR_CODE_ID); - return 0; + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_save_one(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE "/" ERROR_LIST_KEY, + error_code_list, i + 1); + if (ret != 0) { + LOG_ERR("Couldn't save error list: %d", ret); + } + } + + return ret; } static void device_periodic_service(struct k_work *work) @@ -219,6 +252,49 @@ int lwm2m_update_device_service_period(uint32_t period_ms) return lwm2m_engine_update_service_period(device_periodic_service, period_ms); } +static int lwm2m_obj_device_settings_set(const char *name, size_t len, + settings_read_cb read_cb, void *cb_arg) +{ + const char *next; + int rc; + int i; + + if (settings_name_steq(name, ERROR_LIST_KEY, &next) && !next) { + if (len > sizeof(error_code_list)) { + LOG_ERR("Error code list too large: %zu", len); + return -EINVAL; + } + + rc = read_cb(cb_arg, error_code_list, sizeof(error_code_list)); + if (rc == 0) { + reset_error_list(); + return 0; + } else if (rc > 0) { + for (i = 0; i < ARRAY_SIZE(error_code_list); i++) { + if (i < rc) { + error_code_ri[i].res_inst_id = i; + } else { + /* Reset remaining error code instances */ + error_code_list[i] = LWM2M_DEVICE_ERROR_NONE; + error_code_ri[i].res_inst_id = RES_INSTANCE_NOT_CREATED; + } + } + return 0; + } + + LOG_ERR("Error code list read failure: %d", rc); + + return rc; + } + + return -ENOENT; +} + +static struct settings_handler lwm2m_obj_device_settings_handler = { + .name = SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE, + .h_set = lwm2m_obj_device_settings_set, +}; + static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id) { int i = 0, j = 0; @@ -271,7 +347,7 @@ static struct lwm2m_engine_obj_inst *device_create(uint16_t obj_inst_id) static int lwm2m_device_init(void) { struct lwm2m_engine_obj_inst *obj_inst = NULL; - int ret = 0; + int ret; /* Set default values */ time_offset = 0U; @@ -294,12 +370,26 @@ static int lwm2m_device_init(void) LOG_DBG("Create LWM2M instance 0 error: %d", ret); } - /* Create the default error code resource instance */ - lwm2m_device_add_err(0); + /* Ensure error list is reset if not loaded from settings */ + reset_error_list(); + + /* Load error code resource instances */ + if (IS_ENABLED(CONFIG_LWM2M_DEVICE_ERROR_CODE_SETTINGS)) { + ret = settings_register(&lwm2m_obj_device_settings_handler); + if (ret == 0) { + ret = settings_load_subtree(SETTINGS_SUBTREE_LWM2M_OBJ_DEVICE); + if (ret != 0) { + LOG_ERR("Settings load failed: %d", ret); + } + } else { + LOG_ERR("Settings register failed: %d", ret); + } + } /* call device_periodic_service() every 10 seconds */ ret = lwm2m_engine_add_service(device_periodic_service, DEVICE_SERVICE_INTERVAL_MS); + return ret; } diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c index 711fd5fe127..5bb12f80f47 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.c @@ -59,6 +59,7 @@ 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][GATEWAY_MAX_ID]; static struct lwm2m_engine_res_inst res_inst[MAX_INSTANCE_COUNT][RESOURCE_INSTANCE_COUNT]; +lwm2m_engine_gateway_msg_cb gateway_msg_cb[MAX_INSTANCE_COUNT]; static int prefix_validation_cb(uint16_t obj_inst_id, uint16_t res_id, uint16_t res_inst_id, uint8_t *data, uint16_t data_len, bool last_block, @@ -146,6 +147,57 @@ static struct lwm2m_engine_obj_inst *lwm2m_gw_create(uint16_t obj_inst_id) return &inst[index]; } +int lwm2m_gw_handle_req(struct lwm2m_message *msg) +{ + struct coap_option options[4]; + int ret; + + ret = coap_find_options(msg->in.in_cpkt, COAP_OPTION_URI_PATH, options, + ARRAY_SIZE(options)); + if (ret < 0) { + return ret; + } + + for (int index = 0; index < MAX_INSTANCE_COUNT; index++) { + /* Skip uninitialized objects */ + if (!inst[index].obj) { + continue; + } + + char *prefix = device_table[index].prefix; + size_t prefix_len = strlen(prefix); + + if (prefix_len != options[0].len) { + continue; + } + if (strncmp(options[0].value, prefix, prefix_len) != 0) { + continue; + } + + if (gateway_msg_cb[index] == NULL) { + return -ENOENT; + } + /* Delete prefix from path*/ + ret = coap_options_to_path(&options[1], ret - 1, &msg->path); + if (ret < 0) { + return ret; + } + return gateway_msg_cb[index](msg); + } + return -ENOENT; +} + +int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb) +{ + for (int index = 0; index < MAX_INSTANCE_COUNT; index++) { + if (inst[index].obj_inst_id == obj_inst_id) { + gateway_msg_cb[index] = cb; + return 0; + } + } + return -ENOENT; +} + static int lwm2m_gw_init(void) { int ret = 0; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h index 597e3de19bc..0f7a82af249 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h +++ b/subsys/net/lib/lwm2m/lwm2m_obj_gateway.h @@ -9,6 +9,8 @@ #ifndef __LWM2M_OBJ_GATEWAY__ #define __LWM2M_OBJ_GATEWAY__ +#include + /* LwM2M Gateway resource IDs */ /* clang-format off */ #define LWM2M_GATEWAY_DEVICE_RID 0 @@ -17,4 +19,42 @@ #define LWM2M_GATEWAY_IOT_DEVICE_OBJECTS_RID 3 /* clang-format on */ +/** + * @brief A callback which handles the prefixed messages from the server. + * + * The callback gets triggered each time the prefix in front of a received lwm2m + * msg path matches the prefix set in the LWM2M_GATEWAY_PREFIX_RID buffer. + * + * It must handle the content of the coap message completely. + * In case of success the LwM2M engine will then send the formatted coap message, + * otherwise a coap response code is sent. + * + * Example of returning CoAP response: + * @code{.c} + * lwm2m_init_message(msg); + * // Write CoAP packet to msg->out.out_cpkt + * return 0; + * @endcode + * + * + * @return 0 if msg contains a valid CoAP response. + * @return negative error code otherwise. + */ +typedef int (*lwm2m_engine_gateway_msg_cb)(struct lwm2m_message *msg); +/** + * @brief Register a callback which handles the prefixed messages from the server. + * + * @return 0 on success + * @return -ENOENT if no object instance with obj_inst_id was found + */ +int lwm2m_register_gw_callback(uint16_t obj_inst_id, lwm2m_engine_gateway_msg_cb cb); +/** + * @brief Check if given message is handled by Gateway callback. + * + * @return 0 if msg was handled by Gateawy and contains a valid response. Negative error code + * otherwise. + * @return -ENOENT if this msg was not handled by Gateway object. + */ +int lwm2m_gw_handle_req(struct lwm2m_message *msg); + #endif /* __LWM2M_OBJ_GATEWAY__ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_security.c b/subsys/net/lib/lwm2m/lwm2m_obj_security.c index 874925c39d8..00796648634 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_security.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_security.c @@ -212,6 +212,16 @@ int lwm2m_security_index_to_inst_id(int index) return inst[index].obj_inst_id; } +int lwm2m_security_short_id_to_inst(uint16_t short_id) +{ + for (int i = 0; i < MAX_INSTANCE_COUNT; i++) { + if (short_server_id[i] == short_id) { + return inst[i].obj_inst_id; + } + } + return -ENOENT; +} + int lwm2m_security_mode(struct lwm2m_ctx *ctx) { int ret; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.c b/subsys/net/lib/lwm2m/lwm2m_obj_server.c index a1b2185ef1d..a9432340038 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_server.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.c @@ -15,8 +15,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include "lwm2m_object.h" -#include "lwm2m_engine.h" +#include "lwm2m_obj_server.h" #include "lwm2m_rd_client.h" +#include "lwm2m_registry.h" #define SERVER_VERSION_MAJOR 1 #if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) @@ -27,37 +28,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define SERVER_MAX_ID 9 #endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ -/* Server resource IDs */ -#define SERVER_SHORT_SERVER_ID 0 -#define SERVER_LIFETIME_ID 1 -#define SERVER_DEFAULT_MIN_PERIOD_ID 2 -#define SERVER_DEFAULT_MAX_PERIOD_ID 3 -#define SERVER_DISABLE_ID 4 -#define SERVER_DISABLE_TIMEOUT_ID 5 -#define SERVER_STORE_NOTIFY_ID 6 -#define SERVER_TRANSPORT_BINDING_ID 7 -#define SERVER_REG_UPDATE_TRIGGER_ID 8 -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) -#define SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID 9 -#define SERVER_APN_LINK_ID 10 -#define SERVER_TLS_DTLS_ALERT_CODE_ID 11 -#define SERVER_LAST_BOOTSTRAPPED_ID 12 -#define SERVER_REGISTRATION_PRIORITY_ORDER_ID 13 -#define SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID 14 -#define SERVER_REGISTRATION_FAILURE_BLOCK_ID 15 -#define SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID 16 -#define SERVER_COMMUNICATION_RETRY_COUNT_ID 17 -#define SERVER_COMMUNICATION_RETRY_TIMER_ID 18 -#define SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID 19 -#define SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID 20 -#define SERVER_SMS_TRIGGER_ID 21 -#define SERVER_PREFERRED_TRANSPORT_ID 22 -#define SERVER_MUTE_SEND_ID 23 -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ - - /* Server flags */ -#define SERVER_FLAG_DISABLED 1 #define SERVER_FLAG_STORE_NOTIFY 2 #define MAX_INSTANCE_COUNT CONFIG_LWM2M_SERVER_INSTANCE_COUNT @@ -76,13 +47,14 @@ static uint16_t server_id[MAX_INSTANCE_COUNT]; static uint32_t lifetime[MAX_INSTANCE_COUNT]; static uint32_t default_min_period[MAX_INSTANCE_COUNT]; static uint32_t default_max_period[MAX_INSTANCE_COUNT]; -static uint8_t server_flag_disabled[MAX_INSTANCE_COUNT]; +static k_timepoint_t disabled_until[MAX_INSTANCE_COUNT]; static uint32_t disabled_timeout[MAX_INSTANCE_COUNT]; static uint8_t server_flag_store_notify[MAX_INSTANCE_COUNT]; static char transport_binding[MAX_INSTANCE_COUNT][TRANSPORT_BINDING_LEN]; -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) +/* Server object version 1.1 */ +static uint8_t priority[MAX_INSTANCE_COUNT]; static bool mute_send[MAX_INSTANCE_COUNT]; -#endif +static bool boostrap_on_fail[MAX_INSTANCE_COUNT]; static struct lwm2m_engine_obj server; static struct lwm2m_engine_obj_field fields[] = { @@ -101,10 +73,10 @@ static struct lwm2m_engine_obj_field fields[] = { OBJ_FIELD_DATA(SERVER_APN_LINK_ID, RW_OPT, OBJLNK), OBJ_FIELD_DATA(SERVER_TLS_DTLS_ALERT_CODE_ID, R_OPT, U8), OBJ_FIELD_DATA(SERVER_LAST_BOOTSTRAPPED_ID, R_OPT, TIME), - OBJ_FIELD_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, W_OPT, U16), + OBJ_FIELD_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, RW_OPT, U8), OBJ_FIELD_DATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, W_OPT, BOOL), - OBJ_FIELD_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, W_OPT, BOOL), + OBJ_FIELD_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, RW_OPT, BOOL), OBJ_FIELD_DATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, W_OPT, U16), OBJ_FIELD_DATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, W_OPT, U16), @@ -123,13 +95,21 @@ static struct lwm2m_engine_res_inst static int disable_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { - int i; + ARG_UNUSED(args); + ARG_UNUSED(args_len); - LOG_DBG("DISABLE %d", obj_inst_id); - for (i = 0; i < MAX_INSTANCE_COUNT; i++) { + int ret; + + for (int i = 0; i < MAX_INSTANCE_COUNT; i++) { if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { - server_flag_disabled[i] = 1U; - return 0; + LOG_DBG("DISABLE %d", obj_inst_id); + ret = lwm2m_rd_client_server_disabled(obj_inst_id); + if (ret == 0) { + disabled_until[i] = + sys_timepoint_calc(K_SECONDS(disabled_timeout[i])); + return 0; + } + return ret; } } @@ -143,7 +123,6 @@ static int update_trigger_cb(uint16_t obj_inst_id, return 0; } -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) static int bootstrap_trigger_cb(uint16_t obj_inst_id, uint8_t *args, uint16_t args_len) { @@ -161,7 +140,6 @@ bool lwm2m_server_get_mute_send(uint16_t obj_inst_id) } return false; } -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ static int lifetime_write_cb(uint16_t obj_inst_id, uint16_t res_id, @@ -233,6 +211,116 @@ int lwm2m_server_short_id_to_inst(uint16_t short_id) return -ENOENT; } +static int lwm2m_server_inst_id_to_index(uint16_t obj_inst_id) +{ + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + if (inst[i].obj && inst[i].obj_inst_id == obj_inst_id) { + return i; + } + } + return -1; +} + +bool lwm2m_server_is_enabled(uint16_t obj_inst_id) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return false; + } + return sys_timepoint_expired(disabled_until[idx]); +} + +int lwm2m_server_disable(uint16_t obj_inst_id, k_timeout_t timeout) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return -ENOENT; + } + disabled_until[idx] = sys_timepoint_calc(timeout); + return 0; +} + +k_timepoint_t lwm2m_server_get_disabled_time(uint16_t obj_inst_id) +{ + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return sys_timepoint_calc(K_FOREVER); + } + return disabled_until[idx]; +} + +void lwm2m_server_reset_timestamps(void) +{ + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + disabled_until[i] = sys_timepoint_calc(K_NO_WAIT); + } +} + +bool lwm2m_server_select(uint16_t *obj_inst_id) +{ + uint8_t min = UINT8_MAX; + uint8_t max = 0; + + /* Find priority boundaries */ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + if (min > priority[i]) { + min = priority[i]; + } + if (max < priority[i]) { + max = priority[i]; + } + } + } else { + min = max = 0; + } + + for (uint8_t prio = min; prio <= max; prio++) { + for (int i = 0; i < ARRAY_SIZE(inst); i++) { + /* Disabled for a period */ + if (!lwm2m_server_is_enabled(inst[i].obj_inst_id)) { + continue; + } + + /* Invalid short IDs */ + if (server_id[i] == 0 || server_id[i] == UINT16_MAX) { + continue; + } + + /* Check priority */ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + if (priority[i] > prio) { + continue; + } + } + if (obj_inst_id) { + *obj_inst_id = inst[i].obj_inst_id; + } + return true; + } + } + + LOG_ERR("No server candidate found"); + return false; +} + +uint8_t lwm2m_server_get_prio(uint16_t obj_inst_id) +{ + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + int idx = lwm2m_server_inst_id_to_index(obj_inst_id); + + if (idx < 0) { + return UINT8_MAX; + } + return priority[idx]; + } + + return (uint8_t)obj_inst_id % UINT8_MAX; +} + static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) { int index, i = 0, j = 0; @@ -259,16 +347,14 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) } /* Set default values */ - server_flag_disabled[index] = 0U; + disabled_until[i] = sys_timepoint_calc(K_NO_WAIT); server_flag_store_notify[index] = 0U; server_id[index] = index + 1; lifetime[index] = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME; default_min_period[index] = CONFIG_LWM2M_SERVER_DEFAULT_PMIN; default_max_period[index] = CONFIG_LWM2M_SERVER_DEFAULT_PMAX; disabled_timeout[index] = 86400U; -#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) - mute_send[index] = false; -#endif + boostrap_on_fail[index] = true; lwm2m_engine_get_binding(transport_binding[index]); @@ -305,33 +391,39 @@ static struct lwm2m_engine_obj_inst *server_create(uint16_t obj_inst_id) 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); - INIT_OBJ_RES_OPTDATA(SERVER_APN_LINK_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_TLS_DTLS_ALERT_CODE_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_LAST_BOOTSTRAPPED_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, res[index], i, res_inst[index], - j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID, res[index], i, - res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_SMS_TRIGGER_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_OPTDATA(SERVER_PREFERRED_TRANSPORT_ID, res[index], i, res_inst[index], j); - INIT_OBJ_RES_DATA(SERVER_MUTE_SEND_ID, res[index], i, res_inst[index], j, &mute_send[index], - sizeof(bool)); -#endif /* defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) */ + + if (IS_ENABLED(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)) { + mute_send[index] = false; + priority[index] = 0; + INIT_OBJ_RES_EXECUTE(SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID, res[index], i, + bootstrap_trigger_cb); + INIT_OBJ_RES_OPTDATA(SERVER_APN_LINK_ID, res[index], i, res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_TLS_DTLS_ALERT_CODE_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_OPTDATA(SERVER_LAST_BOOTSTRAPPED_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_DATA(SERVER_REGISTRATION_PRIORITY_ORDER_ID, res[index], i, + res_inst[index], j, &priority[index], sizeof(uint8_t)); + INIT_OBJ_RES_OPTDATA(SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_REGISTRATION_FAILURE_BLOCK_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_DATA(SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID, res[index], i, + res_inst[index], j, &boostrap_on_fail[index], sizeof(bool)); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_COUNT_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_RETRY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID, res[index], i, + res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_SMS_TRIGGER_ID, res[index], i, res_inst[index], j); + INIT_OBJ_RES_OPTDATA(SERVER_PREFERRED_TRANSPORT_ID, res[index], i, res_inst[index], + j); + INIT_OBJ_RES_DATA(SERVER_MUTE_SEND_ID, res[index], i, res_inst[index], j, + &mute_send[index], sizeof(bool)); + } inst[index].resources = res[index]; inst[index].resource_count = i; diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_server.h b/subsys/net/lib/lwm2m/lwm2m_obj_server.h new file mode 100644 index 00000000000..56d7a674071 --- /dev/null +++ b/subsys/net/lib/lwm2m/lwm2m_obj_server.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef LWM2M_OBJ_SERVER_H_ +#define LWM2M_OBJ_SERVER_H_ + +#include +#include +#include + +/* Server resource IDs */ +#define SERVER_SHORT_SERVER_ID 0 +#define SERVER_LIFETIME_ID 1 +#define SERVER_DEFAULT_MIN_PERIOD_ID 2 +#define SERVER_DEFAULT_MAX_PERIOD_ID 3 +#define SERVER_DISABLE_ID 4 +#define SERVER_DISABLE_TIMEOUT_ID 5 +#define SERVER_STORE_NOTIFY_ID 6 +#define SERVER_TRANSPORT_BINDING_ID 7 +#define SERVER_REG_UPDATE_TRIGGER_ID 8 +/* Server object version 1.1 resource IDs */ +#define SERVER_BOOTSTRAP_UPDATE_TRIGGER_ID 9 +#define SERVER_APN_LINK_ID 10 +#define SERVER_TLS_DTLS_ALERT_CODE_ID 11 +#define SERVER_LAST_BOOTSTRAPPED_ID 12 +#define SERVER_REGISTRATION_PRIORITY_ORDER_ID 13 +#define SERVER_INITIAL_REGISTRATION_DELAY_TIMER_ID 14 +#define SERVER_REGISTRATION_FAILURE_BLOCK_ID 15 +#define SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID 16 +#define SERVER_COMMUNICATION_RETRY_COUNT_ID 17 +#define SERVER_COMMUNICATION_RETRY_TIMER_ID 18 +#define SERVER_COMMUNICATION_SEQUENCE_DELAY_TIMER_ID 19 +#define SERVER_COMMUNICATION_SEQUENCE_RETRY_TIMER_ID 20 +#define SERVER_SMS_TRIGGER_ID 21 +#define SERVER_PREFERRED_TRANSPORT_ID 22 +#define SERVER_MUTE_SEND_ID 23 + +/** + * @brief Returns the default minimum period for an observation set for the server + * with object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object instance + * @return int32_t pmin value + */ +int32_t lwm2m_server_get_pmin(uint16_t obj_inst_id); + +/** + * @brief Returns the default maximum period for an observation set for the server + * with object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object instance + * @return int32_t pmax value + */ +int32_t lwm2m_server_get_pmax(uint16_t obj_inst_id); + +/** + * @brief Returns the Short Server ID of the server object instance with + * object instance id given by @p obj_inst_id. + * + * @param[in] obj_inst_id Object instance id of the server object + * @return SSID or negative in case not found + */ +int lwm2m_server_get_ssid(uint16_t obj_inst_id); + +/** + * @brief Returns the object instance id of the server having ssid given by @p short_id. + * + * @param[in] short_id ssid of the server object + * @return Object instance id or negative in case not found + */ +int lwm2m_server_short_id_to_inst(uint16_t short_id); + +/** + * @brief Check if given server instance is not disabled + * + * @param[in] obj_inst_id server instance + * @return true if not disabled, false otherwise. + */ +bool lwm2m_server_is_enabled(uint16_t obj_inst_id); + +/** + * @brief Select server instance. + * + * Find possible server instance considering values on server data. + * Server candidates cannot be in disabled state and if priority values are set, + * those are compared and lowest values are considered first. + * + * If @ref obj_inst_id is NULL, this can be used to check if there are any server available. + * + * @param[out] obj_inst_id where selected server instance ID is written. Can be NULL. + * @return true if server instance was found, false otherwise. + */ +bool lwm2m_server_select(uint16_t *obj_inst_id); + +/** + * @brief Disable server instance for a period of time. + * + * Timeout values can be calculated using kernel macros like K_SECONDS(). + * Values like K_FOREVER or K_NO_WAIT are also accepted. + * + * @param timeout Timeout value. + * @return zero on success, negative error code otherwise. + */ +int lwm2m_server_disable(uint16_t obj_inst_id, k_timeout_t timeout); + +/** + * @brief Get timepoint how long server instance is disabled. + * + * If server instance is not disabled, this still returns a valid timepoint + * that have already expired. + * If the instance id is not valid, the timepoint is set to K_FOREVER. + * + * @param obj_inst_id Server instance ID. + * @return timepoint + */ +k_timepoint_t lwm2m_server_get_disabled_time(uint16_t obj_inst_id); + +/** + * @brief Get priority of given server instance. + * + * Lower values mean higher priority. + * If LwM2M server object version 1.1 is not enabled, + * this returns obj_inst_id as priority. + * + * @param obj_inst_id instance ID + * @return priority or UINT8_MAX if instance not found + */ +uint8_t lwm2m_server_get_prio(uint16_t obj_inst_id); + +/** + * @brief Reset all disable-timers for all server instances. + * + */ +void lwm2m_server_reset_timestamps(void); + +#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) +bool lwm2m_server_get_mute_send(uint16_t obj_inst_id); +#endif + + +#endif /* LWM2M_OBJ_SERVER_H_ */ diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 9ee1fa6eda1..1c8034e6535 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -37,6 +37,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include #include #include +#include "lwm2m_obj_server.h" #if defined(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT) #include "lwm2m_rw_senml_json.h" diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index d9f2e229edd..22ce51e5248 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -62,6 +62,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_rd_client.h" #include "lwm2m_rw_link_format.h" #include "lwm2m_util.h" +#include "lwm2m_obj_server.h" #define LWM2M_RD_CLIENT_URI "rd" #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH @@ -71,6 +72,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define DELAY_FOR_ACK 100U #define EXCHANGE_LIFETIME 247U #define MINIMUM_PERIOD 15 +#define DISABLE_TIMEOUT (K_SECONDS(CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES * EXCHANGE_LIFETIME)) static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -79,6 +81,8 @@ static void lwm2m_rd_client_service(struct k_work *work); static int64_t calc_next_event(void); static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms); static void set_sm_state(uint8_t sm_state); +/** Try to fallback to bootstrap. Return true if we did. */ +static bool fallback_to_bootstrap(void); /* The states for the RD client state machine */ /* @@ -100,6 +104,7 @@ enum sm_engine_state { ENGINE_REGISTRATION_DONE_RX_OFF, ENGINE_UPDATE_REGISTRATION, ENGINE_UPDATE_SENT, + ENGINE_SERVER_DISABLED, ENGINE_SUSPENDED, ENGINE_DEREGISTER, ENGINE_DEREGISTER_SENT, @@ -124,11 +129,11 @@ struct lwm2m_rd_client_info { char ep_name[CLIENT_EP_LEN]; char server_ep[CLIENT_EP_LEN]; - bool use_bootstrap : 1; - + bool use_bootstrap : 1; bool trigger_update : 1; bool update_objects : 1; - bool close_socket : 1; + bool close_socket : 1; + bool server_disabled: 1; } client; /* Allocate some data for queries and updates. Make sure it's large enough to @@ -200,23 +205,18 @@ static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE; } else if (sm_state == ENGINE_REGISTRATION_DONE_RX_OFF) { event = LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF; - } else if ((sm_state == ENGINE_INIT || - sm_state == ENGINE_DEREGISTERED) && + } else if (sm_state == ENGINE_DEREGISTERED && (client.engine_state >= ENGINE_DO_REGISTRATION && - client.engine_state <= ENGINE_DEREGISTER_SENT)) { + client.engine_state <= ENGINE_DEREGISTER_SENT) && !client.server_disabled) { event = LWM2M_RD_CLIENT_EVENT_DISCONNECT; - } else if (sm_state == ENGINE_NETWORK_ERROR) { - lwm2m_socket_close(client.ctx); - client.retry_delay = 1 << client.retries; - client.retries++; - if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) { - client.retries = 0; - event = LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR; - } } 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 (client.server_disabled) { + event = LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED; + } else { + event = LWM2M_RD_CLIENT_EVENT_DEREGISTER; + } } if (sm_is_suspended()) { @@ -291,27 +291,22 @@ static uint8_t get_sm_state(void) return state; } -static void sm_handle_timeout_state(struct lwm2m_message *msg, - enum sm_engine_state sm_state) +static void sm_handle_timeout_state(enum sm_engine_state sm_state) { k_mutex_lock(&client.mutex, K_FOREVER); enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE; -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.engine_state == ENGINE_BOOTSTRAP_REG_SENT) { - event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE; - } else -#endif - { - if (client.engine_state == ENGINE_REGISTRATION_SENT) { - event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; - } else if (client.engine_state == ENGINE_UPDATE_SENT) { - event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; - } else if (client.engine_state == ENGINE_DEREGISTER_SENT) { - event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE; - } else { - /* TODO: unknown timeout state */ - } + /* Don't send BOOTSTRAP_REG_FAILURE event, that is only emitted from + * do_network_error() once we are out of retries. + */ + if (client.engine_state == ENGINE_REGISTRATION_SENT) { + event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; + } else if (client.engine_state == ENGINE_UPDATE_SENT) { + event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT; + } else if (client.engine_state == ENGINE_DEREGISTER_SENT) { + event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE; + } else { + /* TODO: unknown timeout state */ } set_sm_state(sm_state); @@ -373,11 +368,14 @@ static void socket_fault_cb(int error) /* Network error state causes engine to re-register, * so only trigger that state if we are not stopping the * engine. + * Also when engine is going to be disabled, for a while, we might get spurious + * socket errors when closing, so ignore them. */ if (client.engine_state > ENGINE_IDLE && - client.engine_state < ENGINE_SUSPENDED) { - set_sm_state(ENGINE_NETWORK_ERROR); - } else if (client.engine_state != ENGINE_SUSPENDED) { + client.engine_state < ENGINE_SERVER_DISABLED) { + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); + } else if (client.engine_state != ENGINE_SUSPENDED && + !client.server_disabled) { sm_handle_failure_state(ENGINE_IDLE); } } @@ -452,13 +450,7 @@ static int do_bootstrap_reply_cb(const struct coap_packet *response, static void do_bootstrap_reg_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("Bootstrap Timeout"); - - /* TODO: - * Look for the "next" BOOTSTRAP server entry in our security info - */ - - /* Restart from scratch */ - sm_handle_timeout_state(msg, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); } #endif @@ -521,6 +513,8 @@ static int do_registration_reply_cb(const struct coap_packet *response, /* remember the last reg time */ client.last_update = k_uptime_get(); + client.server_disabled = false; + client.retries = 0; memcpy(client.server_ep, options[1].value, options[1].len); @@ -532,11 +526,12 @@ static int do_registration_reply_cb(const struct coap_packet *response, return 0; } - LOG_ERR("Failed with code %u.%u (%s). Not Retrying.", + LOG_ERR("Failed with code %u.%u (%s).", COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code), code2str(code)); fail: - sm_handle_failure_state(ENGINE_IDLE); + lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT); + sm_handle_failure_state(ENGINE_NETWORK_ERROR); return ret; } @@ -545,8 +540,7 @@ static void do_registration_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("Registration Timeout"); - /* Restart from scratch */ - sm_handle_timeout_state(msg, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_NETWORK_ERROR); } static int do_update_reply_cb(const struct coap_packet *response, @@ -587,7 +581,7 @@ static void do_update_timeout_cb(struct lwm2m_message *msg) client.close_socket = true; } /* Re-do registration */ - sm_handle_timeout_state(msg, ENGINE_DO_REGISTRATION); + sm_handle_timeout_state(ENGINE_DO_REGISTRATION); } static int do_deregister_reply_cb(const struct coap_packet *response, @@ -611,7 +605,7 @@ static int do_deregister_reply_cb(const struct coap_packet *response, COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code), code2str(code)); - sm_handle_failure_state(ENGINE_IDLE); + sm_handle_failure_state(ENGINE_DEREGISTERED); return 0; } @@ -620,10 +614,10 @@ static void do_deregister_timeout_cb(struct lwm2m_message *msg) { LOG_WRN("De-Registration Timeout"); - sm_handle_timeout_state(msg, ENGINE_IDLE); + sm_handle_timeout_state(ENGINE_DEREGISTERED); } -static bool sm_bootstrap_verify(bool bootstrap_server, int sec_obj_inst) +static bool is_bootsrap_server(int sec_obj_inst) { bool bootstrap; int ret; @@ -633,12 +627,7 @@ static bool sm_bootstrap_verify(bool bootstrap_server, int sec_obj_inst) LOG_WRN("Failed to check bootstrap, err %d", ret); return false; } - - if (bootstrap == bootstrap_server) { - return true; - } else { - return false; - } + return bootstrap; } static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) @@ -664,58 +653,40 @@ static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime) return false; } -static int sm_select_server_inst(int sec_obj_inst, int *srv_obj_inst, - uint32_t *lifetime) -{ - uint16_t server_id; - int ret, obj_inst_id; - - ret = lwm2m_get_u16(&LWM2M_OBJ(0, sec_obj_inst, 10), &server_id); - if (ret < 0) { - LOG_WRN("Failed to obtain Short Server ID, err %d", ret); - return -EINVAL; - } - - obj_inst_id = lwm2m_server_short_id_to_inst(server_id); - if (obj_inst_id < 0) { - LOG_WRN("Failed to obtain Server Object instance, err %d", - obj_inst_id); - return -EINVAL; - } - - sm_update_lifetime(obj_inst_id, lifetime); - *srv_obj_inst = obj_inst_id; - - return 0; -} - -static int sm_select_security_inst(bool bootstrap_server, int *sec_obj_inst) +/** + * @brief Find the next security instance for bootstrapping. + * + * Search for the next security instance that has the bootstrap flag set and + * is not the same as current security instance. + * + * @param sec_obj_inst current security instance or -1. + * @return zero on success, negative on error. + */ +static int sm_next_bootstrap_inst(int *sec_obj_inst) { int i, obj_inst_id = -1; - /* lookup existing index */ - i = lwm2m_security_inst_id_to_index(*sec_obj_inst); - if (i >= 0 && sm_bootstrap_verify(bootstrap_server, *sec_obj_inst)) { - return 0; + if (*sec_obj_inst >= 0 && !is_bootsrap_server(*sec_obj_inst)) { + *sec_obj_inst = -1; } - *sec_obj_inst = -1; - /* Iterate over all instances to find the correct one. */ for (i = 0; i < CONFIG_LWM2M_SECURITY_INSTANCE_COUNT; i++) { obj_inst_id = lwm2m_security_index_to_inst_id(i); if (obj_inst_id < 0) { - LOG_WRN("Failed to get inst id for %d", i); + continue; + } + if (obj_inst_id == *sec_obj_inst) { continue; } - if (sm_bootstrap_verify(bootstrap_server, obj_inst_id)) { + if (is_bootsrap_server(obj_inst_id)) { *sec_obj_inst = obj_inst_id; return 0; } } - LOG_WRN("sec_obj_inst: No matching servers found."); + LOG_WRN("No Bootstrap servers found."); return -ENOENT; } @@ -725,24 +696,17 @@ static int sm_select_security_inst(bool bootstrap_server, int *sec_obj_inst) static int sm_do_init(void) { lwm2m_engine_stop(client.ctx); - client.ctx->sec_obj_inst = -1; - client.ctx->srv_obj_inst = -1; client.trigger_update = false; client.lifetime = 0U; - client.retries = 0U; client.last_update = 0U; client.close_socket = false; /* Do bootstrap or registration */ -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.use_bootstrap) { + if (client.use_bootstrap && IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { set_sm_state(ENGINE_DO_BOOTSTRAP_REG); } else { set_sm_state(ENGINE_DO_REGISTRATION); } -#else - set_sm_state(ENGINE_DO_REGISTRATION); -#endif return 0; } @@ -813,7 +777,7 @@ static int sm_send_bootstrap_registration(void) return ret; } -static int sm_do_bootstrap_reg(void) +static void sm_do_bootstrap_reg(void) { int ret; @@ -823,23 +787,20 @@ static int sm_do_bootstrap_reg(void) } client.ctx->bootstrap_mode = true; - ret = sm_select_security_inst(client.ctx->bootstrap_mode, - &client.ctx->sec_obj_inst); + ret = sm_next_bootstrap_inst(&client.ctx->sec_obj_inst); if (ret < 0) { - /* no bootstrap server found, let's move to registration */ - LOG_WRN("Bootstrap server not found! Try normal registration."); - set_sm_state(ENGINE_DO_REGISTRATION); - return ret; + set_sm_state(ENGINE_NETWORK_ERROR); + return; } - LOG_INF("Bootstrap started with endpoint '%s' with client lifetime %d", - client.ep_name, client.lifetime); + LOG_INF("Bootstrap started with endpoint '%s' using security object %d", + client.ep_name, client.ctx->sec_obj_inst); ret = lwm2m_engine_start(client.ctx); if (ret < 0) { LOG_ERR("Cannot init LWM2M engine (%d)", ret); set_sm_state(ENGINE_NETWORK_ERROR); - return ret; + return; } ret = sm_send_bootstrap_registration(); @@ -850,7 +811,7 @@ static int sm_do_bootstrap_reg(void) set_sm_state(ENGINE_NETWORK_ERROR); } - return ret; + return; } void engine_bootstrap_finish(void) @@ -1046,8 +1007,9 @@ static int sm_send_registration_msg(void) return ret; } -static int sm_do_registration(void) +static void sm_do_registration(void) { + uint16_t ssid; int ret = 0; if (client.ctx->connection_suspended) { @@ -1055,10 +1017,16 @@ static int sm_do_registration(void) lwm2m_engine_context_close(client.ctx); /* perform full registration */ set_sm_state(ENGINE_DO_REGISTRATION); - return 0; + return; } } else { + bool select_srv = true; + uint16_t srv = (uint16_t) client.ctx->srv_obj_inst; + + client.last_update = 0; + client.ctx->bootstrap_mode = false; + /* clear out existing connection data */ if (client.ctx->sock_fd > -1) { if (client.close_socket) { @@ -1067,43 +1035,58 @@ static int sm_do_registration(void) lwm2m_engine_stop(client.ctx); } else { lwm2m_engine_context_close(client.ctx); + /* Keep current connection, retry registration with same server */ + select_srv = false; } } - client.last_update = 0; + if (select_srv) { + /* Select next one from the list, or fail */ + if (!lwm2m_server_select(&srv)) { + LOG_ERR("Unable to find a valid server instance."); + goto bootstrap_or_retry; + } - client.ctx->bootstrap_mode = false; - ret = sm_select_security_inst(client.ctx->bootstrap_mode, - &client.ctx->sec_obj_inst); - if (ret < 0) { - LOG_ERR("Unable to find a valid security instance."); - set_sm_state(ENGINE_INIT); - return -EINVAL; - } + client.ctx->srv_obj_inst = srv; + sm_update_lifetime(srv, &client.lifetime); - ret = sm_select_server_inst(client.ctx->sec_obj_inst, - &client.ctx->srv_obj_inst, - &client.lifetime); - if (ret < 0) { - LOG_ERR("Unable to find a valid server instance."); - set_sm_state(ENGINE_INIT); - return -EINVAL; + ret = lwm2m_get_u16(&LWM2M_OBJ(1, client.ctx->srv_obj_inst, 0), &ssid); + if (ret < 0) { + LOG_ERR("Failed to read SSID"); + lwm2m_server_disable(srv, K_FOREVER); + goto bootstrap_or_retry; + } + + ret = lwm2m_security_short_id_to_inst(ssid); + if (ret < 0) { + LOG_ERR("Unable to find a valid security instance."); + lwm2m_server_disable(srv, K_FOREVER); + goto bootstrap_or_retry; + } + client.ctx->sec_obj_inst = (uint16_t) ret; } - LOG_INF("RD Client started with endpoint '%s' with client lifetime %d", - client.ep_name, client.lifetime); + LOG_INF("RD Client started with endpoint '%s' with client lifetime %d using server " + "object %d", + client.ep_name, client.lifetime, client.ctx->srv_obj_inst); ret = lwm2m_engine_start(client.ctx); if (ret < 0) { LOG_ERR("Cannot init LWM2M engine (%d)", ret); - set_sm_state(ENGINE_NETWORK_ERROR); - return ret; + goto bootstrap_or_retry; } } - ret = sm_send_registration_msg(); + sm_send_registration_msg(); + return; - return ret; +bootstrap_or_retry: + lwm2m_engine_stop(client.ctx); + if (!client.server_disabled && fallback_to_bootstrap()) { + return; + } + + set_sm_state(ENGINE_NETWORK_ERROR); } static int64_t next_update(void) @@ -1149,7 +1132,7 @@ static void sm_registration_done(void) if (sm_is_registered() && (client.trigger_update || now >= next_update())) { - set_sm_state(ENGINE_UPDATE_REGISTRATION); + set_sm_state_delayed(ENGINE_UPDATE_REGISTRATION, DELAY_FOR_ACK); } else if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED) && (client.engine_state != ENGINE_REGISTRATION_DONE_RX_OFF) && (now >= next_rx_off())) { @@ -1268,32 +1251,116 @@ static int sm_do_deregister(void) return ret; } +static bool fallback_to_bootstrap(void) +{ + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + bool fallback = true; + + (void)lwm2m_get_bool(&LWM2M_OBJ(LWM2M_OBJECT_SERVER_ID, client.ctx->srv_obj_inst, + SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID), + &fallback); + if (fallback) { + client.use_bootstrap = true; + set_sm_state(ENGINE_INIT); + return true; + } + } + return false; +} + static void sm_do_network_error(void) { int err; + LOG_ERR("sm_do_network_error, retries %d", client.retries); + + lwm2m_socket_close(client.ctx); + if (client.retry_delay) { - client.retry_delay = 0; next_event_at(k_uptime_get() + client.retry_delay * MSEC_PER_SEC); + client.retry_delay = 0; return; } + client.retry_delay = 1 << client.retries; + client.retries++; -#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) - if (client.ctx->bootstrap_mode) { - lwm2m_engine_context_close(client.ctx); - set_sm_state(ENGINE_DO_BOOTSTRAP_REG); - return; + /* Stop retrying and try fallback */ + if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) { + LOG_ERR("Network error, max retries reached (%d)", client.retries); + + /* Disable current server for a period so lwm2m_server_select() does not pick it */ + if (client.ctx->srv_obj_inst > -1) { + lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT); + } + + /* Are we in bootstrap? Try if we can fallback to some other BS server */ + if (client.ctx->bootstrap_mode && + IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + LOG_DBG("In bootstrap, try fallback srv"); + /* Do we have any other bootstrap server to back off to? */ + if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) { + /* No, we are out of options, stop engine */ + goto stop_engine; + } + set_sm_state(ENGINE_INIT); + return; + } + + /* Try if there are other server to fall back to, + * Only allow fallback to higher priority server (lower value, or lower id) + * if we have successfully registered before. + * This should block us from looping the same list again. + * Instead we should fallback to bootstrap. + */ + uint16_t srv; + + if (lwm2m_server_select(&srv)) { + uint8_t p1, p2; + + p1 = lwm2m_server_get_prio(client.ctx->srv_obj_inst); + p2 = lwm2m_server_get_prio(srv); + if (p1 < p2 || client.last_update != 0) { + set_sm_state(ENGINE_INIT); + return; + } + } + + /* If we have been disabled by some server, don't fall back to bootstrap */ + if (client.server_disabled) { + set_sm_state(ENGINE_SERVER_DISABLED); + return; + } + + if (fallback_to_bootstrap()) { + return; + } + goto stop_engine; + } + + /* Retry bootstrap */ + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) { + if (client.ctx->bootstrap_mode) { + lwm2m_engine_context_close(client.ctx); + /* If we don't have fallback BS server, retry with current one */ + if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) { + client.ctx->sec_obj_inst = -1; + } + set_sm_state(ENGINE_DO_BOOTSTRAP_REG); + return; + } } -#endif if (!client.last_update || (k_uptime_get() - client.last_update) / MSEC_PER_SEC > client.lifetime) { /* do full registration as there is no active registration or lifetime exceeded */ - lwm2m_engine_context_close(client.ctx); + /* Keep the same server until out of retry */ set_sm_state(ENGINE_DO_REGISTRATION); return; } + /* Try if we can recover the DTLS session and try Update. + * This might fallback into full registration on sm_handle_registration_update_failure(). + */ err = lwm2m_socket_start(client.ctx); if (err) { LOG_ERR("Failed to start socket %d", err); @@ -1304,8 +1371,21 @@ static void sm_do_network_error(void) set_sm_state(ENGINE_NETWORK_ERROR); return; } - set_sm_state(ENGINE_UPDATE_REGISTRATION); + return; + +stop_engine: + + /* We are out of options, stop engine */ + if (client.ctx->event_cb) { + if (client.ctx->bootstrap_mode) { + client.ctx->event_cb(client.ctx, + LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE); + } else { + client.ctx->event_cb(client.ctx, LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR); + } + } + set_sm_state(ENGINE_IDLE); } static void lwm2m_rd_client_service(struct k_work *work) @@ -1379,6 +1459,19 @@ static void lwm2m_rd_client_service(struct k_work *work) timeout = EXCHANGE_LIFETIME; break; + case ENGINE_SERVER_DISABLED: + if (lwm2m_server_select(NULL)) { + set_sm_state(ENGINE_INIT); + } else { + /* wait for server to be enabled. */ + /* + * TODO: Once engine is converted to use timepoint_t + * this should calculate the next event from the previous server. + */ + next_event_at(k_uptime_get() + SEC_PER_MIN * MSEC_PER_SEC); + } + break; + case ENGINE_DEREGISTER: sm_do_deregister(); break; @@ -1390,7 +1483,11 @@ static void lwm2m_rd_client_service(struct k_work *work) case ENGINE_DEREGISTERED: lwm2m_engine_stop(client.ctx); - set_sm_state(ENGINE_IDLE); + if (client.server_disabled) { + set_sm_state(ENGINE_SERVER_DISABLED); + } else { + set_sm_state(ENGINE_IDLE); + } break; case ENGINE_NETWORK_ERROR: @@ -1407,7 +1504,7 @@ static void lwm2m_rd_client_service(struct k_work *work) if (end < k_uptime_get()) { LOG_DBG("State machine have timed out"); - sm_handle_timeout_state(NULL, ENGINE_INIT); + sm_handle_timeout_state(ENGINE_INIT); } else if (client.next_event > end) { next_event_at(end); } @@ -1441,6 +1538,7 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name, } /* Init Context */ + lwm2m_server_reset_timestamps(); lwm2m_engine_context_init(client_ctx); client.ctx = client_ctx; @@ -1449,13 +1547,15 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name, client.ctx->observe_cb = observe_cb; client.ctx->event_cb = event_cb; client.use_bootstrap = flags & LWM2M_RD_CLIENT_FLAG_BOOTSTRAP; + client.ctx->srv_obj_inst = -1; + client.ctx->sec_obj_inst = -1; + client.retries = 0; - set_sm_state(ENGINE_INIT); strncpy(client.ep_name, ep_name, CLIENT_EP_LEN - 1); client.ep_name[CLIENT_EP_LEN - 1] = '\0'; LOG_INF("Start LWM2M Client: %s", client.ep_name); - next_event_at(0); + set_sm_state(ENGINE_INIT); k_mutex_unlock(&client.mutex); @@ -1476,9 +1576,10 @@ int lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx, client.ctx->event_cb = event_cb; rd_client_message_free(); - if (sm_is_registered() && deregister) { + if (sm_is_registered() && deregister && !client.server_disabled) { set_sm_state(ENGINE_DEREGISTER); } else { + client.server_disabled = false; set_sm_state(ENGINE_DEREGISTERED); } @@ -1556,7 +1657,7 @@ int lwm2m_rd_client_resume(void) #endif /* Or do we resume into registration state */ if (client.engine_state >= ENGINE_DO_REGISTRATION && - client.engine_state <= ENGINE_SUSPENDED) { + client.engine_state <= ENGINE_SERVER_DISABLED) { if (!client.last_update || (client.lifetime <= (k_uptime_get() - client.last_update) / MSEC_PER_SEC)) { /* No lifetime left, register again */ @@ -1574,6 +1675,29 @@ int lwm2m_rd_client_resume(void) return 0; } +int lwm2m_rd_client_server_disabled(uint16_t inst_id) +{ + if (client.ctx->srv_obj_inst != inst_id) { + return -EPERM; + } + + k_mutex_lock(&client.mutex, K_FOREVER); + + client.server_disabled = true; + + if (sm_is_registered()) { + LOG_INF("Server disabled, deregister"); + set_sm_state_delayed(ENGINE_DEREGISTER, DELAY_BEFORE_CLOSING); + } else { + LOG_INF("Server disabled"); + set_sm_state(ENGINE_DEREGISTERED); + } + + k_mutex_unlock(&client.mutex); + + return 0; +} + void lwm2m_rd_client_update(void) { engine_trigger_update(false); @@ -1602,7 +1726,12 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx) IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE)) || !IS_ENABLED(CONFIG_LWM2M_DTLS_SUPPORT)) { client.engine_state = ENGINE_REGISTRATION_DONE; - client.trigger_update = true; + if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_NO_MSG_BUFFERING)) { + /* Force online for a short period */ + engine_update_tx_time(); + } else { + client.trigger_update = true; + } } else { client.engine_state = ENGINE_DO_REGISTRATION; } diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.h b/subsys/net/lib/lwm2m/lwm2m_rd_client.h index 66a3aac20f3..5d71ccb30f6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.h +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.h @@ -56,4 +56,14 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx); void engine_update_tx_time(void); struct lwm2m_message *lwm2m_get_ongoing_rd_msg(void); +/** + * @brief Notify RD client that this server is disabled. + * + * This may return error -EPERM, if RD client is not registered on that server. + * + * @param inst_id server instance id + * @return int 0 on success, negative errno on failure. + */ +int lwm2m_rd_client_server_disabled(uint16_t inst_id); + #endif /* LWM2M_RD_CLIENT_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index 210c5525756..1701b7f7412 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -890,7 +890,7 @@ int lwm2m_engine_set_u64(const char *pathstr, uint64_t value) if (ret < 0) { return ret; } - return lwm2m_set_u64(&path, value); + return lwm2m_set_s64(&path, (int64_t) value); } int lwm2m_set_s8(const struct lwm2m_obj_path *path, int8_t value) @@ -1378,7 +1378,7 @@ int lwm2m_engine_get_u64(const char *pathstr, uint64_t *value) if (ret < 0) { return ret; } - return lwm2m_get_u64(&path, value); + return lwm2m_get_s64(&path, (int64_t *) value); } int lwm2m_get_s8(const struct lwm2m_obj_path *path, int8_t *value) diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c index daa37d3b4ba..3b35d579569 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_cbor.c @@ -66,7 +66,7 @@ static int put_time(struct lwm2m_output_context *out, struct lwm2m_obj_path *pat ZCBOR_STATE_E(states, 0, CPKT_BUF_W_PTR(out->out_cpkt), CPKT_BUF_W_SIZE(out->out_cpkt), 1); /* Are tags required? V1.1 leaves this unspecified but some servers require tags */ - ret = zcbor_tag_encode(states, ZCBOR_TAG_TIME_TSTR); + ret = zcbor_tag_put(states, ZCBOR_TAG_TIME_TSTR); if (!ret) { LOG_ERR("unable to encode date/time string tag"); @@ -77,7 +77,7 @@ static int put_time(struct lwm2m_output_context *out, struct lwm2m_obj_path *pat out->out_cpkt->offset += tag_sz; - ret = zcbor_tstr_put_term(states, time_str); + ret = zcbor_tstr_put_term(states, time_str, sizeof(time_str)); if (!ret) { LOG_ERR("unable to encode date/time string"); return -ENOMEM; @@ -232,7 +232,7 @@ static int put_objlnk(struct lwm2m_output_context *out, struct lwm2m_obj_path *p static int get_s64(struct lwm2m_input_context *in, int64_t *value) { - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_int64_decode(states, value)) { LOG_WRN("unable to decode a 64-bit integer value"); @@ -248,7 +248,7 @@ static int get_s64(struct lwm2m_input_context *in, int64_t *value) static int get_s32(struct lwm2m_input_context *in, int32_t *value) { - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_int32_decode(states, value)) { LOG_WRN("unable to decode a 32-bit integer value, err: %d", @@ -265,7 +265,7 @@ static int get_s32(struct lwm2m_input_context *in, int32_t *value) static int get_float(struct lwm2m_input_context *in, double *value) { - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_float_decode(states, value)) { LOG_ERR("unable to decode a floating-point value"); @@ -284,7 +284,7 @@ static int get_string(struct lwm2m_input_context *in, uint8_t *value, size_t buf struct zcbor_string hndl; int len; - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_tstr_decode(states, &hndl)) { LOG_WRN("unable to decode a string"); @@ -313,7 +313,7 @@ static int get_time_string(struct lwm2m_input_context *in, int64_t *value) char time_str[sizeof("4294967295")] = { 0 }; struct zcbor_string hndl = { .value = time_str, .len = sizeof(time_str) - 1 }; - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_tstr_decode(states, &hndl)) { return -EBADMSG; @@ -331,7 +331,7 @@ static int get_time_string(struct lwm2m_input_context *in, int64_t *value) */ static int get_time_numerical(struct lwm2m_input_context *in, int64_t *value) { - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_int64_decode(states, value)) { LOG_WRN("unable to decode seconds since Epoch"); @@ -350,7 +350,7 @@ static int get_time(struct lwm2m_input_context *in, time_t *value) bool success; int64_t temp64; - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); success = zcbor_tag_decode(states, &tag); @@ -400,7 +400,7 @@ static int get_time(struct lwm2m_input_context *in, time_t *value) static int get_bool(struct lwm2m_input_context *in, bool *value) { - ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 0, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); if (!zcbor_bool_decode(states, value)) { LOG_WRN("unable to decode a boolean value"); @@ -420,7 +420,7 @@ static int get_opaque(struct lwm2m_input_context *in, uint8_t *value, size_t buf struct zcbor_string_fragment hndl = { 0 }; int ret; - ZCBOR_STATE_D(states, 1, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1); + ZCBOR_STATE_D(states, 1, ICTX_BUF_R_PTR(in), ICTX_BUF_R_LEFT_SZ(in), 1, 0); /* Get the CBOR header only on first read. */ if (opaque->remaining == 0) { diff --git a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c index dd963aa0583..6c20024bbde 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c +++ b/subsys/net/lib/lwm2m/lwm2m_rw_senml_cbor.c @@ -81,12 +81,12 @@ K_MUTEX_DEFINE(fd_mtx); #define GET_CBOR_FD_NAME(fd) ((fd)->names[(fd)->name_cnt]) /* Get the current record */ #define GET_CBOR_FD_REC(fd) \ - &((fd)->input._lwm2m_senml__record[(fd)->input._lwm2m_senml__record_count]) + &((fd)->input.lwm2m_senml_record_m[(fd)->input.lwm2m_senml_record_m_count]) /* Get a record */ -#define GET_IN_FD_REC_I(fd, i) &((fd)->dcd._lwm2m_senml__record[i]) +#define GET_IN_FD_REC_I(fd, i) &((fd)->dcd.lwm2m_senml_record_m[i]) /* Consume the current record */ #define CONSUME_CBOR_FD_REC(fd) \ - &((fd)->input._lwm2m_senml__record[(fd)->input._lwm2m_senml__record_count++]) + &((fd)->input.lwm2m_senml_record_m[(fd)->input.lwm2m_senml_record_m_count++]) /* Get CBOR output formatter data */ #define LWM2M_OFD_CBOR(octx) ((struct cbor_out_fmt_data *)engine_get_out_user_data(octx)) @@ -131,7 +131,7 @@ static int fmt_range_check(struct cbor_out_fmt_data *fd) { if (fd->name_cnt >= CONFIG_LWM2M_RW_SENML_CBOR_RECORDS || fd->objlnk_cnt >= CONFIG_LWM2M_RW_SENML_CBOR_RECORDS || - fd->input._lwm2m_senml__record_count >= CONFIG_LWM2M_RW_SENML_CBOR_RECORDS) { + fd->input.lwm2m_senml_record_m_count >= CONFIG_LWM2M_RW_SENML_CBOR_RECORDS) { LOG_ERR("CONFIG_LWM2M_RW_SENML_CBOR_RECORDS too small"); return -ENOMEM; } @@ -161,9 +161,9 @@ static int put_basename(struct lwm2m_output_context *out, struct lwm2m_obj_path /* Tell CBOR encoder where to find the name */ struct record *record = GET_CBOR_FD_REC(fd); - record->_record_bn._record_bn.value = basename; - record->_record_bn._record_bn.len = len; - record->_record_bn_present = 1; + record->record_bn.record_bn.value = basename; + record->record_bn.record_bn.len = len; + record->record_bn_present = 1; if ((len < sizeof("/0/0") - 1) || (len >= SENML_MAX_NAME_SIZE)) { __ASSERT_NO_MSG(false); @@ -190,7 +190,7 @@ static int put_end(struct lwm2m_output_context *out, struct lwm2m_obj_path *path size_t len; struct lwm2m_senml *input = &(LWM2M_OFD_CBOR(out)->input); - if (!input->_lwm2m_senml__record_count) { + if (!input->lwm2m_senml_record_m_count) { len = put_empty_array(out); return len; @@ -258,9 +258,9 @@ static int put_begin_r(struct lwm2m_output_context *out, struct lwm2m_obj_path * /* Tell CBOR encoder where to find the name */ struct record *record = GET_CBOR_FD_REC(fd); - record->_record_n._record_n.value = name; - record->_record_n._record_n.len = len; - record->_record_n_present = 1; + record->record_n.record_n.value = name; + record->record_n.record_n.len = len; + record->record_n_present = 1; /* Makes possible to use same slot for storing r/ri name combination. * No need to increase the name count if an existing name has been used @@ -287,12 +287,12 @@ static int put_data_timestamp(struct lwm2m_output_context *out, time_t value) out_record = GET_CBOR_FD_REC(fd); if (fd->basetime) { - out_record->_record_t._record_t = value - fd->basetime; - out_record->_record_t_present = 1; + out_record->record_t.record_t = value - fd->basetime; + out_record->record_t_present = 1; } else { fd->basetime = value; - out_record->_record_bt._record_bt = value; - out_record->_record_bt_present = 1; + out_record->record_bt.record_bt = value; + out_record->record_bt_present = 1; } return 0; @@ -332,9 +332,9 @@ static int put_begin_ri(struct lwm2m_output_context *out, struct lwm2m_obj_path } /* Tell CBOR encoder where to find the name */ - record->_record_n._record_n.value = name; - record->_record_n._record_n.len = len; - record->_record_n_present = 1; + record->record_n.record_n.value = name; + record->record_n.record_n.len = len; + record->record_n_present = 1; /* No need to increase the name count if an existing name has been used */ if (name == GET_CBOR_FD_NAME(fd)) { @@ -353,7 +353,7 @@ static int put_name_nth_ri(struct lwm2m_output_context *out, struct lwm2m_obj_pa /* With the first ri the resource name (and ri name) are already in place*/ if (path->res_inst_id > 0) { ret = put_begin_ri(out, path); - } else if (record && record->_record_t_present) { + } else if (record && record->record_t_present) { /* Name need to be add for each time serialized record */ ret = put_begin_r(out, path); } @@ -372,9 +372,9 @@ static int put_value(struct lwm2m_output_context *out, struct lwm2m_obj_path *pa struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vi; - record->_record_union._union_vi = value; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vi_c; + record->record_union.union_vi = value; + record->record_union_present = 1; return 0; } @@ -410,9 +410,9 @@ static int put_time(struct lwm2m_output_context *out, struct lwm2m_obj_path *pat struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vi; - record->_record_union._union_vi = (int64_t)value; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vi_c; + record->record_union.union_vi = (int64_t)value; + record->record_union_present = 1; return 0; } @@ -428,9 +428,9 @@ static int put_float(struct lwm2m_output_context *out, struct lwm2m_obj_path *pa struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vf; - record->_record_union._union_vf = *value; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vf_c; + record->record_union.union_vf = *value; + record->record_union_present = 1; return 0; } @@ -447,10 +447,10 @@ static int put_string(struct lwm2m_output_context *out, struct lwm2m_obj_path *p struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vs; - record->_record_union._union_vs.value = buf; - record->_record_union._union_vs.len = buflen; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vs_c; + record->record_union.union_vs.value = buf; + record->record_union.union_vs.len = buflen; + record->record_union_present = 1; return 0; } @@ -466,9 +466,9 @@ static int put_bool(struct lwm2m_output_context *out, struct lwm2m_obj_path *pat struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vb; - record->_record_union._union_vb = value; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vb_c; + record->record_union.union_vb = value; + record->record_union_present = 1; return 0; } @@ -485,10 +485,10 @@ static int put_opaque(struct lwm2m_output_context *out, struct lwm2m_obj_path *p struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vd; - record->_record_union._union_vd.value = buf; - record->_record_union._union_vd.len = buflen; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vd_c; + record->record_union.union_vd.value = buf; + record->record_union.union_vd.len = buflen; + record->record_union_present = 1; return 0; } @@ -522,10 +522,10 @@ static int put_objlnk(struct lwm2m_output_context *out, struct lwm2m_obj_path *p struct record *record = CONSUME_CBOR_FD_REC(LWM2M_OFD_CBOR(out)); /* Write the value */ - record->_record_union._record_union_choice = _union_vlo; - record->_record_union._union_vlo.value = objlink_buf; - record->_record_union._union_vlo.len = objlnk_len; - record->_record_union_present = 1; + record->record_union.record_union_choice = union_vlo_c; + record->record_union.union_vlo.value = objlink_buf; + record->record_union.union_vlo.len = objlnk_len; + record->record_union_present = 1; fd->objlnk_cnt++; @@ -548,14 +548,14 @@ static int get_opaque(struct lwm2m_input_context *in, return -EINVAL; } - opaque->len = fd->current->_record_union._union_vd.len; + opaque->len = fd->current->record_union.union_vd.len; if (buflen < opaque->len) { LOG_DBG("Write opaque failed, no buffer space"); return -ENOMEM; } - dest = memcpy(value, fd->current->_record_union._union_vd.value, opaque->len); + dest = memcpy(value, fd->current->record_union.union_vd.value, opaque->len); *last_block = true; } else { LOG_DBG("Blockwise transfer not supported with SenML CBOR"); @@ -574,7 +574,7 @@ static int get_s32(struct lwm2m_input_context *in, int32_t *value) return -EINVAL; } - *value = fd->current->_record_union._union_vi; + *value = fd->current->record_union.union_vi; fd->current = NULL; return 0; @@ -589,7 +589,7 @@ static int get_s64(struct lwm2m_input_context *in, int64_t *value) return -EINVAL; } - *value = fd->current->_record_union._union_vi; + *value = fd->current->record_union.union_vi; fd->current = NULL; return 0; @@ -615,7 +615,7 @@ static int get_float(struct lwm2m_input_context *in, double *value) return -EINVAL; } - *value = fd->current->_record_union._union_vf; + *value = fd->current->record_union.union_vf; fd->current = NULL; return 0; @@ -631,9 +631,9 @@ static int get_string(struct lwm2m_input_context *in, uint8_t *buf, size_t bufle return -EINVAL; } - len = MIN(buflen-1, fd->current->_record_union._union_vs.len); + len = MIN(buflen-1, fd->current->record_union.union_vs.len); - memcpy(buf, fd->current->_record_union._union_vs.value, len); + memcpy(buf, fd->current->record_union.union_vs.value, len); buf[len] = '\0'; fd->current = NULL; @@ -698,7 +698,7 @@ static int get_bool(struct lwm2m_input_context *in, bool *value) return -EINVAL; } - *value = fd->current->_record_union._union_vb; + *value = fd->current->record_union.union_vb; fd->current = NULL; return 0; @@ -727,9 +727,9 @@ static int do_write_op_item(struct lwm2m_message *msg, struct record *rec) } /* If there's no name then the basename forms the path */ - if (rec->_record_n_present) { - len = MIN(sizeof(name) - 1, rec->_record_n._record_n.len); - snprintk(name, len + 1, "%s", rec->_record_n._record_n.value); + if (rec->record_n_present) { + len = MIN(sizeof(name) - 1, rec->record_n.record_n.len); + snprintk(name, len + 1, "%s", rec->record_n.record_n.value); } /* Form fully qualified path name */ @@ -853,29 +853,29 @@ static uint8_t parse_composite_read_paths(struct lwm2m_message *msg, msg->in.offset += isize; - for (int idx = 0; idx < fd->dcd._lwm2m_senml__record_count; idx++) { + for (int idx = 0; idx < fd->dcd.lwm2m_senml_record_m_count; idx++) { /* Where to find the basenames and names */ struct record *record = GET_IN_FD_REC_I(fd, idx); /* Set null terminated effective basename */ - if (record->_record_bn_present) { - len = MIN(sizeof(basename)-1, record->_record_bn._record_bn.len); - snprintk(basename, len + 1, "%s", record->_record_bn._record_bn.value); + if (record->record_bn_present) { + len = MIN(sizeof(basename)-1, record->record_bn.record_bn.len); + snprintk(basename, len + 1, "%s", record->record_bn.record_bn.value); basename[len] = '\0'; } /* Best effort with read, skip if no proper name is available */ - if (!record->_record_n_present) { + if (!record->record_n_present) { if (strcmp(basename, "") == 0) { continue; } } /* Set null terminated name */ - if (record->_record_n_present) { - len = MIN(sizeof(name)-1, record->_record_n._record_n.len); - snprintk(name, len + 1, "%s", record->_record_n._record_n.value); + if (record->record_n_present) { + len = MIN(sizeof(name)-1, record->record_n.record_n.len); + snprintk(name, len + 1, "%s", record->record_n.record_n.value); name[len] = '\0'; } @@ -979,30 +979,30 @@ int do_write_op_senml_cbor(struct lwm2m_message *msg) msg->in.offset += decoded_sz; - for (int idx = 0; idx < fd->dcd._lwm2m_senml__record_count; idx++) { + for (int idx = 0; idx < fd->dcd.lwm2m_senml_record_m_count; idx++) { - struct record *rec = &fd->dcd._lwm2m_senml__record[idx]; + struct record *rec = &fd->dcd.lwm2m_senml_record_m[idx]; /* Basename applies for current and succeeding records */ - if (rec->_record_bn_present) { + if (rec->record_bn_present) { int len = MIN(sizeof(fd->basename) - 1, - rec->_record_bn._record_bn.len); + rec->record_bn.record_bn.len); - snprintk(fd->basename, len + 1, "%s", rec->_record_bn._record_bn.value); + snprintk(fd->basename, len + 1, "%s", rec->record_bn.record_bn.value); goto write; } /* Keys' lexicographic order differ from the default */ - for (int jdx = 0; jdx < rec->_record__key_value_pair_count; jdx++) { + for (int jdx = 0; jdx < rec->record_key_value_pair_m_count; jdx++) { struct key_value_pair *kvp = - &(rec->_record__key_value_pair[jdx]._record__key_value_pair); + &(rec->record_key_value_pair_m[jdx].record_key_value_pair_m); - if (kvp->_key_value_pair_key == lwm2m_senml_cbor_key_bn) { + if (kvp->key_value_pair_key == lwm2m_senml_cbor_key_bn) { int len = MIN(sizeof(fd->basename) - 1, - kvp->_key_value_pair._value_tstr.len); + kvp->key_value_pair.value_tstr.len); snprintk(fd->basename, len + 1, "%s", - kvp->_key_value_pair._value_tstr.value); + kvp->key_value_pair.value_tstr.value); break; } } diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor.patch b/subsys/net/lib/lwm2m/lwm2m_senml_cbor.patch index 48b984aafac..41bb3f0a5d4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor.patch +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor.patch @@ -1,94 +1,59 @@ diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c -index f97f0ebb2d..1c1233d616 100644 +index c12f477cce..f41b81275d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 - * https://github.com/NordicSemiconductor/zcbor + * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ -@@ -15,9 +15,6 @@ - #include "zcbor_decode.h" +@@ -16,10 +16,6 @@ #include "lwm2m_senml_cbor_decode.h" + #include "zcbor_print.h" -#if DEFAULT_MAX_QTY != 99 -#error "The type file was generated with a different default_max_qty than this file" -#endif - +- static bool decode_repeated_record_bn(zcbor_state_t *state, struct record_bn *result); static bool decode_repeated_record_bt(zcbor_state_t *state, struct record_bt *result); -@@ -52,7 +49,7 @@ static bool decode_repeated_record_bt( - - bool tmp_result = ((((zcbor_int32_expect(state, (-3)))) - && (zcbor_int64_decode(state, (&(*result)._record_bt))) -- && ((((*result)._record_bt >= -9223372036854775807LL) -+ && ((((*result)._record_bt >= INT64_MIN) - && ((*result)._record_bt <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)))); - - if (!tmp_result) -@@ -82,7 +79,7 @@ static bool decode_repeated_record_t( - - bool tmp_result = ((((zcbor_uint32_expect(state, (6)))) - && (zcbor_int64_decode(state, (&(*result)._record_t))) -- && ((((*result)._record_t >= -9223372036854775807LL) -+ && ((((*result)._record_t >= INT64_MIN) - && ((*result)._record_t <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)))); - - if (!tmp_result) -@@ -100,7 +97,7 @@ static bool decode_repeated_record_union( - - bool tmp_result = (((zcbor_union_start_code(state) && (int_res = (((((zcbor_uint32_expect_union(state, (2)))) - && (zcbor_int64_decode(state, (&(*result)._union_vi))) -- && ((((*result)._union_vi >= -9223372036854775807LL) -+ && ((((*result)._union_vi >= INT64_MIN) - && ((*result)._union_vi <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) && (((*result)._record_union_choice = _union_vi), true)) - || ((((zcbor_uint32_expect_union(state, (2)))) - && (zcbor_float_decode(state, (&(*result)._union_vf)))) && (((*result)._record_union_choice = _union_vf), true)) -@@ -128,7 +125,7 @@ static bool decode_value( - bool tmp_result = (((zcbor_union_start_code(state) && (int_res = ((((zcbor_tstr_decode(state, (&(*result)._value_tstr)))) && (((*result)._value_choice = _value_tstr), true)) - || (((zcbor_bstr_decode(state, (&(*result)._value_bstr)))) && (((*result)._value_choice = _value_bstr), true)) - || (((zcbor_int64_decode(state, (&(*result)._value_int))) -- && ((((*result)._value_int >= -9223372036854775807LL) -+ && ((((*result)._value_int >= INT64_MIN) - && ((*result)._value_int <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) && (((*result)._value_choice = _value_int), true)) - || (((zcbor_float_decode(state, (&(*result)._value_float)))) && (((*result)._value_choice = _value_float), true)) - || (((zcbor_bool_decode(state, (&(*result)._value_bool)))) && (((*result)._value_choice = _value_bool), true))), zcbor_union_end_code(state), int_res)))); -@@ -176,7 +173,7 @@ static bool decode_record( - && zcbor_present_decode(&((*result)._record_n_present), (zcbor_decoder_t *)decode_repeated_record_n, state, (&(*result)._record_n)) - && zcbor_present_decode(&((*result)._record_t_present), (zcbor_decoder_t *)decode_repeated_record_t, state, (&(*result)._record_t)) - && zcbor_present_decode(&((*result)._record_union_present), (zcbor_decoder_t *)decode_repeated_record_union, state, (&(*result)._record_union)) -- && zcbor_multi_decode(0, 5, &(*result)._record__key_value_pair_count, (zcbor_decoder_t *)decode_repeated_record__key_value_pair, state, (&(*result)._record__key_value_pair), sizeof(struct record__key_value_pair))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_map_end_decode(state)))); -+ && zcbor_multi_decode(0, ZCBOR_ARRAY_SIZE(result->_record__key_value_pair), &(*result)._record__key_value_pair_count, (zcbor_decoder_t *)decode_repeated_record__key_value_pair, state, (&(*result)._record__key_value_pair), sizeof(struct record__key_value_pair))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_map_end_decode(state)))); - - if (!tmp_result) - zcbor_trace(); -@@ -189,7 +186,7 @@ static bool decode_lwm2m_senml( + static bool decode_repeated_record_n(zcbor_state_t *state, struct record_n *result); +@@ -209,7 +205,7 @@ static bool decode_record( + && zcbor_present_decode(&((*result).record_n_present), (zcbor_decoder_t *)decode_repeated_record_n, state, (&(*result).record_n)) + && zcbor_present_decode(&((*result).record_t_present), (zcbor_decoder_t *)decode_repeated_record_t, state, (&(*result).record_t)) + && zcbor_present_decode(&((*result).record_union_present), (zcbor_decoder_t *)decode_repeated_record_union, state, (&(*result).record_union)) +- && zcbor_multi_decode(0, 5, &(*result).record_key_value_pair_m_count, (zcbor_decoder_t *)decode_repeated_record_key_value_pair_m, state, (&(*result).record_key_value_pair_m), sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_map_end_decode(state)))); ++ && zcbor_multi_decode(0, ZCBOR_ARRAY_SIZE(result->record_key_value_pair_m), &(*result).record_key_value_pair_m_count, (zcbor_decoder_t *)decode_repeated_record_key_value_pair_m, state, (&(*result).record_key_value_pair_m), sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_map_end_decode(state)))); + + if (!tmp_result) { + zcbor_trace_file(state); +@@ -226,7 +222,7 @@ static bool decode_lwm2m_senml( { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); -- bool tmp_result = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, 99, &(*result)._lwm2m_senml__record_count, (zcbor_decoder_t *)decode_record, state, (&(*result)._lwm2m_senml__record), sizeof(struct record))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))); -+ bool tmp_result = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, ZCBOR_ARRAY_SIZE(result->_lwm2m_senml__record), &(*result)._lwm2m_senml__record_count, (zcbor_decoder_t *)decode_record, state, (&(*result)._lwm2m_senml__record), sizeof(struct record))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))); +- bool tmp_result = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, 99, &(*result).lwm2m_senml_record_m_count, (zcbor_decoder_t *)decode_record, state, (&(*result).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))); ++ bool tmp_result = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode(1, ZCBOR_ARRAY_SIZE(result->lwm2m_senml_record_m), &(*result).lwm2m_senml_record_m_count, (zcbor_decoder_t *)decode_record, state, (&(*result).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))); - if (!tmp_result) - zcbor_trace(); + if (!tmp_result) { + zcbor_trace_file(state); diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h -index cb5d5c9695..7db7ed0591 100644 +index a36f8782c6..b913fb78e9 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 - * https://github.com/NordicSemiconductor/zcbor + * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ -@@ -21,10 +21,6 @@ +@@ -21,11 +21,6 @@ extern "C" { #endif @@ -96,25 +61,26 @@ index cb5d5c9695..7db7ed0591 100644 -#error "The type file was generated with a different default_max_qty than this file" -#endif - - +- int cbor_decode_lwm2m_senml( - const uint8_t *payload, size_t payload_len, + const uint8_t *payload, size_t payload_len, + struct lwm2m_senml *result, diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c -index 982cfca6c3..afdc6a32f7 100644 +index 94926c531f..5521917853 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 - * https://github.com/NordicSemiconductor/zcbor + * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ -@@ -15,10 +15,6 @@ - #include "zcbor_encode.h" +@@ -16,10 +16,6 @@ #include "lwm2m_senml_cbor_encode.h" + #include "zcbor_print.h" -#if DEFAULT_MAX_QTY != 99 -#error "The type file was generated with a different default_max_qty than this file" @@ -123,80 +89,44 @@ index 982cfca6c3..afdc6a32f7 100644 static bool encode_repeated_record_bn(zcbor_state_t *state, const struct record_bn *input); static bool encode_repeated_record_bt(zcbor_state_t *state, const struct record_bt *input); static bool encode_repeated_record_n(zcbor_state_t *state, const struct record_n *input); -@@ -51,7 +47,7 @@ static bool encode_repeated_record_bt( - zcbor_print("%s\r\n", __func__); - - bool tmp_result = ((((zcbor_int32_put(state, (-3)))) -- && ((((*input)._record_bt >= -9223372036854775807LL) -+ && ((((*input)._record_bt >= INT64_MIN) - && ((*input)._record_bt <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) - && (zcbor_int64_encode(state, (&(*input)._record_bt))))); - -@@ -81,7 +77,7 @@ static bool encode_repeated_record_t( - zcbor_print("%s\r\n", __func__); - - bool tmp_result = ((((zcbor_uint32_put(state, (6)))) -- && ((((*input)._record_t >= -9223372036854775807LL) -+ && ((((*input)._record_t >= INT64_MIN) - && ((*input)._record_t <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) - && (zcbor_int64_encode(state, (&(*input)._record_t))))); - -@@ -98,7 +94,7 @@ static bool encode_repeated_record_union( - struct zcbor_string tmp_str; - - bool tmp_result = (((((*input)._record_union_choice == _union_vi) ? (((zcbor_uint32_put(state, (2)))) -- && ((((*input)._union_vi >= -9223372036854775807LL) -+ && ((((*input)._union_vi >= INT64_MIN) - && ((*input)._union_vi <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) - && (zcbor_int64_encode(state, (&(*input)._union_vi)))) - : (((*input)._record_union_choice == _union_vf) ? (((zcbor_uint32_put(state, (2)))) -@@ -126,7 +122,7 @@ static bool encode_value( - - bool tmp_result = (((((*input)._value_choice == _value_tstr) ? ((zcbor_tstr_encode(state, (&(*input)._value_tstr)))) - : (((*input)._value_choice == _value_bstr) ? ((zcbor_bstr_encode(state, (&(*input)._value_bstr)))) -- : (((*input)._value_choice == _value_int) ? (((((*input)._value_int >= -9223372036854775807LL) -+ : (((*input)._value_choice == _value_int) ? (((((*input)._value_int >= INT64_MIN) - && ((*input)._value_int <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) - && (zcbor_int64_encode(state, (&(*input)._value_int)))) - : (((*input)._value_choice == _value_float) ? ((zcbor_float64_encode(state, (&(*input)._value_float)))) -@@ -171,12 +167,12 @@ static bool encode_record( +@@ -204,12 +200,12 @@ static bool encode_record( { - zcbor_print("%s\r\n", __func__); - -- bool tmp_result = (((zcbor_map_start_encode(state, 10) && ((zcbor_present_encode(&((*input)._record_bn_present), (zcbor_encoder_t *)encode_repeated_record_bn, state, (&(*input)._record_bn)) -+ bool tmp_result = (((zcbor_map_start_encode(state, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair)) && ((zcbor_present_encode(&((*input)._record_bn_present), (zcbor_encoder_t *)encode_repeated_record_bn, state, (&(*input)._record_bn)) - && zcbor_present_encode(&((*input)._record_bt_present), (zcbor_encoder_t *)encode_repeated_record_bt, state, (&(*input)._record_bt)) - && zcbor_present_encode(&((*input)._record_n_present), (zcbor_encoder_t *)encode_repeated_record_n, state, (&(*input)._record_n)) - && zcbor_present_encode(&((*input)._record_t_present), (zcbor_encoder_t *)encode_repeated_record_t, state, (&(*input)._record_t)) - && zcbor_present_encode(&((*input)._record_union_present), (zcbor_encoder_t *)encode_repeated_record_union, state, (&(*input)._record_union)) -- && zcbor_multi_encode_minmax(0, 5, &(*input)._record__key_value_pair_count, (zcbor_encoder_t *)encode_repeated_record__key_value_pair, state, (&(*input)._record__key_value_pair), sizeof(struct record__key_value_pair))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_map_end_encode(state, 10)))); -+ && zcbor_multi_encode_minmax(0, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair), &(*input)._record__key_value_pair_count, (zcbor_encoder_t *)encode_repeated_record__key_value_pair, state, (&(*input)._record__key_value_pair), sizeof(struct record__key_value_pair))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_map_end_encode(state, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair))))); - - if (!tmp_result) - zcbor_trace(); -@@ -189,7 +185,7 @@ static bool encode_lwm2m_senml( + zcbor_log("%s\r\n", __func__); + +- bool tmp_result = (((zcbor_map_start_encode(state, 10) && (((!(*input).record_bn_present || encode_repeated_record_bn(state, (&(*input).record_bn))) ++ bool tmp_result = (((zcbor_map_start_encode(state, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m)) && (((!(*input).record_bn_present || encode_repeated_record_bn(state, (&(*input).record_bn))) + && (!(*input).record_bt_present || encode_repeated_record_bt(state, (&(*input).record_bt))) + && (!(*input).record_n_present || encode_repeated_record_n(state, (&(*input).record_n))) + && (!(*input).record_t_present || encode_repeated_record_t(state, (&(*input).record_t))) + && (!(*input).record_union_present || encode_repeated_record_union(state, (&(*input).record_union))) +- && zcbor_multi_encode_minmax(0, 5, &(*input).record_key_value_pair_m_count, (zcbor_encoder_t *)encode_repeated_record_key_value_pair_m, state, (&(*input).record_key_value_pair_m), sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_map_end_encode(state, 10)))); ++ && zcbor_multi_encode_minmax(0, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m), &(*input).record_key_value_pair_m_count, (zcbor_encoder_t *)encode_repeated_record_key_value_pair_m, state, (&(*input).record_key_value_pair_m), sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_map_end_encode(state, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m))))); + + if (!tmp_result) { + zcbor_trace_file(state); +@@ -226,7 +222,7 @@ static bool encode_lwm2m_senml( { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); -- bool tmp_result = (((zcbor_list_start_encode(state, 99) && ((zcbor_multi_encode_minmax(1, 99, &(*input)._lwm2m_senml__record_count, (zcbor_encoder_t *)encode_record, state, (&(*input)._lwm2m_senml__record), sizeof(struct record))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 99)))); -+ bool tmp_result = (((zcbor_list_start_encode(state, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record)) && ((zcbor_multi_encode_minmax(1, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record), &(*input)._lwm2m_senml__record_count, (zcbor_encoder_t *)encode_record, state, (&(*input)._lwm2m_senml__record), sizeof(struct record))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record))))); +- bool tmp_result = (((zcbor_list_start_encode(state, 99) && ((zcbor_multi_encode_minmax(1, 99, &(*input).lwm2m_senml_record_m_count, (zcbor_encoder_t *)encode_record, state, (&(*input).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, 99)))); ++ bool tmp_result = (((zcbor_list_start_encode(state, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m)) && ((zcbor_multi_encode_minmax(1, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m), &(*input).lwm2m_senml_record_m_count, (zcbor_encoder_t *)encode_record, state, (&(*input).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_encode(state), false)) && zcbor_list_end_encode(state, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m))))); - if (!tmp_result) - zcbor_trace(); + if (!tmp_result) { + zcbor_trace_file(state); diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h -index b6c54afde5..cbc32e540c 100644 +index df2f0ac6a1..8fa1eedb2b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 - * https://github.com/NordicSemiconductor/zcbor + * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ -@@ -21,10 +21,6 @@ +@@ -21,11 +21,6 @@ extern "C" { #endif @@ -204,26 +134,36 @@ index b6c54afde5..cbc32e540c 100644 -#error "The type file was generated with a different default_max_qty than this file" -#endif - - +- int cbor_encode_lwm2m_senml( - uint8_t *payload, size_t payload_len, + uint8_t *payload, size_t payload_len, + const struct lwm2m_senml *input, diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h -index e12f33636e..f709086a5c 100644 +index 77649036ef..f0a2958072 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 - * https://github.com/NordicSemiconductor/zcbor + * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ -@@ -20,6 +20,18 @@ +@@ -20,14 +20,18 @@ extern "C" { #endif +-/** Which value for --default-max-qty this file was created with. +- * +- * The define is used in the other generated file to do a build-time +- * compatibility check. +- * +- * See `zcbor --help` for more information about --default-max-qty +- */ +-#define DEFAULT_MAX_QTY 99 ++ +enum lwm2m_senml_cbor_key { + lwm2m_senml_cbor_key_bn = -2, + lwm2m_senml_cbor_key_bt = -3, @@ -235,25 +175,15 @@ index e12f33636e..f709086a5c 100644 + lwm2m_senml_cbor_key_vb = 4, + lwm2m_senml_cbor_key_vd = 8, +}; -+ - /** Which value for --default-max-qty this file was created with. - * - * The define is used in the other generated file to do a build-time -@@ -27,7 +39,7 @@ extern "C" { - * - * See `zcbor --help` for more information about --default-max-qty - */ --#define DEFAULT_MAX_QTY 99 -+#define DEFAULT_MAX_QTY CONFIG_LWM2M_RW_SENML_CBOR_RECORDS struct record_bn { - struct zcbor_string _record_bn; -@@ -118,7 +130,7 @@ struct record { + struct zcbor_string record_bn; +@@ -118,7 +122,7 @@ struct record { }; struct lwm2m_senml { -- struct record _lwm2m_senml__record[99]; -+ struct record _lwm2m_senml__record[DEFAULT_MAX_QTY]; - size_t _lwm2m_senml__record_count; +- struct record lwm2m_senml_record_m[99]; ++ struct record lwm2m_senml_record_m[CONFIG_LWM2M_RW_SENML_CBOR_RECORDS]; + size_t lwm2m_senml_record_m_count; }; diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c index a75aee02120..28b0265b9cc 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ @@ -14,28 +14,32 @@ #include #include "zcbor_decode.h" #include "lwm2m_senml_cbor_decode.h" +#include "zcbor_print.h" static bool decode_repeated_record_bn(zcbor_state_t *state, struct record_bn *result); static bool decode_repeated_record_bt(zcbor_state_t *state, struct record_bt *result); static bool decode_repeated_record_n(zcbor_state_t *state, struct record_n *result); static bool decode_repeated_record_t(zcbor_state_t *state, struct record_t *result); -static bool decode_repeated_record_union(zcbor_state_t *state, struct record_union_ *result); -static bool decode_value(zcbor_state_t *state, struct value_ *result); +static bool decode_repeated_record_union(zcbor_state_t *state, struct record_union_r *result); +static bool decode_value(zcbor_state_t *state, struct value_r *result); static bool decode_key_value_pair(zcbor_state_t *state, struct key_value_pair *result); -static bool decode_repeated_record__key_value_pair(zcbor_state_t *state, - struct record__key_value_pair *result); +static bool decode_repeated_record_key_value_pair_m(zcbor_state_t *state, + struct record_key_value_pair_m *result); static bool decode_record(zcbor_state_t *state, struct record *result); static bool decode_lwm2m_senml(zcbor_state_t *state, struct lwm2m_senml *result); static bool decode_repeated_record_bn(zcbor_state_t *state, struct record_bn *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_int32_expect(state, (-2)))) && - (zcbor_tstr_decode(state, (&(*result)._record_bn))))); + (zcbor_tstr_decode(state, (&(*result).record_bn))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -43,16 +47,19 @@ static bool decode_repeated_record_bn(zcbor_state_t *state, struct record_bn *re static bool decode_repeated_record_bt(zcbor_state_t *state, struct record_bt *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_int32_expect(state, (-3)))) && - (zcbor_int64_decode(state, (&(*result)._record_bt))) && - ((((*result)._record_bt >= INT64_MIN) && ((*result)._record_bt <= INT64_MAX)) || + (zcbor_int64_decode(state, (&(*result).record_bt))) && + ((((*result).record_bt >= INT64_MIN) && ((*result).record_bt <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -60,13 +67,16 @@ static bool decode_repeated_record_bt(zcbor_state_t *state, struct record_bt *re static bool decode_repeated_record_n(zcbor_state_t *state, struct record_n *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_uint32_expect(state, (0)))) && - (zcbor_tstr_decode(state, (&(*result)._record_n))))); + (zcbor_tstr_decode(state, (&(*result).record_n))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -74,86 +84,94 @@ static bool decode_repeated_record_n(zcbor_state_t *state, struct record_n *resu static bool decode_repeated_record_t(zcbor_state_t *state, struct record_t *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_uint32_expect(state, (6)))) && - (zcbor_int64_decode(state, (&(*result)._record_t))) && - ((((*result)._record_t >= INT64_MIN) && ((*result)._record_t <= INT64_MAX)) || + (zcbor_int64_decode(state, (&(*result).record_t))) && + ((((*result).record_t >= INT64_MIN) && ((*result).record_t <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool decode_repeated_record_union(zcbor_state_t *state, struct record_union_ *result) +static bool decode_repeated_record_union(zcbor_state_t *state, struct record_union_r *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); struct zcbor_string tmp_str; bool int_res; bool tmp_result = (((zcbor_union_start_code(state) && (int_res = (((((zcbor_uint32_expect_union(state, (2)))) && - (zcbor_int64_decode(state, (&(*result)._union_vi))) && - ((((*result)._union_vi >= INT64_MIN) && - ((*result)._union_vi <= INT64_MAX)) || + (zcbor_int64_decode(state, (&(*result).union_vi))) && + ((((*result).union_vi >= INT64_MIN) && + ((*result).union_vi <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) && - (((*result)._record_union_choice = _union_vi), true)) || + (((*result).record_union_choice = union_vi_c), true)) || ((((zcbor_uint32_expect_union(state, (2)))) && - (zcbor_float_decode(state, (&(*result)._union_vf)))) && - (((*result)._record_union_choice = _union_vf), true)) || + (zcbor_float_decode(state, (&(*result).union_vf)))) && + (((*result).record_union_choice = union_vf_c), true)) || ((((zcbor_uint32_expect_union(state, (3)))) && - (zcbor_tstr_decode(state, (&(*result)._union_vs)))) && - (((*result)._record_union_choice = _union_vs), true)) || + (zcbor_tstr_decode(state, (&(*result).union_vs)))) && + (((*result).record_union_choice = union_vs_c), true)) || ((((zcbor_uint32_expect_union(state, (4)))) && - (zcbor_bool_decode(state, (&(*result)._union_vb)))) && - (((*result)._record_union_choice = _union_vb), true)) || + (zcbor_bool_decode(state, (&(*result).union_vb)))) && + (((*result).record_union_choice = union_vb_c), true)) || ((((zcbor_uint32_expect_union(state, (8)))) && - (zcbor_bstr_decode(state, (&(*result)._union_vd)))) && - (((*result)._record_union_choice = _union_vd), true)) || + (zcbor_bstr_decode(state, (&(*result).union_vd)))) && + (((*result).record_union_choice = union_vd_c), true)) || (zcbor_union_elem_code(state) && ((((zcbor_tstr_expect( state, ((tmp_str.value = (uint8_t *)"vlo", tmp_str.len = sizeof("vlo") - 1, &tmp_str))))) && - (zcbor_tstr_decode(state, (&(*result)._union_vlo)))) && - (((*result)._record_union_choice = _union_vlo), true)))), + (zcbor_tstr_decode(state, (&(*result).union_vlo)))) && + (((*result).record_union_choice = union_vlo_c), true)))), zcbor_union_end_code(state), int_res)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool decode_value(zcbor_state_t *state, struct value_ *result) +static bool decode_value(zcbor_state_t *state, struct value_r *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool int_res; - bool tmp_result = - (((zcbor_union_start_code(state) && - (int_res = ((((zcbor_tstr_decode(state, (&(*result)._value_tstr)))) && - (((*result)._value_choice = _value_tstr), true)) || - (((zcbor_bstr_decode(state, (&(*result)._value_bstr)))) && - (((*result)._value_choice = _value_bstr), true)) || - (((zcbor_int64_decode(state, (&(*result)._value_int))) && - ((((*result)._value_int >= INT64_MIN) && - ((*result)._value_int <= INT64_MAX)) || - (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) && - (((*result)._value_choice = _value_int), true)) || - (((zcbor_float_decode(state, (&(*result)._value_float)))) && - (((*result)._value_choice = _value_float), true)) || - (((zcbor_bool_decode(state, (&(*result)._value_bool)))) && - (((*result)._value_choice = _value_bool), true))), - zcbor_union_end_code(state), int_res)))); + bool tmp_result = (((zcbor_union_start_code(state) && + (int_res = ((((zcbor_tstr_decode(state, (&(*result).value_tstr)))) && + (((*result).value_choice = value_tstr_c), true)) || + (((zcbor_bstr_decode(state, (&(*result).value_bstr)))) && + (((*result).value_choice = value_bstr_c), true)) || + (((zcbor_int64_decode(state, (&(*result).value_int))) && + ((((*result).value_int >= INT64_MIN) && + ((*result).value_int <= INT64_MAX)) || + (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false))) && + (((*result).value_choice = value_int_c), true)) || + (((zcbor_float_decode(state, (&(*result).value_float)))) && + (((*result).value_choice = value_float_c), true)) || + (((zcbor_bool_decode(state, (&(*result).value_bool)))) && + (((*result).value_choice = value_bool_c), true))), + zcbor_union_end_code(state), int_res)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -161,27 +179,33 @@ static bool decode_value(zcbor_state_t *state, struct value_ *result) static bool decode_key_value_pair(zcbor_state_t *state, struct key_value_pair *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); - bool tmp_result = ((((zcbor_int32_decode(state, (&(*result)._key_value_pair_key)))) && - (decode_value(state, (&(*result)._key_value_pair))))); + bool tmp_result = ((((zcbor_int32_decode(state, (&(*result).key_value_pair_key)))) && + (decode_value(state, (&(*result).key_value_pair))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool decode_repeated_record__key_value_pair(zcbor_state_t *state, - struct record__key_value_pair *result) +static bool decode_repeated_record_key_value_pair_m(zcbor_state_t *state, + struct record_key_value_pair_m *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); - bool tmp_result = (((decode_key_value_pair(state, (&(*result)._record__key_value_pair))))); + bool tmp_result = (((decode_key_value_pair(state, (&(*result).record_key_value_pair_m))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -189,35 +213,38 @@ static bool decode_repeated_record__key_value_pair(zcbor_state_t *state, static bool decode_record(zcbor_state_t *state, struct record *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = (((zcbor_map_start_decode(state) && - ((zcbor_present_decode(&((*result)._record_bn_present), + ((zcbor_present_decode(&((*result).record_bn_present), (zcbor_decoder_t *)decode_repeated_record_bn, state, - (&(*result)._record_bn)) && - zcbor_present_decode(&((*result)._record_bt_present), + (&(*result).record_bn)) && + zcbor_present_decode(&((*result).record_bt_present), (zcbor_decoder_t *)decode_repeated_record_bt, state, - (&(*result)._record_bt)) && - zcbor_present_decode(&((*result)._record_n_present), + (&(*result).record_bt)) && + zcbor_present_decode(&((*result).record_n_present), (zcbor_decoder_t *)decode_repeated_record_n, state, - (&(*result)._record_n)) && - zcbor_present_decode(&((*result)._record_t_present), + (&(*result).record_n)) && + zcbor_present_decode(&((*result).record_t_present), (zcbor_decoder_t *)decode_repeated_record_t, state, - (&(*result)._record_t)) && - zcbor_present_decode(&((*result)._record_union_present), + (&(*result).record_t)) && + zcbor_present_decode(&((*result).record_union_present), (zcbor_decoder_t *)decode_repeated_record_union, state, - (&(*result)._record_union)) && - zcbor_multi_decode(0, ZCBOR_ARRAY_SIZE(result->_record__key_value_pair), - &(*result)._record__key_value_pair_count, - (zcbor_decoder_t *)decode_repeated_record__key_value_pair, - state, (&(*result)._record__key_value_pair), - sizeof(struct record__key_value_pair))) || + (&(*result).record_union)) && + zcbor_multi_decode(0, ZCBOR_ARRAY_SIZE(result->record_key_value_pair_m), + &(*result).record_key_value_pair_m_count, + (zcbor_decoder_t *)decode_repeated_record_key_value_pair_m, + state, (&(*result).record_key_value_pair_m), + sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_map_end_decode(state)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -225,19 +252,22 @@ static bool decode_record(zcbor_state_t *state, struct record *result) static bool decode_lwm2m_senml(zcbor_state_t *state, struct lwm2m_senml *result) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = (((zcbor_list_start_decode(state) && ((zcbor_multi_decode( - 1, ZCBOR_ARRAY_SIZE(result->_lwm2m_senml__record), - &(*result)._lwm2m_senml__record_count, (zcbor_decoder_t *)decode_record, - state, (&(*result)._lwm2m_senml__record), sizeof(struct record))) || + 1, ZCBOR_ARRAY_SIZE(result->lwm2m_senml_record_m), + &(*result).lwm2m_senml_record_m_count, (zcbor_decoder_t *)decode_record, + state, (&(*result).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_decode(state), false)) && zcbor_list_end_decode(state)))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -248,19 +278,7 @@ int cbor_decode_lwm2m_senml(const uint8_t *payload, size_t payload_len, struct l { zcbor_state_t states[5]; - zcbor_new_state(states, sizeof(states) / sizeof(zcbor_state_t), payload, payload_len, 1); - - bool ret = decode_lwm2m_senml(states, result); - - if (ret && (payload_len_out != NULL)) { - *payload_len_out = MIN(payload_len, (size_t)states[0].payload - (size_t)payload); - } - - if (!ret) { - int err = zcbor_pop_error(states); - - zcbor_print("Return error: %d\r\n", err); - return (err == ZCBOR_SUCCESS) ? ZCBOR_ERR_UNKNOWN : err; - } - return ZCBOR_SUCCESS; + return zcbor_entry_function(payload, payload_len, (void *)result, payload_len_out, states, + (zcbor_decoder_t *)decode_lwm2m_senml, + sizeof(states) / sizeof(zcbor_state_t), 1); } diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h index a8ae779b6a1..4e1fdeb66a2 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_decode.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c index 74c9310941b..14ec7431e5b 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ @@ -14,28 +14,32 @@ #include #include "zcbor_encode.h" #include "lwm2m_senml_cbor_encode.h" +#include "zcbor_print.h" static bool encode_repeated_record_bn(zcbor_state_t *state, const struct record_bn *input); static bool encode_repeated_record_bt(zcbor_state_t *state, const struct record_bt *input); static bool encode_repeated_record_n(zcbor_state_t *state, const struct record_n *input); static bool encode_repeated_record_t(zcbor_state_t *state, const struct record_t *input); -static bool encode_repeated_record_union(zcbor_state_t *state, const struct record_union_ *input); -static bool encode_value(zcbor_state_t *state, const struct value_ *input); +static bool encode_repeated_record_union(zcbor_state_t *state, const struct record_union_r *input); +static bool encode_value(zcbor_state_t *state, const struct value_r *input); static bool encode_key_value_pair(zcbor_state_t *state, const struct key_value_pair *input); -static bool encode_repeated_record__key_value_pair(zcbor_state_t *state, - const struct record__key_value_pair *input); +static bool encode_repeated_record_key_value_pair_m(zcbor_state_t *state, + const struct record_key_value_pair_m *input); static bool encode_record(zcbor_state_t *state, const struct record *input); static bool encode_lwm2m_senml(zcbor_state_t *state, const struct lwm2m_senml *input); static bool encode_repeated_record_bn(zcbor_state_t *state, const struct record_bn *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_int32_put(state, (-2)))) && - (zcbor_tstr_encode(state, (&(*input)._record_bn))))); + (zcbor_tstr_encode(state, (&(*input).record_bn))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -43,16 +47,19 @@ static bool encode_repeated_record_bn(zcbor_state_t *state, const struct record_ static bool encode_repeated_record_bt(zcbor_state_t *state, const struct record_bt *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_int32_put(state, (-3)))) && - ((((*input)._record_bt >= INT64_MIN) && ((*input)._record_bt <= INT64_MAX)) || + ((((*input).record_bt >= INT64_MIN) && ((*input).record_bt <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) && - (zcbor_int64_encode(state, (&(*input)._record_bt))))); + (zcbor_int64_encode(state, (&(*input).record_bt))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -60,13 +67,16 @@ static bool encode_repeated_record_bt(zcbor_state_t *state, const struct record_ static bool encode_repeated_record_n(zcbor_state_t *state, const struct record_n *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_uint32_put(state, (0)))) && - (zcbor_tstr_encode(state, (&(*input)._record_n))))); + (zcbor_tstr_encode(state, (&(*input).record_n))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -74,81 +84,98 @@ static bool encode_repeated_record_n(zcbor_state_t *state, const struct record_n static bool encode_repeated_record_t(zcbor_state_t *state, const struct record_t *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((((zcbor_uint32_put(state, (6)))) && - ((((*input)._record_t >= INT64_MIN) && ((*input)._record_t <= INT64_MAX)) || + ((((*input).record_t >= INT64_MIN) && ((*input).record_t <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) && - (zcbor_int64_encode(state, (&(*input)._record_t))))); + (zcbor_int64_encode(state, (&(*input).record_t))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool encode_repeated_record_union(zcbor_state_t *state, const struct record_union_ *input) +static bool encode_repeated_record_union(zcbor_state_t *state, const struct record_union_r *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); struct zcbor_string tmp_str; bool tmp_result = ((( - ((*input)._record_union_choice == _union_vi) + ((*input).record_union_choice == union_vi_c) ? (((zcbor_uint32_put(state, (2)))) && - ((((*input)._union_vi >= INT64_MIN) && - ((*input)._union_vi <= INT64_MAX)) || + ((((*input).union_vi >= INT64_MIN) && + ((*input).union_vi <= INT64_MAX)) || (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) && - (zcbor_int64_encode(state, (&(*input)._union_vi)))) - : (((*input)._record_union_choice == _union_vf) - ? (((zcbor_uint32_put(state, (2)))) && - (zcbor_float64_encode(state, (&(*input)._union_vf)))) - : (((*input)._record_union_choice == _union_vs) - ? (((zcbor_uint32_put(state, (3)))) && - (zcbor_tstr_encode(state, (&(*input)._union_vs)))) - : (((*input)._record_union_choice == _union_vb) - ? (((zcbor_uint32_put(state, (4)))) && - (zcbor_bool_encode(state, (&(*input)._union_vb)))) - : (((*input)._record_union_choice == _union_vd) - ? (((zcbor_uint32_put(state, (8)))) && - (zcbor_bstr_encode(state, (&(*input)._union_vd)))) - : (((*input)._record_union_choice == _union_vlo) - ? (((zcbor_tstr_encode(state, ((tmp_str.value = (uint8_t *)"vlo", - tmp_str.len = sizeof("vlo") - 1, - &tmp_str))))) && - (zcbor_tstr_encode(state, (&(*input)._union_vlo)))) - : false)))))))); + (zcbor_int64_encode(state, (&(*input).union_vi)))) + : (((*input).record_union_choice == union_vf_c) + ? (((zcbor_uint32_put(state, (2)))) && + (zcbor_float64_encode(state, (&(*input).union_vf)))) + : (((*input).record_union_choice == union_vs_c) + ? (((zcbor_uint32_put(state, (3)))) && + (zcbor_tstr_encode(state, (&(*input).union_vs)))) + : (((*input).record_union_choice == union_vb_c) + ? (((zcbor_uint32_put(state, (4)))) && + (zcbor_bool_encode(state, (&(*input).union_vb)))) + : (((*input).record_union_choice == union_vd_c) + ? (((zcbor_uint32_put(state, (8)))) && + (zcbor_bstr_encode(state, (&(*input).union_vd)))) + : (((*input).record_union_choice == union_vlo_c) + ? (((zcbor_tstr_encode( + state, + ((tmp_str.value = (uint8_t *)"vlo", + tmp_str.len = sizeof("vlo") - 1, + &tmp_str))))) && + (zcbor_tstr_encode( + state, + (&(*input).union_vlo)))) + : false)))))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool encode_value(zcbor_state_t *state, const struct value_ *input) +static bool encode_value(zcbor_state_t *state, const struct value_r *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = ((( - ((*input)._value_choice == _value_tstr) - ? ((zcbor_tstr_encode(state, (&(*input)._value_tstr)))) - : (((*input)._value_choice == _value_bstr) - ? ((zcbor_bstr_encode(state, (&(*input)._value_bstr)))) - : (((*input)._value_choice == _value_int) - ? (((((*input)._value_int >= INT64_MIN) && - ((*input)._value_int <= INT64_MAX)) || - (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), false)) && - (zcbor_int64_encode(state, (&(*input)._value_int)))) - : (((*input)._value_choice == _value_float) - ? ((zcbor_float64_encode(state, (&(*input)._value_float)))) - : (((*input)._value_choice == _value_bool) - ? ((zcbor_bool_encode(state, (&(*input)._value_bool)))) - : false))))))); + ((*input).value_choice == value_tstr_c) + ? ((zcbor_tstr_encode(state, (&(*input).value_tstr)))) + : (((*input).value_choice == value_bstr_c) + ? ((zcbor_bstr_encode(state, (&(*input).value_bstr)))) + : (((*input).value_choice == value_int_c) + ? (((((*input).value_int >= INT64_MIN) && + ((*input).value_int <= INT64_MAX)) || + (zcbor_error(state, ZCBOR_ERR_WRONG_RANGE), + false)) && + (zcbor_int64_encode(state, (&(*input).value_int)))) + : (((*input).value_choice == value_float_c) + ? ((zcbor_float64_encode( + state, (&(*input).value_float)))) + : (((*input).value_choice == value_bool_c) + ? ((zcbor_bool_encode( + state, + (&(*input).value_bool)))) + : false))))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -156,27 +183,33 @@ static bool encode_value(zcbor_state_t *state, const struct value_ *input) static bool encode_key_value_pair(zcbor_state_t *state, const struct key_value_pair *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); - bool tmp_result = ((((zcbor_int32_encode(state, (&(*input)._key_value_pair_key)))) && - (encode_value(state, (&(*input)._key_value_pair))))); + bool tmp_result = ((((zcbor_int32_encode(state, (&(*input).key_value_pair_key)))) && + (encode_value(state, (&(*input).key_value_pair))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; } -static bool encode_repeated_record__key_value_pair(zcbor_state_t *state, - const struct record__key_value_pair *input) +static bool encode_repeated_record_key_value_pair_m(zcbor_state_t *state, + const struct record_key_value_pair_m *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); - bool tmp_result = (((encode_key_value_pair(state, (&(*input)._record__key_value_pair))))); + bool tmp_result = (((encode_key_value_pair(state, (&(*input).record_key_value_pair_m))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -184,36 +217,34 @@ static bool encode_repeated_record__key_value_pair(zcbor_state_t *state, static bool encode_record(zcbor_state_t *state, const struct record *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = (( - (zcbor_map_start_encode(state, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair)) && - ((zcbor_present_encode(&((*input)._record_bn_present), - (zcbor_encoder_t *)encode_repeated_record_bn, state, - (&(*input)._record_bn)) && - zcbor_present_encode(&((*input)._record_bt_present), - (zcbor_encoder_t *)encode_repeated_record_bt, state, - (&(*input)._record_bt)) && - zcbor_present_encode(&((*input)._record_n_present), - (zcbor_encoder_t *)encode_repeated_record_n, state, - (&(*input)._record_n)) && - zcbor_present_encode(&((*input)._record_t_present), - (zcbor_encoder_t *)encode_repeated_record_t, state, - (&(*input)._record_t)) && - zcbor_present_encode(&((*input)._record_union_present), - (zcbor_encoder_t *)encode_repeated_record_union, state, - (&(*input)._record_union)) && + (zcbor_map_start_encode(state, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m)) && + (((!(*input).record_bn_present || + encode_repeated_record_bn(state, (&(*input).record_bn))) && + (!(*input).record_bt_present || + encode_repeated_record_bt(state, (&(*input).record_bt))) && + (!(*input).record_n_present || + encode_repeated_record_n(state, (&(*input).record_n))) && + (!(*input).record_t_present || + encode_repeated_record_t(state, (&(*input).record_t))) && + (!(*input).record_union_present || + encode_repeated_record_union(state, (&(*input).record_union))) && zcbor_multi_encode_minmax( - 0, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair), - &(*input)._record__key_value_pair_count, - (zcbor_encoder_t *)encode_repeated_record__key_value_pair, state, - (&(*input)._record__key_value_pair), - sizeof(struct record__key_value_pair))) || + 0, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m), + &(*input).record_key_value_pair_m_count, + (zcbor_encoder_t *)encode_repeated_record_key_value_pair_m, state, + (&(*input).record_key_value_pair_m), + sizeof(struct record_key_value_pair_m))) || (zcbor_list_map_end_force_encode(state), false)) && - zcbor_map_end_encode(state, ZCBOR_ARRAY_SIZE(input->_record__key_value_pair))))); + zcbor_map_end_encode(state, ZCBOR_ARRAY_SIZE(input->record_key_value_pair_m))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -221,19 +252,22 @@ static bool encode_record(zcbor_state_t *state, const struct record *input) static bool encode_lwm2m_senml(zcbor_state_t *state, const struct lwm2m_senml *input) { - zcbor_print("%s\r\n", __func__); + zcbor_log("%s\r\n", __func__); bool tmp_result = - (((zcbor_list_start_encode(state, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record)) && + (((zcbor_list_start_encode(state, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m)) && ((zcbor_multi_encode_minmax( - 1, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record), - &(*input)._lwm2m_senml__record_count, (zcbor_encoder_t *)encode_record, - state, (&(*input)._lwm2m_senml__record), sizeof(struct record))) || + 1, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m), + &(*input).lwm2m_senml_record_m_count, (zcbor_encoder_t *)encode_record, + state, (&(*input).lwm2m_senml_record_m), sizeof(struct record))) || (zcbor_list_map_end_force_encode(state), false)) && - zcbor_list_end_encode(state, ZCBOR_ARRAY_SIZE(input->_lwm2m_senml__record))))); + zcbor_list_end_encode(state, ZCBOR_ARRAY_SIZE(input->lwm2m_senml_record_m))))); if (!tmp_result) { - zcbor_trace(); + zcbor_trace_file(state); + zcbor_log("%s error: %s\r\n", __func__, zcbor_error_str(zcbor_peek_error(state))); + } else { + zcbor_log("%s success\r\n", __func__); } return tmp_result; @@ -244,19 +278,7 @@ int cbor_encode_lwm2m_senml(uint8_t *payload, size_t payload_len, const struct l { zcbor_state_t states[5]; - zcbor_new_state(states, sizeof(states) / sizeof(zcbor_state_t), payload, payload_len, 1); - - bool ret = encode_lwm2m_senml(states, input); - - if (ret && (payload_len_out != NULL)) { - *payload_len_out = MIN(payload_len, (size_t)states[0].payload - (size_t)payload); - } - - if (!ret) { - int err = zcbor_pop_error(states); - - zcbor_print("Return error: %d\r\n", err); - return (err == ZCBOR_SUCCESS) ? ZCBOR_ERR_UNKNOWN : err; - } - return ZCBOR_SUCCESS; + return zcbor_entry_function(payload, payload_len, (void *)input, payload_len_out, states, + (zcbor_decoder_t *)encode_lwm2m_senml, + sizeof(states) / sizeof(zcbor_state_t), 1); } diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h index 05d2664c2a0..fc08ead18d4 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_encode.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_regenerate.sh b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_regenerate.sh index 448a9020862..cf293d7b579 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_regenerate.sh +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_regenerate.sh @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0 git add -A git commit -s -m"pre-patch" -git apply lwm2m_senml_cbor.patch +git apply --reject lwm2m_senml_cbor.patch clang-format -i \ lwm2m_senml_cbor_decode.c lwm2m_senml_cbor_decode.h \ diff --git a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h index f1b86bb60b0..dbb5a368551 100644 --- a/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h +++ b/subsys/net/lib/lwm2m/lwm2m_senml_cbor_types.h @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * Generated using zcbor version 0.7.0 + * Generated using zcbor version 0.8.1 * https://github.com/zephyrproject-rtos/zcbor * Generated with a --default-max-qty of 99 */ @@ -32,115 +32,97 @@ enum lwm2m_senml_cbor_key { lwm2m_senml_cbor_key_vd = 8, }; -/** Which value for --default-max-qty this file was created with. - * - * The define is used in the other generated file to do a build-time - * compatibility check. - * - * See `zcbor --help` for more information about --default-max-qty - */ -#define DEFAULT_MAX_QTY CONFIG_LWM2M_RW_SENML_CBOR_RECORDS - struct record_bn { - struct zcbor_string _record_bn; + struct zcbor_string record_bn; }; struct record_bt { - int64_t _record_bt; + int64_t record_bt; }; struct record_n { - struct zcbor_string _record_n; + struct zcbor_string record_n; }; struct record_t { - int64_t _record_t; + int64_t record_t; }; -/* The union members and enum members have the same names. - * This is intentional so we need to ignore -Wshadow to avoid - * compiler complaining about them. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshadow" - -struct record_union_ { +struct record_union_r { union { struct { - int64_t _union_vi; + int64_t union_vi; }; struct { - double _union_vf; + double union_vf; }; struct { - struct zcbor_string _union_vs; + struct zcbor_string union_vs; }; struct { - bool _union_vb; + bool union_vb; }; struct { - struct zcbor_string _union_vd; + struct zcbor_string union_vd; }; struct { - struct zcbor_string _union_vlo; + struct zcbor_string union_vlo; }; }; enum { - _union_vi, - _union_vf, - _union_vs, - _union_vb, - _union_vd, - _union_vlo, - } _record_union_choice; + union_vi_c, + union_vf_c, + union_vs_c, + union_vb_c, + union_vd_c, + union_vlo_c, + } record_union_choice; }; -struct value_ { +struct value_r { union { - struct zcbor_string _value_tstr; - struct zcbor_string _value_bstr; - int64_t _value_int; - double _value_float; - bool _value_bool; + struct zcbor_string value_tstr; + struct zcbor_string value_bstr; + int64_t value_int; + double value_float; + bool value_bool; }; enum { - _value_tstr, - _value_bstr, - _value_int, - _value_float, - _value_bool, - } _value_choice; + value_tstr_c, + value_bstr_c, + value_int_c, + value_float_c, + value_bool_c, + } value_choice; }; -#pragma GCC diagnostic pop - struct key_value_pair { - int32_t _key_value_pair_key; - struct value_ _key_value_pair; + int32_t key_value_pair_key; + struct value_r key_value_pair; }; -struct record__key_value_pair { - struct key_value_pair _record__key_value_pair; +struct record_key_value_pair_m { + struct key_value_pair record_key_value_pair_m; }; struct record { - struct record_bn _record_bn; - bool _record_bn_present; - struct record_bt _record_bt; - bool _record_bt_present; - struct record_n _record_n; - bool _record_n_present; - struct record_t _record_t; - bool _record_t_present; - struct record_union_ _record_union; - bool _record_union_present; - struct record__key_value_pair _record__key_value_pair[5]; - size_t _record__key_value_pair_count; + struct record_bn record_bn; + bool record_bn_present; + struct record_bt record_bt; + bool record_bt_present; + struct record_n record_n; + bool record_n_present; + struct record_t record_t; + bool record_t_present; + struct record_union_r record_union; + bool record_union_present; + struct record_key_value_pair_m record_key_value_pair_m[5]; + size_t record_key_value_pair_m_count; }; struct lwm2m_senml { - struct record _lwm2m_senml__record[DEFAULT_MAX_QTY]; - size_t _lwm2m_senml__record_count; + struct record lwm2m_senml_record_m[CONFIG_LWM2M_RW_SENML_CBOR_RECORDS]; + size_t lwm2m_senml_record_m_count; }; #ifdef __cplusplus diff --git a/subsys/net/lib/lwm2m/lwm2m_shell.c b/subsys/net/lib/lwm2m/lwm2m_shell.c index a4cedf8cd62..aad7dc5d166 100644 --- a/subsys/net/lib/lwm2m/lwm2m_shell.c +++ b/subsys/net/lib/lwm2m/lwm2m_shell.c @@ -246,14 +246,6 @@ static int cmd_read(const struct shell *sh, size_t argc, char **argv) goto out; } shell_print(sh, "%d\n", temp); - } else if (strcmp(dtype, "-u64") == 0) { - uint64_t temp = 0; - - ret = lwm2m_get_u64(&path, &temp); - if (ret != 0) { - goto out; - } - shell_print(sh, "%lld\n", temp); } else if (strcmp(dtype, "-f") == 0) { double temp = 0; @@ -349,8 +341,6 @@ static int cmd_write(const struct shell *sh, size_t argc, char **argv) ret = lwm2m_set_u16(&path, strtoul(value, &e, 10)); } else if (strcmp(dtype, "-u32") == 0) { ret = lwm2m_set_u32(&path, strtoul(value, &e, 10)); - } else if (strcmp(dtype, "-u64") == 0) { - ret = lwm2m_set_u64(&path, strtoull(value, &e, 10)); } else if (strcmp(dtype, "-b") == 0) { ret = lwm2m_set_bool(&path, strtoul(value, &e, 10)); } else if (strcmp(dtype, "-t") == 0) { diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index c835656b6cf..8e9cc87239a 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -22,10 +22,15 @@ int mqtt_client_tls_connect(struct mqtt_client *client) { const struct sockaddr *broker = client->broker; struct mqtt_sec_config *tls_config = &client->transport.tls.config; + int type = SOCK_STREAM; int ret; + if (tls_config->set_native_tls) { + type |= SOCK_NATIVE_TLS; + } + client->transport.tls.sock = zsock_socket(broker->sa_family, - SOCK_STREAM, IPPROTO_TLS_1_2); + type, IPPROTO_TLS_1_2); if (client->transport.tls.sock < 0) { return -errno; } @@ -78,6 +83,16 @@ int mqtt_client_tls_connect(struct mqtt_client *client) } } + if (tls_config->session_cache == TLS_SESSION_CACHE_ENABLED) { + ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, + TLS_SESSION_CACHE, + &tls_config->session_cache, + sizeof(tls_config->session_cache)); + if (ret < 0) { + goto error; + } + } + if (tls_config->cert_nocopy != TLS_CERT_NOCOPY_NONE) { ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, TLS_CERT_NOCOPY, &tls_config->cert_nocopy, diff --git a/subsys/net/lib/shell/CMakeLists.txt b/subsys/net/lib/shell/CMakeLists.txt index 2c5c0757505..5cfb5c269b4 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(dhcpv4.c) zephyr_library_sources(dns.c) zephyr_library_sources(events.c) zephyr_library_sources(gptp.c) 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/common.h b/subsys/net/lib/shell/common.h deleted file mode 100644 index 8b5566022d9..00000000000 --- a/subsys/net/lib/shell/common.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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" -#include "../ip/ipv6.h" - -struct net_shell_user_data { - const struct shell *sh; - 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 - -#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 - -#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) -#define IFACE_DYN_CMD &iface_index -#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); -void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data); 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/dhcpv4.c b/subsys/net/lib/shell/dhcpv4.c new file mode 100644 index 00000000000..a59b9c45edb --- /dev/null +++ b/subsys/net/lib/shell/dhcpv4.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_DECLARE(net_shell); + +#include +#include +#include + +#include "net_shell_private.h" + +static int cmd_net_dhcpv4_server_start(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_if *iface = NULL; + struct in_addr base_addr; + 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_addr_pton(AF_INET, argv[2], &base_addr)) { + PR_ERROR("Invalid address: %s\n", argv[2]); + return -EINVAL; + } + + ret = net_dhcpv4_server_start(iface, &base_addr); + if (ret == -EALREADY) { + PR_WARNING("DHCPv4 server already running on interface %d\n", idx); + } else if (ret < 0) { + PR_ERROR("DHCPv4 server failed to start on interface %d, error %d\n", + idx, -ret); + } else { + PR("DHCPv4 server started on interface %d\n", idx); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +static int cmd_net_dhcpv4_server_stop(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_if *iface = NULL; + 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_dhcpv4_server_stop(iface); + if (ret == -ENOENT) { + PR_WARNING("DHCPv4 server is not running on interface %d\n", idx); + } else if (ret < 0) { + PR_ERROR("DHCPv4 server failed to stop on interface %d, error %d\n", + idx, -ret); + } else { + PR("DHCPv4 server stopped on interface %d\n", idx); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +#if defined(CONFIG_NET_DHCPV4_SERVER) +static const char *dhcpv4_addr_state_to_str(enum dhcpv4_server_addr_state state) +{ + switch (state) { + case DHCPV4_SERVER_ADDR_FREE: + return "FREE"; + case DHCPV4_SERVER_ADDR_RESERVED: + return "RESERVED"; + case DHCPV4_SERVER_ADDR_ALLOCATED: + return "ALLOCATED"; + case DHCPV4_SERVER_ADDR_DECLINED: + return "DECLINED"; + } + + return ""; +} + +static uint32_t timepoint_to_s(k_timepoint_t timepoint) +{ + k_timeout_t timeout = sys_timepoint_timeout(timepoint); + + if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { + return 0; + } + + if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { + return UINT32_MAX; + } + + return k_ticks_to_ms_floor64(timeout.ticks) / 1000; +} + +static void dhcpv4_lease_cb(struct net_if *iface, + struct dhcpv4_addr_slot *lease, + void *user_data) +{ + struct net_shell_user_data *data = user_data; + const struct shell *sh = data->sh; + int *count = data->user_data; + char expiry_str[] = "4294967295"; /* Lease time is uint32_t, so take + * theoretical max. + */ + char iface_name[IFNAMSIZ] = ""; + + if (*count == 0) { + PR(" Iface Address\t State\tExpiry (sec)\n"); + } + + (*count)++; + + (void)net_if_get_name(iface, iface_name, sizeof(iface_name)); + + if (lease->state == DHCPV4_SERVER_ADDR_DECLINED) { + snprintk(expiry_str, sizeof(expiry_str) - 1, "infinite"); + } else { + snprintk(expiry_str, sizeof(expiry_str) - 1, "%u", + timepoint_to_s(lease->expiry)); + } + + PR("%2d. %6s %15s\t%9s\t%12s\n", + *count, iface_name, net_sprint_ipv4_addr(&lease->addr), + dhcpv4_addr_state_to_str(lease->state), expiry_str); +} +#endif /* CONFIG_NET_DHCPV4_SERVER */ + +static int cmd_net_dhcpv4_server_status(const struct shell *sh, size_t argc, char *argv[]) +{ +#if defined(CONFIG_NET_DHCPV4_SERVER) + struct net_shell_user_data user_data; + struct net_if *iface = NULL; + int idx = 0, ret; + int count = 0; + + if (argc > 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; + } + } + + user_data.sh = sh; + user_data.user_data = &count; + + ret = net_dhcpv4_server_foreach_lease(iface, dhcpv4_lease_cb, &user_data); + if (ret == -ENOENT) { + PR_WARNING("DHCPv4 server is not running on interface %d\n", idx); + } else if (count == 0) { + PR("DHCPv4 server - no addresses assigned\n"); + } +#else /* CONFIG_NET_DHCPV4_SERVER */ + PR_INFO("Set %s to enable %s support.\n", + "CONFIG_NET_DHCPV4_SERVER", "DHCPv4 server"); +#endif /* CONFIG_NET_DHCPV4_SERVER */ + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dhcpv4_server, + SHELL_CMD_ARG(start, NULL, "Start the DHCPv4 server operation on the interface.\n" + "'net dhcpv4 server start '\n" + " is the network interface index.\n" + " is the first address for the address pool.", + cmd_net_dhcpv4_server_start, 3, 0), + SHELL_CMD_ARG(stop, NULL, "Stop the DHCPv4 server operation on the interface.\n" + "'net dhcpv4 server stop '\n" + " is the network interface index.", + cmd_net_dhcpv4_server_stop, 2, 0), + SHELL_CMD_ARG(status, NULL, "Print the DHCPv4 server status on the interface.\n" + "'net dhcpv4 server status '\n" + " is the network interface index. Optional.", + cmd_net_dhcpv4_server_status, 1, 1), + SHELL_SUBCMD_SET_END +); + +SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_dhcpv4, + SHELL_CMD(server, &net_cmd_dhcpv4_server, + "DHCPv4 server service management.", + NULL), + SHELL_SUBCMD_SET_END +); + +SHELL_SUBCMD_ADD((net), dhcpv4, &net_cmd_dhcpv4, "Manage DHPCv4 services.", + NULL, 1, 0); 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/net_shell_private.h b/subsys/net/lib/shell/net_shell_private.h new file mode 100644 index 00000000000..076bfd63d33 --- /dev/null +++ b/subsys/net/lib/shell/net_shell_private.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define PR(fmt, ...) \ + do { \ + if (sh) { \ + shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__); \ + } else { \ + printk(fmt, ##__VA_ARGS__); \ + } \ + } while (false) + +#define PR_SHELL(sh, fmt, ...) \ + do { \ + if (sh) { \ + shell_fprintf(sh, SHELL_NORMAL, fmt, ##__VA_ARGS__); \ + } else { \ + printk(fmt, ##__VA_ARGS__); \ + } \ + } while (false) + +#define PR_ERROR(fmt, ...) \ + do { \ + if (sh) { \ + shell_fprintf(sh, SHELL_ERROR, fmt, ##__VA_ARGS__); \ + } else { \ + printk(fmt, ##__VA_ARGS__); \ + } \ + } while (false) + +#define PR_INFO(fmt, ...) \ + do { \ + if (sh) { \ + shell_fprintf(sh, SHELL_INFO, fmt, ##__VA_ARGS__); \ + } else { \ + printk(fmt, ##__VA_ARGS__); \ + } \ + } while (false) + +#define PR_WARNING(fmt, ...) \ + do { \ + if (sh) { \ + shell_fprintf(sh, SHELL_WARNING, fmt, ##__VA_ARGS__); \ + } else { \ + printk(fmt, ##__VA_ARGS__); \ + } \ + } while (false) + +#include "net_private.h" +#include "../ip/ipv6.h" + +struct net_shell_user_data { + const struct shell *sh; + 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 + +#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 + +#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION) +#define IFACE_DYN_CMD &iface_index +#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); +void ipv6_frag_cb(struct net_ipv6_reassembly *reass, void *user_data); 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" diff --git a/subsys/net/lib/sockets/CMakeLists.txt b/subsys/net/lib/sockets/CMakeLists.txt index 7ffd6dc476b..253cb4a182f 100644 --- a/subsys/net/lib/sockets/CMakeLists.txt +++ b/subsys/net/lib/sockets/CMakeLists.txt @@ -26,6 +26,7 @@ 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) +zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_SERVICE sockets_service.c) if(CONFIG_NET_SOCKETS_NET_MGMT) zephyr_library_sources(sockets_net_mgmt.c) diff --git a/subsys/net/lib/sockets/Kconfig b/subsys/net/lib/sockets/Kconfig index b2da30c1e48..4d6c091b749 100644 --- a/subsys/net/lib/sockets/Kconfig +++ b/subsys/net/lib/sockets/Kconfig @@ -73,6 +73,53 @@ config NET_SOCKET_MAX_SEND_WAIT The maximum time a socket is waiting for a blocked connection before returning an ENOBUFS error. +config NET_SOCKETS_SERVICE + bool "Socket service support [EXPERIMENTAL]" + select EXPERIMENTAL + select EVENTFD + help + The socket service can monitor multiple sockets and save memory + by only having one thread listening socket data. If data is received + in the monitored socket, a user supplied work is called. + Note that you need to set CONFIG_NET_SOCKETS_POLL_MAX high enough + so that enough sockets entries can be serviced. This depends on + system needs as multiple services can be activated at the same time + depending on network configuration. + +config NET_SOCKETS_SERVICE_THREAD_PRIO + int "Priority of the socket service dispatcher thread" + default NUM_PREEMPT_PRIORITIES + depends on NET_SOCKETS_SERVICE + help + Set the priority of the socket service dispatcher thread. This handler + polls the sockets and either places the triggered socket to work queue + for asynchronous handlers, or calls the user supplied callback directly + for synchronous handlers. + The value should be selected carefully because if this thread priority + is too high, the work queue handlers might not be able to run if using + asynchronous handlers that are called via a work queue. + + Note that >= 0 value means preemptive thread priority, the lowest + value is NUM_PREEMPT_PRIORITIES. + Highest preemptive thread priority is 0. + Lowest cooperative thread priority is -1. + Highest cooperative thread priority is -NUM_COOP_PRIORITIES. + Make sure the priority is lower than workqueue priority so that + we never block the workqueue handler. + +config NET_SOCKETS_SERVICE_STACK_SIZE + int "Stack size for the thread handling socket services" + default 2400 if NET_DHCPV4_SERVER + default 1200 + depends on NET_SOCKETS_SERVICE + help + Set the internal stack size for the thread that polls sockets. + +config NET_SOCKETS_SERVICE_INIT_PRIO + int "Startup priority for the network socket service" + default 95 + depends on NET_SOCKETS_SERVICE + config NET_SOCKETS_SOCKOPT_TLS bool "TCP TLS socket option support [EXPERIMENTAL]" imply TLS_CREDENTIALS diff --git a/subsys/net/lib/sockets/sockets.c b/subsys/net/lib/sockets/sockets.c index d35317352c9..060c7fff8f7 100644 --- a/subsys/net/lib/sockets/sockets.c +++ b/subsys/net/lib/sockets/sockets.c @@ -681,7 +681,9 @@ int z_impl_zsock_accept(int sock, struct sockaddr *addr, socklen_t *addrlen) new_sock = VTABLE_CALL(accept, sock, addr, addrlen); - (void)sock_obj_core_alloc_find(sock, new_sock, addr->sa_family, SOCK_STREAM); + if (addr) { + (void)sock_obj_core_alloc_find(sock, new_sock, addr->sa_family, SOCK_STREAM); + } return new_sock; } diff --git a/subsys/net/lib/sockets/sockets_packet.c b/subsys/net/lib/sockets/sockets_packet.c index bcf063abe29..ce4f83190c4 100644 --- a/subsys/net/lib/sockets/sockets_packet.c +++ b/subsys/net/lib/sockets/sockets_packet.c @@ -144,6 +144,10 @@ static void zpacket_set_eth_pkttype(struct net_if *iface, struct sockaddr_ll *addr, struct net_linkaddr *lladdr) { + if (lladdr == NULL || lladdr->addr == NULL) { + return; + } + if (net_eth_is_addr_broadcast((struct net_eth_addr *)lladdr->addr)) { addr->sll_pkttype = PACKET_BROADCAST; } else if (net_eth_is_addr_multicast( diff --git a/subsys/net/lib/sockets/sockets_service.c b/subsys/net/lib/sockets/sockets_service.c new file mode 100644 index 00000000000..89b653d31e5 --- /dev/null +++ b/subsys/net/lib/sockets/sockets_service.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(net_sock_svc, CONFIG_NET_SOCKETS_LOG_LEVEL); + +#include +#include +#include + +static int init_socket_service(void); +static bool init_done; + +static K_MUTEX_DEFINE(lock); +static K_CONDVAR_DEFINE(wait_start); + +STRUCT_SECTION_START_EXTERN(net_socket_service_desc); +STRUCT_SECTION_END_EXTERN(net_socket_service_desc); + +static struct service { + /* The +1 is for triggering events from register function */ + struct zsock_pollfd events[1 + CONFIG_NET_SOCKETS_POLL_MAX]; + int count; +} ctx; + +#define get_idx(svc) (*(svc->idx)) + +void net_socket_service_foreach(net_socket_service_cb_t cb, void *user_data) +{ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + cb(svc, user_data); + } +} + +static void cleanup_svc_events(const struct net_socket_service_desc *svc) +{ + for (int i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i].fd = -1; + svc->pev[i].event.fd = -1; + svc->pev[i].event.events = 0; + } +} + +int z_impl_net_socket_service_register(const struct net_socket_service_desc *svc, + struct zsock_pollfd *fds, int len, + void *user_data) +{ + int i, ret = -ENOENT; + + k_mutex_lock(&lock, K_FOREVER); + + if (!init_done) { + (void)k_condvar_wait(&wait_start, &lock, K_FOREVER); + } + + if (STRUCT_SECTION_START(net_socket_service_desc) > svc || + STRUCT_SECTION_END(net_socket_service_desc) <= svc) { + goto out; + } + + if (fds == NULL) { + cleanup_svc_events(svc); + } else { + if (len > svc->pev_len) { + NET_DBG("Too many file descriptors, " + "max is %d for service %p", + svc->pev_len, svc); + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < len; i++) { + svc->pev[i].event = fds[i]; + svc->pev[i].user_data = user_data; + } + + for (i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i] = svc->pev[i].event; + } + } + + /* Tell the thread to re-read the variables */ + eventfd_write(ctx.events[0].fd, 1); + ret = 0; + +out: + k_mutex_unlock(&lock); + + return ret; +} + +static struct net_socket_service_desc *find_svc_and_event( + struct zsock_pollfd *pev, + struct net_socket_service_event **event) +{ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + for (int i = 0; i < svc->pev_len; i++) { + if (svc->pev[i].event.fd == pev->fd) { + *event = &svc->pev[i]; + return svc; + } + } + } + + return NULL; +} + +/* We do not set the user callback to our work struct because we need to + * hook into the flow and restore the global poll array so that the next poll + * round will not notice it and call the callback again while we are + * servicing the callback. + */ +void net_socket_service_callback(struct k_work *work) +{ + struct net_socket_service_event *pev = + CONTAINER_OF(work, struct net_socket_service_event, work); + struct net_socket_service_desc *svc = pev->svc; + struct net_socket_service_event ev = *pev; + + ev.callback(&ev.work); + + /* Copy back the socket fd to the global array because we marked + * it as -1 when triggering the work. + */ + for (int i = 0; i < svc->pev_len; i++) { + ctx.events[get_idx(svc) + i] = svc->pev[i].event; + } +} + +static int call_work(struct zsock_pollfd *pev, struct k_work_q *work_q, + struct k_work *work) +{ + int ret = 0; + + /* Mark the global fd non pollable so that we do not + * call the callback second time. + */ + pev->fd = -1; + + if (work->handler == NULL) { + /* Synchronous call */ + net_socket_service_callback(work); + } else { + if (work_q != NULL) { + ret = k_work_submit_to_queue(work_q, work); + } else { + ret = k_work_submit(work); + } + + k_yield(); + } + + return ret; + +} + +static int trigger_work(struct zsock_pollfd *pev) +{ + struct net_socket_service_event *event; + struct net_socket_service_desc *svc; + + svc = find_svc_and_event(pev, &event); + if (svc == NULL) { + return -ENOENT; + } + + event->svc = svc; + + /* Copy the triggered event to our event so that we know what + * was actually causing the event. + */ + event->event = *pev; + + return call_work(pev, svc->work_q, &event->work); +} + +static void socket_service_thread(void) +{ + int ret, i, fd, count = 0; + eventfd_t value; + + STRUCT_SECTION_COUNT(net_socket_service_desc, &ret); + if (ret == 0) { + NET_INFO("No socket services found, service disabled."); + goto fail; + } + + /* Create contiguous poll event array to enable socket polling */ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + get_idx(svc) = count + 1; + count += svc->pev_len; + } + + if ((count + 1) > ARRAY_SIZE(ctx.events)) { + NET_ERR("You have %d services to monitor but " + "%zd poll entries configured.", + count + 1, ARRAY_SIZE(ctx.events)); + NET_ERR("Please increase value of %s to at least %d", + "CONFIG_NET_SOCKETS_POLL_MAX", count + 1); + goto fail; + } + + NET_DBG("Monitoring %d socket entries", count); + + ctx.count = count + 1; + + /* Create an eventfd that can be used to trigger events during polling */ + fd = eventfd(0, 0); + if (fd < 0) { + fd = -errno; + NET_ERR("eventfd failed (%d)", fd); + goto out; + } + + init_done = true; + k_condvar_broadcast(&wait_start); + + ctx.events[0].fd = fd; + ctx.events[0].events = ZSOCK_POLLIN; + +restart: + i = 1; + + k_mutex_lock(&lock, K_FOREVER); + + /* Copy individual events to the big array */ + STRUCT_SECTION_FOREACH(net_socket_service_desc, svc) { + for (int j = 0; j < svc->pev_len; j++) { + ctx.events[get_idx(svc) + j] = svc->pev[j].event; + } + } + + k_mutex_unlock(&lock); + + while (true) { + ret = zsock_poll(ctx.events, count + 1, -1); + if (ret < 0) { + ret = -errno; + NET_ERR("poll failed (%d)", ret); + goto out; + } + + if (ret == 0) { + /* should not happen because timeout is -1 */ + break; + } + + if (ret > 0 && ctx.events[0].revents) { + eventfd_read(ctx.events[0].fd, &value); + NET_DBG("Received restart event."); + goto restart; + } + + for (i = 1; i < (count + 1); i++) { + if (ctx.events[i].fd < 0) { + continue; + } + + if (ctx.events[i].revents > 0) { + ret = trigger_work(&ctx.events[i]); + if (ret < 0) { + NET_DBG("Triggering work failed (%d)", ret); + } + } + } + } + +out: + NET_DBG("Socket service thread stopped"); + init_done = false; + + return; + +fail: + k_condvar_broadcast(&wait_start); +} + +static int init_socket_service(void) +{ + k_tid_t ssm; + static struct k_thread service_thread; + + static K_THREAD_STACK_DEFINE(service_thread_stack, + CONFIG_NET_SOCKETS_SERVICE_STACK_SIZE); + + ssm = k_thread_create(&service_thread, + service_thread_stack, + K_THREAD_STACK_SIZEOF(service_thread_stack), + (k_thread_entry_t)socket_service_thread, NULL, NULL, NULL, + CLAMP(CONFIG_NET_SOCKETS_SERVICE_THREAD_PRIO, + K_HIGHEST_APPLICATION_THREAD_PRIO, + K_LOWEST_APPLICATION_THREAD_PRIO), 0, K_NO_WAIT); + + k_thread_name_set(ssm, "net_socket_service"); + + return 0; +} + +SYS_INIT(init_socket_service, APPLICATION, CONFIG_NET_SOCKETS_SERVICE_INIT_PRIO); diff --git a/subsys/net/lib/tls_credentials/CMakeLists.txt b/subsys/net/lib/tls_credentials/CMakeLists.txt index 490a558953d..5a80bed58a6 100644 --- a/subsys/net/lib/tls_credentials/CMakeLists.txt +++ b/subsys/net/lib/tls_credentials/CMakeLists.txt @@ -15,3 +15,9 @@ zephyr_library_sources_ifdef(CONFIG_TLS_CREDENTIALS_SHELL ) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) + +if (CONFIG_TLS_CREDENTIALS_BACKEND_PROTECTED_STORAGE AND CONFIG_BUILD_WITH_TFM) + target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE + $/api_ns/interface/include + ) +endif() diff --git a/subsys/net/lib/trickle/CMakeLists.txt b/subsys/net/lib/trickle/CMakeLists.txt new file mode 100644 index 00000000000..b9cf222aab5 --- /dev/null +++ b/subsys/net/lib/trickle/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources( + trickle.c + ) diff --git a/subsys/net/lib/trickle/Kconfig b/subsys/net/lib/trickle/Kconfig new file mode 100644 index 00000000000..edc4f8fcf56 --- /dev/null +++ b/subsys/net/lib/trickle/Kconfig @@ -0,0 +1,18 @@ +# Trickle Library for Zephyr + +# Copyright (c) 2016 Intel Corporation. +# SPDX-License-Identifier: Apache-2.0 + +config NET_TRICKLE + bool "Trickle library" + help + Normally this is enabled automatically if needed, + so say 'n' if unsure. + +if NET_TRICKLE +module = NET_TRICKLE +module-dep = NET_LOG +module-str = Log level for Trickle algorithm +module-help = Enables Trickle library output debug messages +source "subsys/net/Kconfig.template.log_config.net" +endif # NET_TRICKLE diff --git a/subsys/net/ip/trickle.c b/subsys/net/lib/trickle/trickle.c similarity index 100% rename from subsys/net/ip/trickle.c rename to subsys/net/lib/trickle/trickle.c diff --git a/subsys/net/lib/zperf/Kconfig b/subsys/net/lib/zperf/Kconfig index 204144a805b..0cb637f376e 100644 --- a/subsys/net/lib/zperf/Kconfig +++ b/subsys/net/lib/zperf/Kconfig @@ -5,6 +5,7 @@ menuconfig NET_ZPERF bool "zperf shell utility" select NET_CONTEXT_RCVTIMEO if NET_NATIVE_UDP + select NET_SOCKETS_SERVICE help This option enables zperf shell utility, which allows to generate network traffic and evaluate network bandwidth. diff --git a/subsys/net/lib/zperf/zperf_common.c b/subsys/net/lib/zperf/zperf_common.c index 4bc675ed45e..89224b691ca 100644 --- a/subsys/net/lib/zperf/zperf_common.c +++ b/subsys/net/lib/zperf/zperf_common.c @@ -222,8 +222,6 @@ static int zperf_init(void) zperf_udp_uploader_init(); zperf_tcp_uploader_init(); - zperf_udp_receiver_init(); - zperf_tcp_receiver_init(); zperf_session_init(); diff --git a/subsys/net/lib/zperf/zperf_internal.h b/subsys/net/lib/zperf/zperf_internal.h index 592424a9446..b8cdb84cbbf 100644 --- a/subsys/net/lib/zperf/zperf_internal.h +++ b/subsys/net/lib/zperf/zperf_internal.h @@ -103,8 +103,6 @@ uint32_t zperf_packet_duration(uint32_t packet_size, uint32_t rate_in_kbps); void zperf_async_work_submit(struct k_work *work); void zperf_udp_uploader_init(void); void zperf_tcp_uploader_init(void); -void zperf_udp_receiver_init(void); -void zperf_tcp_receiver_init(void); void zperf_shell_init(void); diff --git a/subsys/net/lib/zperf/zperf_session.c b/subsys/net/lib/zperf/zperf_session.c index 3b72367e179..6fff4abf9cc 100644 --- a/subsys/net/lib/zperf/zperf_session.c +++ b/subsys/net/lib/zperf/zperf_session.c @@ -102,14 +102,27 @@ void zperf_reset_session_stats(struct session *session) session->last_transit_time = 0; } -void zperf_session_init(void) +void zperf_session_reset(enum session_proto proto) { int i, j; + if (proto >= SESSION_PROTO_END) { + return; + } + + i = (int)proto; + + for (j = 0; j < SESSION_MAX; j++) { + sessions[i][j].state = STATE_NULL; + zperf_reset_session_stats(&(sessions[i][j])); + } +} + +void zperf_session_init(void) +{ + int i; + for (i = 0; i < SESSION_PROTO_END; i++) { - for (j = 0; j < SESSION_MAX; j++) { - sessions[i][j].state = STATE_NULL; - zperf_reset_session_stats(&(sessions[i][j])); - } + zperf_session_reset(i); } } diff --git a/subsys/net/lib/zperf/zperf_session.h b/subsys/net/lib/zperf/zperf_session.h index ea28dec2c60..f01bc66b71a 100644 --- a/subsys/net/lib/zperf/zperf_session.h +++ b/subsys/net/lib/zperf/zperf_session.h @@ -58,5 +58,7 @@ struct session *get_session(const struct sockaddr *addr, enum session_proto proto); void zperf_session_init(void); void zperf_reset_session_stats(struct session *session); +/* Reset all sessions for a given protocol. */ +void zperf_session_reset(enum session_proto proto); #endif /* __ZPERF_SESSION_H */ diff --git a/subsys/net/lib/zperf/zperf_shell.c b/subsys/net/lib/zperf/zperf_shell.c index 444cf125c31..2c30c1e33e3 100644 --- a/subsys/net/lib/zperf/zperf_shell.c +++ b/subsys/net/lib/zperf/zperf_shell.c @@ -76,9 +76,9 @@ static struct in_addr shell_ipv4; const uint32_t TIME_US[] = { 60 * 1000 * 1000, 1000 * 1000, 1000, 0 }; const char *TIME_US_UNIT[] = { "m", "s", "ms", "us" }; -const uint32_t KBPS[] = { 1024, 0 }; +const uint32_t KBPS[] = { 1000, 0 }; const char *KBPS_UNIT[] = { "Mbps", "Kbps" }; -const uint32_t K[] = { 1024 * 1024, 1024, 0 }; +const uint32_t K[] = { 1000 * 1000, 1000, 0 }; const char *K_UNIT[] = { "M", "K", "" }; static void print_number(const struct shell *sh, uint32_t value, @@ -308,7 +308,7 @@ static void udp_session_cb(enum zperf_status status, rate_in_kbps = (uint32_t) (((uint64_t)result->total_len * 8ULL * (uint64_t)USEC_PER_SEC) / - ((uint64_t)result->time_in_us * 1024ULL)); + ((uint64_t)result->time_in_us * 1000ULL)); } else { rate_in_kbps = 0U; } @@ -408,7 +408,7 @@ static void shell_udp_upload_print_stats(const struct shell *sh, rate_in_kbps = (uint32_t) (((uint64_t)results->total_len * (uint64_t)8 * (uint64_t)USEC_PER_SEC) / - ((uint64_t)results->time_in_us * 1024U)); + ((uint64_t)results->time_in_us * 1000U)); } else { rate_in_kbps = 0U; } @@ -418,7 +418,7 @@ static void shell_udp_upload_print_stats(const struct shell *sh, (((uint64_t)results->nb_packets_sent * (uint64_t)results->packet_size * (uint64_t)8 * (uint64_t)USEC_PER_SEC) / - ((uint64_t)results->client_time_in_us * 1024U)); + ((uint64_t)results->client_time_in_us * 1000U)); } else { client_rate_in_kbps = 0U; } @@ -474,7 +474,7 @@ static void shell_tcp_upload_print_stats(const struct shell *sh, (((uint64_t)results->nb_packets_sent * (uint64_t)results->packet_size * (uint64_t)8 * (uint64_t)USEC_PER_SEC) / - ((uint64_t)results->client_time_in_us * 1024U)); + ((uint64_t)results->client_time_in_us * 1000U)); } else { client_rate_in_kbps = 0U; } @@ -884,7 +884,7 @@ static int shell_cmd_upload(const struct shell *sh, size_t argc, if (argc > 5) { param.rate_kbps = - (parse_number(argv[start + 5], K, K_UNIT) + 1023) / 1024; + (parse_number(argv[start + 5], K, K_UNIT) + 999) / 1000; } else { param.rate_kbps = 10U; } @@ -1035,7 +1035,7 @@ static int shell_cmd_upload2(const struct shell *sh, size_t argc, if (argc > 4) { param.rate_kbps = - (parse_number(argv[start + 4], K, K_UNIT) + 1023) / 1024; + (parse_number(argv[start + 4], K, K_UNIT) + 999) / 1000; } else { param.rate_kbps = 10U; } @@ -1108,7 +1108,7 @@ static void tcp_session_cb(enum zperf_status status, rate_in_kbps = (uint32_t) (((uint64_t)result->total_len * 8ULL * (uint64_t)USEC_PER_SEC) / - ((uint64_t)result->time_in_us * 1024ULL)); + ((uint64_t)result->time_in_us * 1000ULL)); } else { rate_in_kbps = 0U; } diff --git a/subsys/net/lib/zperf/zperf_tcp_receiver.c b/subsys/net/lib/zperf/zperf_tcp_receiver.c index 344d34fe98c..3efd3ff630b 100644 --- a/subsys/net/lib/zperf/zperf_tcp_receiver.c +++ b/subsys/net/lib/zperf/zperf_tcp_receiver.c @@ -14,6 +14,7 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); #include #include +#include #include #include "zperf_internal.h" @@ -23,31 +24,25 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); #define NET_LOG_ENABLED 1 #include "net_private.h" -#if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) -#define TCP_RECEIVER_THREAD_PRIORITY K_PRIO_COOP(8) -#else -#define TCP_RECEIVER_THREAD_PRIORITY K_PRIO_PREEMPT(8) -#endif - -#define TCP_RECEIVER_STACK_SIZE 2048 - #define SOCK_ID_IPV4_LISTEN 0 #define SOCK_ID_IPV6_LISTEN 1 #define SOCK_ID_MAX (CONFIG_NET_ZPERF_MAX_SESSIONS + 2) #define TCP_RECEIVER_BUF_SIZE 1500 -#define POLL_TIMEOUT_MS 100 - -static K_THREAD_STACK_DEFINE(tcp_receiver_stack_area, TCP_RECEIVER_STACK_SIZE); -static struct k_thread tcp_receiver_thread_data; static zperf_callback tcp_session_cb; 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 struct zsock_pollfd fds[SOCK_ID_MAX]; +static struct sockaddr sock_addr[SOCK_ID_MAX]; + +static void tcp_svc_handler(struct k_work *work); + +NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(svc_tcp, NULL, tcp_svc_handler, + SOCK_ID_MAX); static void tcp_received(const struct sockaddr *addr, size_t datalen) { @@ -99,6 +94,155 @@ static void tcp_received(const struct sockaddr *addr, size_t datalen) } } +static void tcp_session_error_report(void) +{ + if (tcp_session_cb != NULL) { + tcp_session_cb(ZPERF_SESSION_ERROR, NULL, tcp_user_data); + } +} + +static void tcp_receiver_cleanup(void) +{ + int i; + + (void)net_socket_service_unregister(&svc_tcp); + + for (i = 0; i < ARRAY_SIZE(fds); i++) { + if (fds[i].fd >= 0) { + zsock_close(fds[i].fd); + fds[i].fd = -1; + memset(&sock_addr[i], 0, sizeof(struct sockaddr)); + } + } + + tcp_server_running = false; + tcp_session_cb = NULL; + + zperf_session_reset(SESSION_TCP); +} + +static int tcp_recv_data(struct net_socket_service_event *pev) +{ + static uint8_t buf[TCP_RECEIVER_BUF_SIZE]; + int i, ret = 0; + int family, sock, sock_error; + struct sockaddr addr_incoming_conn; + socklen_t optlen = sizeof(int); + socklen_t addrlen = sizeof(struct sockaddr); + + if (!tcp_server_running) { + return -ENOENT; + } + + if ((pev->event.revents & ZSOCK_POLLERR) || + (pev->event.revents & ZSOCK_POLLNVAL)) { + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_ERROR, &sock_error, &optlen); + NET_ERR("TCP receiver IPv%d socket error (%d)", + family == AF_INET ? 4 : 6, sock_error); + ret = -sock_error; + goto error; + } + + if (!(pev->event.revents & ZSOCK_POLLIN)) { + return 0; + } + + /* What is the index to first accepted socket */ + i = SOCK_ID_IPV6_LISTEN + 1; + + /* Check first if we need to accept a connection */ + if (fds[SOCK_ID_IPV4_LISTEN].fd == pev->event.fd || + fds[SOCK_ID_IPV6_LISTEN].fd == pev->event.fd) { + sock = zsock_accept(pev->event.fd, + &addr_incoming_conn, + &addrlen); + if (sock < 0) { + ret = -errno; + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_DOMAIN, &family, &optlen); + NET_ERR("TCP receiver IPv%d accept error (%d)", + family == AF_INET ? 4 : 6, ret); + goto error; + } + + for (; i < SOCK_ID_MAX; i++) { + if (fds[i].fd < 0) { + break; + } + } + + if (i == SOCK_ID_MAX) { + /* Too many connections. */ + NET_ERR("Dropping TCP connection, reached maximum limit."); + zsock_close(sock); + } else { + fds[i].fd = sock; + fds[i].events = ZSOCK_POLLIN; + memcpy(&sock_addr[i], &addr_incoming_conn, addrlen); + + (void)net_socket_service_register(&svc_tcp, fds, + ARRAY_SIZE(fds), + NULL); + } + + } else { + ret = zsock_recv(pev->event.fd, buf, sizeof(buf), 0); + if (ret < 0) { + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_DOMAIN, &family, &optlen); + NET_ERR("recv failed on IPv%d socket (%d)", + family == AF_INET ? 4 : 6, + errno); + tcp_session_error_report(); + /* This will close the zperf session */ + ret = 0; + } + + for (; i < SOCK_ID_MAX; i++) { + if (fds[i].fd == pev->event.fd) { + break; + } + } + + if (i == SOCK_ID_MAX) { + NET_ERR("Descriptor %d not found.", pev->event.fd); + } else { + tcp_received(&sock_addr[i], ret); + if (ret == 0) { + zsock_close(fds[i].fd); + fds[i].fd = -1; + memset(&sock_addr[i], 0, sizeof(struct sockaddr)); + + (void)net_socket_service_register(&svc_tcp, fds, + ARRAY_SIZE(fds), + NULL); + } + } + } + + return ret; + +error: + tcp_session_error_report(); + + return ret; +} + +static void tcp_svc_handler(struct k_work *work) +{ + struct net_socket_service_event *pev = + CONTAINER_OF(work, struct net_socket_service_event, work); + int ret; + + ret = tcp_recv_data(pev); + if (ret < 0) { + tcp_receiver_cleanup(); + } +} + static int tcp_bind_listen_connection(struct zsock_pollfd *pollfd, struct sockaddr *address) { @@ -114,14 +258,14 @@ static int tcp_bind_listen_connection(struct zsock_pollfd *pollfd, ret = zsock_bind(pollfd->fd, address, sizeof(*address)); if (ret < 0) { NET_ERR("Cannot bind IPv%d TCP port %d (%d)", - (address->sa_family == AF_INET ? 4 : 6), port, errno); + address->sa_family == AF_INET ? 4 : 6, port, errno); goto out; } ret = zsock_listen(pollfd->fd, 1); if (ret < 0) { NET_ERR("Cannot listen IPv%d TCP (%d)", - (address->sa_family == AF_INET ? 4 : 6), errno); + address->sa_family == AF_INET ? 4 : 6, errno); goto out; } @@ -131,18 +275,8 @@ static int tcp_bind_listen_connection(struct zsock_pollfd *pollfd, return ret; } -static void tcp_session_error_report(void) +static int zperf_tcp_receiver_init(void) { - if (tcp_session_cb != NULL) { - tcp_session_cb(ZPERF_SESSION_ERROR, NULL, tcp_user_data); - } -} - -static void tcp_server_session(void) -{ - static uint8_t buf[TCP_RECEIVER_BUF_SIZE]; - static struct zsock_pollfd fds[SOCK_ID_MAX]; - static struct sockaddr sock_addr[SOCK_ID_MAX]; int ret; for (int i = 0; i < ARRAY_SIZE(fds); i++) { @@ -156,6 +290,7 @@ static void tcp_server_session(void) fds[SOCK_ID_IPV4_LISTEN].fd = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fds[SOCK_ID_IPV4_LISTEN].fd < 0) { + ret = -errno; NET_ERR("Cannot create IPv4 network socket."); goto error; } @@ -201,6 +336,7 @@ static void tcp_server_session(void) fds[SOCK_ID_IPV6_LISTEN].fd = zsock_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (fds[SOCK_ID_IPV6_LISTEN].fd < 0) { + ret = -errno; NET_ERR("Cannot create IPv6 network socket."); goto error; } @@ -243,135 +379,21 @@ static void tcp_server_session(void) NET_INFO("Listening on port %d", tcp_server_port); - while (true) { - ret = zsock_poll(fds, ARRAY_SIZE(fds), POLL_TIMEOUT_MS); - if (ret < 0) { - NET_ERR("TCP receiver poll error (%d)", errno); - goto error; - } - - if (tcp_server_stop) { - goto cleanup; - } - - if (ret == 0) { - continue; - } - - for (int i = 0; i < ARRAY_SIZE(fds); i++) { - if ((fds[i].revents & ZSOCK_POLLERR) || - (fds[i].revents & ZSOCK_POLLNVAL)) { - NET_ERR("TCP receiver IPv%d socket error", - (sock_addr[i].sa_family == AF_INET - ? 4 : 6)); - goto error; - } - - if (!(fds[i].revents & ZSOCK_POLLIN)) { - continue; - } - - if ((i >= SOCK_ID_IPV4_LISTEN) && (i <= SOCK_ID_IPV6_LISTEN)) { - int j = SOCK_ID_IPV6_LISTEN + 1; - struct sockaddr addr_incoming_conn; - socklen_t addrlen = sizeof(struct sockaddr); - int sock = zsock_accept(fds[i].fd, - &addr_incoming_conn, - &addrlen); - - if (sock < 0) { - NET_ERR("TCP receiver IPv%d accept error", - (sock_addr[i].sa_family == AF_INET - ? 4 : 6)); - goto error; - } - - for (; j < SOCK_ID_MAX; j++) { - if (fds[j].fd < 0) { - break; - } - } - - if (j == SOCK_ID_MAX) { - /* Too many connections. */ - NET_ERR("Dropping TCP connection, reached maximum limit."); - zsock_close(sock); - } else { - fds[j].fd = sock; - fds[j].events = ZSOCK_POLLIN; - memcpy(&sock_addr[j], - &addr_incoming_conn, - addrlen); - } - } else if ((i > SOCK_ID_IPV6_LISTEN) && (i < SOCK_ID_MAX)) { - ret = zsock_recv(fds[i].fd, buf, sizeof(buf), 0); - if (ret < 0) { - NET_ERR("recv failed on IPv%d socket (%d)", - (sock_addr[i].sa_family == AF_INET - ? 4 : 6), - errno); - tcp_session_error_report(); - /* This will close the zperf session */ - ret = 0; - } - - tcp_received(&sock_addr[i], ret); - - if (ret == 0) { - zsock_close(fds[i].fd); - fds[i].fd = -1; - memset(&sock_addr[i], 0, - sizeof(struct sockaddr)); - } - } else { - goto error; - } - } + ret = net_socket_service_register(&svc_tcp, fds, + ARRAY_SIZE(fds), NULL); + if (ret < 0) { + LOG_ERR("Cannot register socket service handler (%d)", ret); } error: - tcp_session_error_report(); - -cleanup: - for (int i = 0; i < ARRAY_SIZE(fds); i++) { - if (fds[i].fd >= 0) { - zsock_close(fds[i].fd); - memset(&sock_addr[i], 0, sizeof(struct sockaddr)); - } - } -} - -void tcp_receiver_thread(void *ptr1, void *ptr2, void *ptr3) -{ - ARG_UNUSED(ptr1); - ARG_UNUSED(ptr2); - ARG_UNUSED(ptr3); - - while (true) { - k_sem_take(&tcp_server_run, K_FOREVER); - - tcp_server_session(); - - tcp_server_running = false; - } -} - -void zperf_tcp_receiver_init(void) -{ - k_thread_create(&tcp_receiver_thread_data, - tcp_receiver_stack_area, - K_THREAD_STACK_SIZEOF(tcp_receiver_stack_area), - tcp_receiver_thread, - NULL, NULL, NULL, - TCP_RECEIVER_THREAD_PRIORITY, - IS_ENABLED(CONFIG_USERSPACE) ? K_USER | - K_INHERIT_PERMS : 0, - K_NO_WAIT); + return ret; } int zperf_tcp_download(const struct zperf_download_params *param, zperf_callback callback, void *user_data) { + int ret; + if (param == NULL || callback == NULL) { return -EINVAL; } @@ -383,11 +405,15 @@ int zperf_tcp_download(const struct zperf_download_params *param, tcp_session_cb = callback; tcp_user_data = user_data; 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); + ret = zperf_tcp_receiver_init(); + if (ret < 0) { + tcp_receiver_cleanup(); + return ret; + } + + tcp_server_running = true; return 0; } @@ -398,8 +424,7 @@ int zperf_tcp_download_stop(void) return -EALREADY; } - tcp_server_stop = true; - tcp_session_cb = NULL; + tcp_receiver_cleanup(); return 0; } diff --git a/subsys/net/lib/zperf/zperf_udp_receiver.c b/subsys/net/lib/zperf/zperf_udp_receiver.c index 75a0b35b234..ae1ac063300 100644 --- a/subsys/net/lib/zperf/zperf_udp_receiver.c +++ b/subsys/net/lib/zperf/zperf_udp_receiver.c @@ -13,6 +13,7 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); #include #include +#include #include #include "zperf_internal.h" @@ -25,14 +26,6 @@ LOG_MODULE_DECLARE(net_zperf, CONFIG_NET_ZPERF_LOG_LEVEL); static struct sockaddr_in6 *in6_addr_my; static struct sockaddr_in *in4_addr_my; -#if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) -#define UDP_RECEIVER_THREAD_PRIORITY K_PRIO_COOP(8) -#else -#define UDP_RECEIVER_THREAD_PRIORITY K_PRIO_PREEMPT(8) -#endif - -#define UDP_RECEIVER_STACK_SIZE 2048 - #define SOCK_ID_IPV4 0 #define SOCK_ID_IPV6 1 #define SOCK_ID_MAX 2 @@ -40,16 +33,18 @@ static struct sockaddr_in *in4_addr_my; #define UDP_RECEIVER_BUF_SIZE 1500 #define POLL_TIMEOUT_MS 100 -static K_THREAD_STACK_DEFINE(udp_receiver_stack_area, UDP_RECEIVER_STACK_SIZE); -static struct k_thread udp_receiver_thread_data; - static zperf_callback udp_session_cb; 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); + +struct zsock_pollfd fds[SOCK_ID_MAX] = { 0 }; + +static void udp_svc_handler(struct k_work *work); + +NET_SOCKET_SERVICE_SYNC_DEFINE_STATIC(svc_udp, NULL, udp_svc_handler, + SOCK_ID_MAX); static inline void build_reply(struct zperf_udp_datagram *hdr, struct zperf_server_hdr *stat, @@ -230,10 +225,91 @@ static void udp_received(int sock, const struct sockaddr *addr, uint8_t *data, } } -static void udp_server_session(void) +static void udp_receiver_cleanup(void) +{ + int i; + + (void)net_socket_service_unregister(&svc_udp); + + for (i = 0; i < ARRAY_SIZE(fds); i++) { + if (fds[i].fd >= 0) { + zsock_close(fds[i].fd); + fds[i].fd = -1; + } + } + + udp_server_running = false; + udp_session_cb = NULL; + + zperf_session_reset(SESSION_UDP); +} + +static int udp_recv_data(struct net_socket_service_event *pev) { static uint8_t buf[UDP_RECEIVER_BUF_SIZE]; - struct zsock_pollfd fds[SOCK_ID_MAX] = { 0 }; + int ret = 0; + int family, sock_error; + struct sockaddr addr; + socklen_t optlen = sizeof(int); + socklen_t addrlen = sizeof(addr); + + if (!udp_server_running) { + return -ENOENT; + } + + if ((pev->event.revents & ZSOCK_POLLERR) || + (pev->event.revents & ZSOCK_POLLNVAL)) { + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_DOMAIN, &family, &optlen); + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_ERROR, &sock_error, &optlen); + NET_ERR("UDP receiver IPv%d socket error (%d)", + family == AF_INET ? 4 : 6, sock_error); + ret = -sock_error; + goto error; + } + + if (!(pev->event.revents & ZSOCK_POLLIN)) { + return 0; + } + + ret = zsock_recvfrom(pev->event.fd, buf, sizeof(buf), 0, + &addr, &addrlen); + if (ret < 0) { + ret = -errno; + (void)zsock_getsockopt(pev->event.fd, SOL_SOCKET, + SO_DOMAIN, &family, &optlen); + NET_ERR("recv failed on IPv%d socket (%d)", + family == AF_INET ? 4 : 6, -ret); + goto error; + } + + udp_received(pev->event.fd, &addr, buf, ret); + + return ret; + +error: + if (udp_session_cb != NULL) { + udp_session_cb(ZPERF_SESSION_ERROR, NULL, udp_user_data); + } + + return ret; +} + +static void udp_svc_handler(struct k_work *work) +{ + struct net_socket_service_event *pev = + CONTAINER_OF(work, struct net_socket_service_event, work); + int ret; + + ret = udp_recv_data(pev); + if (ret < 0) { + udp_receiver_cleanup(); + } +} + +static int zperf_udp_receiver_init(void) +{ int ret; for (int i = 0; i < ARRAY_SIZE(fds); i++) { @@ -248,6 +324,7 @@ static void udp_server_session(void) fds[SOCK_ID_IPV4].fd = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fds[SOCK_ID_IPV4].fd < 0) { + ret = -errno; NET_ERR("Cannot create IPv4 network socket."); goto error; } @@ -296,6 +373,7 @@ static void udp_server_session(void) fds[SOCK_ID_IPV6].fd = zsock_socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (fds[SOCK_ID_IPV6].fd < 0) { + ret = -errno; NET_ERR("Cannot create IPv4 network socket."); goto error; } @@ -341,92 +419,22 @@ static void udp_server_session(void) NET_INFO("Listening on port %d", udp_server_port); - while (true) { - ret = zsock_poll(fds, ARRAY_SIZE(fds), POLL_TIMEOUT_MS); - if (ret < 0) { - NET_ERR("UDP receiver poll error (%d)", errno); - goto error; - } - - if (udp_server_stop) { - goto cleanup; - } - - if (ret == 0) { - continue; - } - - for (int i = 0; i < ARRAY_SIZE(fds); i++) { - struct sockaddr addr; - socklen_t addrlen = sizeof(addr); - - if ((fds[i].revents & ZSOCK_POLLERR) || - (fds[i].revents & ZSOCK_POLLNVAL)) { - NET_ERR("UDP receiver IPv%d socket error", - (i == SOCK_ID_IPV4) ? 4 : 6); - goto error; - } - - if (!(fds[i].revents & ZSOCK_POLLIN)) { - continue; - } - - ret = zsock_recvfrom(fds[i].fd, buf, sizeof(buf), 0, - &addr, &addrlen); - if (ret < 0) { - NET_ERR("recv failed on IPv%d socket (%d)", - (i == SOCK_ID_IPV4) ? 4 : 6, errno); - goto error; - } - - udp_received(fds[i].fd, &addr, buf, ret); - } + ret = net_socket_service_register(&svc_udp, fds, + ARRAY_SIZE(fds), NULL); + if (ret < 0) { + LOG_ERR("Cannot register socket service handler (%d)", ret); } error: - if (udp_session_cb != NULL) { - udp_session_cb(ZPERF_SESSION_ERROR, NULL, udp_user_data); - } - -cleanup: - for (int i = 0; i < ARRAY_SIZE(fds); i++) { - if (fds[i].fd >= 0) { - zsock_close(fds[i].fd); - } - } -} -static void udp_receiver_thread(void *ptr1, void *ptr2, void *ptr3) -{ - ARG_UNUSED(ptr1); - ARG_UNUSED(ptr2); - ARG_UNUSED(ptr3); - - while (true) { - k_sem_take(&udp_server_run, K_FOREVER); - - udp_server_session(); - - udp_server_running = false; - } -} - -void zperf_udp_receiver_init(void) -{ - k_thread_create(&udp_receiver_thread_data, - udp_receiver_stack_area, - K_THREAD_STACK_SIZEOF(udp_receiver_stack_area), - udp_receiver_thread, - NULL, NULL, NULL, - UDP_RECEIVER_THREAD_PRIORITY, - IS_ENABLED(CONFIG_USERSPACE) ? K_USER | - K_INHERIT_PERMS : 0, - K_NO_WAIT); + return ret; } int zperf_udp_download(const struct zperf_download_params *param, zperf_callback callback, void *user_data) { + int ret; + if (param == NULL || callback == NULL) { return -EINVAL; } @@ -438,11 +446,15 @@ int zperf_udp_download(const struct zperf_download_params *param, udp_session_cb = callback; udp_user_data = user_data; 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); + ret = zperf_udp_receiver_init(); + if (ret < 0) { + udp_receiver_cleanup(); + return ret; + } + + udp_server_running = true; return 0; } @@ -453,8 +465,7 @@ int zperf_udp_download_stop(void) return -EALREADY; } - udp_server_stop = true; - udp_session_cb = NULL; + udp_receiver_cleanup(); return 0; } diff --git a/subsys/settings/include/settings/settings_nvs.h b/subsys/settings/include/settings/settings_nvs.h index ce34e192c24..6db576da631 100644 --- a/subsys/settings/include/settings/settings_nvs.h +++ b/subsys/settings/include/settings/settings_nvs.h @@ -45,6 +45,8 @@ struct settings_nvs { } cache[CONFIG_SETTINGS_NVS_NAME_CACHE_SIZE]; uint16_t cache_next; + uint16_t cache_total; + bool loaded; #endif }; diff --git a/subsys/settings/src/settings_nvs.c b/subsys/settings/src/settings_nvs.c index 8e5bfbf3767..6764c7587a3 100644 --- a/subsys/settings/src/settings_nvs.c +++ b/subsys/settings/src/settings_nvs.c @@ -74,6 +74,8 @@ int settings_nvs_dst(struct settings_nvs *cf) } #if CONFIG_SETTINGS_NVS_NAME_CACHE +#define SETTINGS_NVS_CACHE_OVFL(cf) ((cf)->cache_total > ARRAY_SIZE((cf)->cache)) + static void settings_nvs_cache_add(struct settings_nvs *cf, const char *name, uint16_t name_id) { @@ -129,12 +131,22 @@ static int settings_nvs_load(struct settings_store *cs, ssize_t rc1, rc2; uint16_t name_id = NVS_NAMECNT_ID; +#if CONFIG_SETTINGS_NVS_NAME_CACHE + uint16_t cached = 0; + + cf->loaded = false; +#endif + name_id = cf->last_name_id + 1; while (1) { name_id--; if (name_id == NVS_NAMECNT_ID) { +#if CONFIG_SETTINGS_NVS_NAME_CACHE + cf->loaded = true; + cf->cache_total = cached; +#endif break; } @@ -147,6 +159,17 @@ static int settings_nvs_load(struct settings_store *cs, &buf, sizeof(buf)); if ((rc1 <= 0) && (rc2 <= 0)) { + /* Settings largest ID in use is invalid due to + * reset, power failure or partition overflow. + * Decrement it and check the next ID in subsequent + * iteration. + */ + if (name_id == cf->last_name_id) { + cf->last_name_id--; + nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID, + &cf->last_name_id, sizeof(uint16_t)); + } + continue; } @@ -156,13 +179,15 @@ static int settings_nvs_load(struct settings_store *cs, * or deleted. Clean dirty entries to make space for * future settings item. */ + nvs_delete(&cf->cf_nvs, name_id); + nvs_delete(&cf->cf_nvs, name_id + NVS_NAME_ID_OFFSET); + if (name_id == cf->last_name_id) { cf->last_name_id--; nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID, &cf->last_name_id, sizeof(uint16_t)); } - nvs_delete(&cf->cf_nvs, name_id); - nvs_delete(&cf->cf_nvs, name_id + NVS_NAME_ID_OFFSET); + continue; } @@ -173,6 +198,7 @@ static int settings_nvs_load(struct settings_store *cs, #if CONFIG_SETTINGS_NVS_NAME_CACHE settings_nvs_cache_add(cf, name, name_id); + cached++; #endif ret = settings_call_set_handler( @@ -203,10 +229,13 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, delete = ((value == NULL) || (val_len == 0)); #if CONFIG_SETTINGS_NVS_NAME_CACHE + bool name_in_cache = false; + name_id = settings_nvs_cache_match(cf, name, rdname, sizeof(rdname)); if (name_id != NVS_NAMECNT_ID) { write_name_id = name_id; write_name = false; + name_in_cache = true; goto found; } #endif @@ -215,6 +244,13 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, write_name_id = cf->last_name_id + 1; write_name = true; +#if CONFIG_SETTINGS_NVS_NAME_CACHE + /* We can skip reading NVS if we know that the cache wasn't overflowed. */ + if (cf->loaded && !SETTINGS_NVS_CACHE_OVFL(cf)) { + goto found; + } +#endif + while (1) { name_id--; if (name_id == NVS_NAMECNT_ID) { @@ -238,9 +274,6 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, } if (!delete) { -#if CONFIG_SETTINGS_NVS_NAME_CACHE - settings_nvs_cache_add(cf, name, name_id); -#endif write_name_id = name_id; write_name = false; } @@ -254,6 +287,16 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, return 0; } + rc = nvs_delete(&cf->cf_nvs, name_id); + if (rc >= 0) { + rc = nvs_delete(&cf->cf_nvs, name_id + + NVS_NAME_ID_OFFSET); + } + + if (rc < 0) { + return rc; + } + if (name_id == cf->last_name_id) { cf->last_name_id--; rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID, @@ -266,17 +309,6 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, } } - rc = nvs_delete(&cf->cf_nvs, name_id); - - if (rc >= 0) { - rc = nvs_delete(&cf->cf_nvs, name_id + - NVS_NAME_ID_OFFSET); - } - - if (rc < 0) { - return rc; - } - return 0; } @@ -285,6 +317,16 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, return -ENOMEM; } + /* update the last_name_id and write to flash if required*/ + if (write_name_id > cf->last_name_id) { + cf->last_name_id = write_name_id; + rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID, &cf->last_name_id, + sizeof(uint16_t)); + if (rc < 0) { + return rc; + } + } + /* write the value */ rc = nvs_write(&cf->cf_nvs, write_name_id + NVS_NAME_ID_OFFSET, value, val_len); @@ -300,16 +342,14 @@ static int settings_nvs_save(struct settings_store *cs, const char *name, } } - /* update the last_name_id and write to flash if required*/ - if (write_name_id > cf->last_name_id) { - cf->last_name_id = write_name_id; - rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID, &cf->last_name_id, - sizeof(uint16_t)); - } - - if (rc < 0) { - return rc; +#if CONFIG_SETTINGS_NVS_NAME_CACHE + if (!name_in_cache) { + settings_nvs_cache_add(cf, name, write_name_id); + if (cf->loaded && !SETTINGS_NVS_CACHE_OVFL(cf)) { + cf->cache_total++; + } } +#endif return 0; } diff --git a/subsys/shell/Kconfig b/subsys/shell/Kconfig index 43035e520e1..cb9af338b20 100644 --- a/subsys/shell/Kconfig +++ b/subsys/shell/Kconfig @@ -40,9 +40,8 @@ endif config SHELL_STACK_SIZE int "Shell thread stack size" - default 3168 if OPENTHREAD_SHELL && OPENTHREAD_JOINER + default 3168 if OPENTHREAD_SHELL default 3072 if 64BIT - default 2616 if OPENTHREAD_SHELL default 2048 if MULTITHREADING default 0 if !MULTITHREADING help 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); diff --git a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c index 7d793066109..61679107103 100644 --- a/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c +++ b/tests/arch/arm/arm_irq_vector_table/src/arm_irq_vector_table.c @@ -16,66 +16,25 @@ */ #define _ISR_OFFSET 0 -#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) -/* The customized solution for nRF51X-based and nRF52X-based - * platforms requires that the POWER_CLOCK_IRQn line equals 0. - */ -BUILD_ASSERT(POWER_CLOCK_IRQn == 0, - "POWER_CLOCK_IRQn != 0. Consider rework manual vector table."); - -/* The customized solution for nRF51X-based and nRF52X-based - * platforms requires that the RTC1 IRQ line equals 17. - */ -BUILD_ASSERT(RTC1_IRQn == 17, - "RTC1_IRQn != 17. Consider rework manual vector table."); - +#if defined(CONFIG_SOC_FAMILY_NRF) #undef _ISR_OFFSET -#if !defined(CONFIG_BOARD_QEMU_CORTEX_M0) -/* Interrupt line 0 is used by POWER_CLOCK */ -#define _ISR_OFFSET 1 +#if defined(CONFIG_BOARD_QEMU_CORTEX_M0) +/* For the nRF51-based QEMU Cortex-M0 platform, the first set of consecutive + * implemented interrupts that can be used by this test starts right after + * the TIMER0 IRQ line, which is used by the system timer. + */ +#define _ISR_OFFSET (TIMER0_IRQn + 1) +#elif defined(CONFIG_SOC_SERIES_NRF54LX) +/* For nRF54L Series, use SWI00-02 interrupt lines. */ +#define _ISR_OFFSET SWI00_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +/* For nRF54H Series, use BELLBOARD_0-2 interrupt lines. */ +#define _ISR_OFFSET BELLBOARD_0_IRQn #else -/* The customized solution for nRF51-based QEMU Cortex-M0 platform - * requires that the TIMER0 IRQ line equals 8. - */ -BUILD_ASSERT(TIMER0_IRQn == 8, - "TIMER0_IRQn != 8. Consider rework manual vector table."); -/* Interrupt lines 9-11 is the first set of consecutive interrupts implemented - * in QEMU Cortex M0. - */ -#define _ISR_OFFSET 9 - +/* For other nRF targets, use TIMER0-2 interrupt lines. */ +#define _ISR_OFFSET TIMER0_IRQn #endif - -#elif defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF91X) -/* The customized solution for nRF91X-based and nRF53X-based - * platforms requires that the POWER_CLOCK_IRQn line equals 5. - */ -BUILD_ASSERT(CLOCK_POWER_IRQn == 5, - "POWER_CLOCK_IRQn != 5." - "Consider rework manual vector table."); - -#if !defined(CONFIG_SOC_NRF5340_CPUNET) -/* The customized solution for nRF91X-based platforms - * requires that the RTC1 IRQ line equals 21. - */ -BUILD_ASSERT(RTC1_IRQn == 21, - "RTC1_IRQn != 21. Consider rework manual vector table."); - -#else /* CONFIG_SOC_NRF5340_CPUNET */ -/* The customized solution for nRF5340_CPUNET - * requires that the RTC1 IRQ line equals 22. - */ -BUILD_ASSERT(RTC1_IRQn == 22, - "RTC1_IRQn != 22. Consider rework manual vector table."); -#endif -#undef _ISR_OFFSET -/* Interrupt lines 8-10 is the first set of consecutive interrupts implemented - * in nRF9160 SOC. - */ -#define _ISR_OFFSET 8 - -#endif /* CONFIG_SOC_SERIES_NRF52X */ - +#endif /* CONFIG_SOC_FAMILY_NRF */ struct k_sem sem[3]; @@ -182,40 +141,38 @@ typedef void (*vth)(void); /* Vector Table Handler */ * * Note: qemu_cortex_m0 uses TIMER0 to implement system timer. */ -void rtc_nrf_isr(void); void nrfx_power_clock_irq_handler(void); #if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) +#define POWER_CLOCK_IRQ_NUM POWER_CLOCK_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54HX) +#define POWER_CLOCK_IRQ_NUM -1 /* not needed */ +#else +#define POWER_CLOCK_IRQ_NUM CLOCK_POWER_IRQn +#endif + #if defined(CONFIG_BOARD_QEMU_CORTEX_M0) void timer0_nrf_isr(void); -vth __irq_vector_table _irq_vector_table[] = { - nrfx_power_clock_irq_handler, 0, 0, 0, 0, 0, 0, 0, - timer0_nrf_isr, isr0, isr1, isr2 -}; +#define TIMER_IRQ_HANDLER timer0_nrf_isr +#define TIMER_IRQ_NUM TIMER0_IRQn +#elif defined(CONFIG_SOC_SERIES_NRF54LX) || defined(CONFIG_SOC_SERIES_NRF54HX) +void nrfx_grtc_irq_handler(void); +#define TIMER_IRQ_HANDLER nrfx_grtc_irq_handler +#define TIMER_IRQ_NUM GRTC_0_IRQn #else -vth __irq_vector_table _irq_vector_table[] = { - nrfx_power_clock_irq_handler, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; -#endif /* CONFIG_BOARD_QEMU_CORTEX_M0 */ -#elif defined(CONFIG_SOC_SERIES_NRF53X) || defined(CONFIG_SOC_SERIES_NRF91X) -#ifndef CONFIG_SOC_NRF5340_CPUNET -vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrfx_power_clock_irq_handler, 0, 0, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; -#else -vth __irq_vector_table _irq_vector_table[] = { - 0, 0, 0, 0, 0, nrfx_power_clock_irq_handler, 0, 0, - isr0, isr1, isr2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - rtc_nrf_isr -}; +void rtc_nrf_isr(void); +#define TIMER_IRQ_HANDLER rtc_nrf_isr +#define TIMER_IRQ_NUM RTC1_IRQn #endif + +#define IRQ_VECTOR_TABLE_SIZE (MAX(POWER_CLOCK_IRQ_NUM, MAX(TIMER_IRQ_NUM, _ISR_OFFSET + 2)) + 1) + +vth __irq_vector_table _irq_vector_table[IRQ_VECTOR_TABLE_SIZE] = { +#if (POWER_CLOCK_IRQ_NUM != -1) + [POWER_CLOCK_IRQ_NUM] = nrfx_power_clock_irq_handler, #endif + [TIMER_IRQ_NUM] = TIMER_IRQ_HANDLER, + [_ISR_OFFSET] = isr0, isr1, isr2, +}; #elif defined(CONFIG_SOC_SERIES_CC13X2_CC26X2) || defined(CONFIG_SOC_SERIES_CC13X2X7_CC26X2X7) /* TI CC13x2/CC26x2 based platforms also employ a Hardware RTC peripheral * to implement the Kernel system timer, instead of the ARM Cortex-M diff --git a/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt b/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt index 93e91deafcb..10ee1786e16 100644 --- a/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt +++ b/tests/arch/arm/arm_thread_swap_tz/CMakeLists.txt @@ -14,6 +14,6 @@ target_sources(app PRIVATE ${app_sources}) if (CONFIG_BUILD_WITH_TFM) target_include_directories(app PRIVATE - $/install/interface/include + $/api_ns/interface/include ) endif() diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 386ef40e7f7..3b909e4582f 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -57,6 +57,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_get_freq) zassert_equal(ret, 0x03, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_set_val_new) +{ + struct bt_bap_lc3_preset preset = BT_BAP_LC3_UNICAST_PRESET_16_2_1( + BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + const uint8_t frame_blocks = 0x02; + int ret; + + /* Frame blocks are not part of the preset, so we can use that to test adding a new type to + * the config + */ + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&preset.codec_cfg, false); + zassert_equal(ret, -ENODATA, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_set_frame_blocks_per_sdu(&preset.codec_cfg, frame_blocks); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_get_frame_blocks_per_sdu(&preset.codec_cfg, false); + zassert_equal(ret, frame_blocks, "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( @@ -371,7 +391,7 @@ 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) +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list_shorter) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; const uint8_t new_expected_data[] = {0x25, 0x30}; @@ -394,6 +414,95 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list) zassert_mem_equal(new_expected_data, ccid_list, ARRAY_SIZE(new_expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list_longer) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30, 0x35, 0x40}; + 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)); +} + +/* Providing multiple BT_AUDIO_CODEC_DATA to BT_AUDIO_CODEC_CFG without packing it in a macro + * cause compile issue, so define a macro to denote 2 types of data for the ccid_list_first tests + */ +#define DOUBLE_CFG_DATA \ + { \ + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15), \ + BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, \ + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE) \ + } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list_first_shorter) +{ + 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, {}, DOUBLE_CFG_DATA); + 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_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + 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)); + + 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_cfg_meta_set_ccid_list_first_longer) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30, 0x35, 0x40}; + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, DOUBLE_CFG_DATA); + 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_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + 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)); + + 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_cfg_meta_get_parental_rating) { const struct bt_audio_codec_cfg codec_cfg = diff --git a/tests/bluetooth/mesh/blob_io_flash/prj.conf b/tests/bluetooth/mesh/blob_io_flash/prj.conf index 2a0e98421fa..1e7864aa05d 100644 --- a/tests/bluetooth/mesh/blob_io_flash/prj.conf +++ b/tests/bluetooth/mesh/blob_io_flash/prj.conf @@ -15,7 +15,6 @@ CONFIG_BT_NO_DRIVER=y CONFIG_BT_OBSERVER=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_MESH=y -CONFIG_BT_MESH_V1d1=y CONFIG_BT_MESH_BLOB_SRV=y CONFIG_BT_MESH_BLOB_CLI=y CONFIG_BT_MESH_BLOB_IO_FLASH=y diff --git a/tests/bluetooth/mesh_shell/proxy_solicitation.conf b/tests/bluetooth/mesh_shell/proxy_solicitation.conf index f900d743516..51e50c07a01 100644 --- a/tests/bluetooth/mesh_shell/proxy_solicitation.conf +++ b/tests/bluetooth/mesh_shell/proxy_solicitation.conf @@ -1,4 +1,3 @@ -CONFIG_BT_MESH_V1d1=y CONFIG_BT_CENTRAL=y CONFIG_BT_MESH_PROXY_CLIENT=y CONFIG_BT_MESH_PROXY_SOLICITATION=y diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index 4b46c8d6781..ef4eed67eb3 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -13,6 +13,13 @@ tests: tags: bluetooth harness: keyboard min_flash: 145 + bluetooth.shell.power_control_request: + extra_configs: + - CONFIG_BT_TRANSMIT_POWER_CONTROL=y + - CONFIG_BT_CTLR=n + platform_allow: + - native_posix + build_only: true bluetooth.shell.cdc_acm: extra_args: - OVERLAY_CONFIG=cdc_acm.conf diff --git a/tests/bluetooth/tester/overlay-mesh-v1d1.conf b/tests/bluetooth/tester/overlay-mesh-v1d1.conf deleted file mode 100644 index 52045ce34df..00000000000 --- a/tests/bluetooth/tester/overlay-mesh-v1d1.conf +++ /dev/null @@ -1,30 +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_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/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 840af06c1c0..9fded71f792 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -1,3 +1,5 @@ +CONFIG_ENTROPY_GENERATOR=y + CONFIG_BT_MESH=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_PB_ADV=y @@ -23,3 +25,30 @@ 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_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_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/testcase.yaml b/tests/bluetooth/tester/testcase.yaml index 8c36291b30f..37c7ab3193d 100644 --- a/tests/bluetooth/tester/testcase.yaml +++ b/tests/bluetooth/tester/testcase.yaml @@ -28,13 +28,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 - - native_sim - - nrf52840dk_nrf52840 - extra_args: OVERLAY_CONFIG="overlay-mesh.conf;overlay-mesh-v1d1.conf" - tags: bluetooth - harness: bluetooth 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 diff --git a/tests/bsim/bluetooth/audio/src/bap_scan_delegator_test.c b/tests/bsim/bluetooth/audio/src/bap_scan_delegator_test.c index 8827a06bc93..81d3ed7ec2b 100644 --- a/tests/bsim/bluetooth/audio/src/bap_scan_delegator_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_scan_delegator_test.c @@ -616,6 +616,13 @@ static void remove_all_sources(void) printk("[%zu]: Source removed with id %u\n", i, state->src_id); + + printk("Terminating PA sync\n"); + err = pa_sync_term(state); + if (err) { + FAIL("[%zu]: PA sync term failed (err %d)\n", err); + return; + } } } } 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/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh b/tests/bsim/bluetooth/audio_samples/unicast_audio_client/tests_scripts/unicast_client.sh index cc92cda1328..6387b68af7f 100755 --- 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 @@ -24,6 +24,6 @@ Execute ./bs_${BOARD}_tests_bsim_bluetooth_audio_samples_unicast_audio_client_pr -testid=unicast_client Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=20e6 $@ + -D=2 -sim_length=20e6 $@ -argschannel -at=40 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 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/host/att/mtu_update/test_scripts/run_test.sh b/tests/bsim/bluetooth/host/att/mtu_update/test_scripts/run_test.sh index 087aa9385d4..255f6f4f9fa 100755 --- a/tests/bsim/bluetooth/host/att/mtu_update/test_scripts/run_test.sh +++ b/tests/bsim/bluetooth/host/att/mtu_update/test_scripts/run_test.sh @@ -21,6 +21,6 @@ Execute "$peripheral_exe" \ -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -RealEncryption=1 Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=60e6 $@ + -D=2 -sim_length=60e6 $@ -argschannel -at=40 wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/compile.sh b/tests/bsim/bluetooth/host/compile.sh index ff42fd27adf..098c983d75f 100755 --- a/tests/bsim/bluetooth/host/compile.sh +++ b/tests/bsim/bluetooth/host/compile.sh @@ -41,6 +41,7 @@ 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/authorization compile app=tests/bsim/bluetooth/host/gatt/caching compile app=tests/bsim/bluetooth/host/gatt/general compile app=tests/bsim/bluetooth/host/gatt/notify compile diff --git a/tests/bsim/bluetooth/host/gatt/authorization/CMakeLists.txt b/tests/bsim/bluetooth/host/gatt/authorization/CMakeLists.txt new file mode 100644 index 00000000000..acb0dd45947 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/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(bsim_test_gatt_authorization) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources} ) + +zephyr_include_directories( + ${BSIM_COMPONENTS_PATH}/libUtilv1/src/ + ${BSIM_COMPONENTS_PATH}/libPhyComv1/src/ + ) diff --git a/tests/bsim/bluetooth/host/gatt/authorization/prj.conf b/tests/bsim/bluetooth/host/gatt/authorization/prj.conf new file mode 100644 index 00000000000..9cba554afef --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/prj.conf @@ -0,0 +1,7 @@ +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME="GATT tester" +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_BT_GATT_AUTHORIZATION_CUSTOM=y +CONFIG_BT_ATT_PREPARE_COUNT=3 diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/common.c b/tests/bsim/bluetooth/host/gatt/authorization/src/common.c new file mode 100644 index 00000000000..adff2dd05ef --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/common.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +void test_tick(bs_time_t HW_device_time) +{ + if (bst_result != Passed) { + FAIL("test failed (not passed after %i seconds)\n", WAIT_TIME); + } +} + +void test_init(void) +{ + bst_ticker_set_next_tick_absolute(WAIT_TIME); + bst_result = In_progress; +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/common.h b/tests/bsim/bluetooth/host/gatt/authorization/src/common.h new file mode 100644 index 00000000000..339919dfe88 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/common.h @@ -0,0 +1,73 @@ +/** + * Common functions and helpers for BSIM GATT tests + * + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "bs_types.h" +#include "bs_tracing.h" +#include "time_machine.h" +#include "bstests.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +extern enum bst_result_t bst_result; + +#define WAIT_TIME (30 * 1e6) /*seconds*/ + +#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 WAIT_FOR_FLAG(flag) \ + while (!(bool)atomic_get(&flag)) { \ + (void)k_sleep(K_MSEC(1)); \ + } + +#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 CHRC_SIZE 10 + +#define TEST_SERVICE_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00) + +#define TEST_UNHANDLED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFD, 0x00) + +#define TEST_UNAUTHORIZED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFE, 0x00) + +#define TEST_AUTHORIZED_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0x00) + +#define TEST_CP_CHRC_UUID \ + BT_UUID_DECLARE_128(0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x02, 0x03, \ + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xF0, 0x00) + +void test_tick(bs_time_t HW_device_time); +void test_init(void); diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c new file mode 100644 index 00000000000..9c60c5b57b2 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_client_test.c @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include "common.h" + +CREATE_FLAG(flag_is_connected); +CREATE_FLAG(flag_discover_complete); +CREATE_FLAG(flag_write_complete); +CREATE_FLAG(flag_read_complete); + +static struct bt_conn *g_conn; +static uint16_t unhandled_chrc_handle; +static uint16_t unauthorized_chrc_handle; +static uint16_t authorized_chrc_handle; +static uint16_t cp_chrc_handle; +static const struct bt_uuid *test_svc_uuid = TEST_SERVICE_UUID; + +#define ARRAY_ITEM(i, _) i +static uint8_t chrc_data[] = { LISTIFY(CHRC_SIZE, ARRAY_ITEM, (,)) }; /* 1, 2, 3 ... */ + +static void connected(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err != 0) { + FAIL("Failed to connect to %s (%u)\n", addr, err); + return; + } + + printk("Connected to %s\n", addr); + + __ASSERT_NO_MSG(g_conn == conn); + + SET_FLAG(flag_is_connected); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != g_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(g_conn); + + g_conn = NULL; + UNSET_FLAG(flag_is_connected); +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +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; + + if (g_conn != NULL) { + return; + } + + /* We're only interested in connectable events */ + if (type != BT_HCI_ADV_IND && type != BT_HCI_ADV_DIRECT_IND) { + return; + } + + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Device found: %s (RSSI %d)\n", addr_str, rssi); + + printk("Stopping scan\n"); + err = bt_le_scan_stop(); + if (err != 0) { + FAIL("Could not stop scan: %d"); + return; + } + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &g_conn); + if (err != 0) { + FAIL("Could not connect to peer: %d", err); + } +} + +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) { + if (unhandled_chrc_handle == 0 || + unauthorized_chrc_handle == 0 || + authorized_chrc_handle == 0) { + FAIL("Did not discover required characterstics"); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_discover_complete); + + return BT_GATT_ITER_STOP; + } + + printk("[ATTRIBUTE] handle %u\n", attr->handle); + + if (params->type == BT_GATT_DISCOVER_PRIMARY && + bt_uuid_cmp(params->uuid, TEST_SERVICE_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) { + struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + + if (bt_uuid_cmp(chrc->uuid, TEST_UNHANDLED_CHRC_UUID) == 0) { + printk("Found unhandled chrc\n"); + unhandled_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + printk("Found unauthorized\n"); + unauthorized_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + printk("Found authorized chrc\n"); + authorized_chrc_handle = chrc->value_handle; + } else if (bt_uuid_cmp(chrc->uuid, TEST_CP_CHRC_UUID) == 0) { + printk("Found CP chrc\n"); + cp_chrc_handle = chrc->value_handle; + } + } + + return BT_GATT_ITER_CONTINUE; +} + +static void gatt_discover(void) +{ + static struct bt_gatt_discover_params discover_params; + int err; + + printk("Discovering services and characteristics\n"); + + discover_params.uuid = test_svc_uuid; + 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_PRIMARY; + + err = bt_gatt_discover(g_conn, &discover_params); + if (err != 0) { + FAIL("Discover failed(err %d)\n", err); + } + + WAIT_FOR_FLAG(flag_discover_complete); + printk("Discover complete\n"); +} + +static void gatt_write_cb(struct bt_conn *conn, uint8_t err, + struct bt_gatt_write_params *params) +{ + if ((err != BT_ATT_ERR_SUCCESS) && (params->handle != unauthorized_chrc_handle)) { + FAIL("Write failed on authorized characteristics: 0x%02X\n", err); + } + + if ((err != BT_ATT_ERR_AUTHORIZATION) && (params->handle == unauthorized_chrc_handle)) { + FAIL("Write failed on unauthorized characteristics: 0x%02X\n", err); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_write_complete); +} + +static void gatt_write(uint16_t handle) +{ + static struct bt_gatt_write_params write_params; + int err; + + printk("Writing to chrc\n"); + + write_params.data = chrc_data; + write_params.length = sizeof(chrc_data); + write_params.func = gatt_write_cb; + write_params.handle = handle; + + UNSET_FLAG(flag_write_complete); + + err = bt_gatt_write(g_conn, &write_params); + if (err != 0) { + FAIL("bt_gatt_write failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_write_complete); + printk("success\n"); +} + +static void gatt_cp_write(void) +{ + static struct bt_gatt_write_params write_params; + int err; + uint8_t cp_write_data[] = {0x00}; + + printk("Writing to CP chrc\n"); + + write_params.data = cp_write_data; + write_params.length = sizeof(cp_write_data); + write_params.func = gatt_write_cb; + write_params.handle = cp_chrc_handle; + + UNSET_FLAG(flag_write_complete); + + err = bt_gatt_write(g_conn, &write_params); + if (err != 0) { + FAIL("bt_gatt_write failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_write_complete); + printk("success\n"); +} + +static uint8_t gatt_read_cb(struct bt_conn *conn, uint8_t err, + struct bt_gatt_read_params *params, + const void *data, uint16_t length) +{ + if ((err != BT_ATT_ERR_SUCCESS) && + (params->single.handle != unauthorized_chrc_handle)) { + FAIL("Read failed on authorized characteristics: 0x%02X\n", err); + + if ((length != CHRC_SIZE) || (memcmp(data, chrc_data, length) != 0)) { + FAIL("chrc data different than expected", err); + } + } + + if ((err != BT_ATT_ERR_AUTHORIZATION) && + (params->single.handle == unauthorized_chrc_handle)) { + FAIL("Read failed on unauthorized characteristics: 0x%02X\n", err); + } + + (void)memset(params, 0, sizeof(*params)); + + SET_FLAG(flag_read_complete); + + return 0; +} + +static void gatt_read(uint16_t handle) +{ + static struct bt_gatt_read_params read_params; + int err; + + printk("Reading chrc\n"); + + read_params.func = gatt_read_cb; + read_params.handle_count = 1; + read_params.single.handle = handle; + read_params.single.offset = 0; + + UNSET_FLAG(flag_read_complete); + + err = bt_gatt_read(g_conn, &read_params); + if (err != 0) { + FAIL("bt_gatt_read failed: %d\n", err); + } + + WAIT_FOR_FLAG(flag_read_complete); + printk("success\n"); +} + +static void gatt_interact(uint16_t handle) +{ + gatt_write(handle); + gatt_read(handle); + gatt_cp_write(); +} + +static void test_main(void) +{ + int err; + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth discover failed (err %d)\n", err); + } + + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err != 0) { + FAIL("Scanning failed to start (err %d)\n", err); + } + + printk("Scanning successfully started\n"); + + WAIT_FOR_FLAG(flag_is_connected); + + gatt_discover(); + + printk("Interacting with the unhandled characteristic\n"); + gatt_interact(unhandled_chrc_handle); + + printk("Interacting with the unauthorized characteristic\n"); + gatt_interact(unauthorized_chrc_handle); + + printk("Interacting with the authorized characteristic\n"); + gatt_interact(authorized_chrc_handle); + + PASS("GATT client Passed\n"); +} + +static const struct bst_test_instance test_vcs[] = { + { + .test_id = "gatt_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_gatt_client_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_vcs); +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c new file mode 100644 index 00000000000..d5dd5e0e0a7 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/gatt_server_test.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "common.h" + +extern enum bst_result_t bst_result; + +CREATE_FLAG(flag_is_chrc_ctx_validated); + +static struct bt_conn *g_conn; + +static void connected(struct bt_conn *conn, uint8_t err) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err != 0) { + FAIL("Failed to connect to %s (%u)\n", addr, err); + return; + } + + printk("Connected to %s\n", addr); + + g_conn = bt_conn_ref(conn); +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != g_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(g_conn); + + g_conn = NULL; +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +struct test_chrc_ctx { + uint16_t auth_read_cnt; + uint16_t read_cnt; + uint16_t auth_write_cnt; + uint16_t write_cnt; + uint8_t data[CHRC_SIZE]; +}; + +static ssize_t read_test_chrc(struct test_chrc_ctx *chrc_ctx, + struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + chrc_ctx->read_cnt++; + + return bt_gatt_attr_read(conn, attr, buf, len, offset, + (void *)chrc_ctx->data, + sizeof(chrc_ctx->data)); +} + +static ssize_t write_test_chrc(struct test_chrc_ctx *chrc_ctx, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + chrc_ctx->write_cnt++; + + if (len != sizeof(chrc_ctx->data)) { + printk("Invalid chrc length\n"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + } + + if (offset != 0) { + printk("Invalid chrc offset and length\n"); + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + if (flags != 0) { + FAIL("Invalid flags %u\n", flags); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + (void)memcpy(chrc_ctx->data, buf, len); + + return len; +} + +static struct test_chrc_ctx unhandled_chrc_ctx; + +static ssize_t read_test_unhandled_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&unhandled_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_unhandled_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("unhandled chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&unhandled_chrc_ctx, buf, len, offset, flags); +} + +static struct test_chrc_ctx unauthorized_chrc_ctx; + +static ssize_t read_test_unauthorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&unauthorized_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_unauthorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("unauthorized chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&unauthorized_chrc_ctx, buf, len, offset, flags); +} + +static struct test_chrc_ctx authorized_chrc_ctx; + +static ssize_t read_test_authorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + return read_test_chrc(&authorized_chrc_ctx, conn, attr, buf, len, offset); +} + +static ssize_t write_test_authorized_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + printk("authorized chrc len %u offset %u\n", len, offset); + + return write_test_chrc(&authorized_chrc_ctx, buf, len, offset, flags); +} + +static const struct test_chrc_ctx zeroed_chrc_ctx; + +static bool unhandled_chrc_operation_validate(void) +{ + if (memcmp(&unauthorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&authorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((unhandled_chrc_ctx.read_cnt != 1) && (unhandled_chrc_ctx.write_cnt != 1)) { + return false; + } + + if ((unhandled_chrc_ctx.auth_read_cnt != 0) && + (unhandled_chrc_ctx.auth_write_cnt != 0)) { + return false; + } + + return true; +} + +static bool unauthorized_chrc_operation_validate(void) +{ + if (memcmp(&unhandled_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&authorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((unauthorized_chrc_ctx.read_cnt != 0) && (unauthorized_chrc_ctx.write_cnt != 0)) { + return false; + } + + if ((unauthorized_chrc_ctx.auth_read_cnt != 1) && + (unauthorized_chrc_ctx.auth_write_cnt != 1)) { + return false; + } + + return true; +} + +static bool authorized_chrc_operation_validate(void) +{ + if (memcmp(&unhandled_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if (memcmp(&unauthorized_chrc_ctx, &zeroed_chrc_ctx, sizeof(zeroed_chrc_ctx)) != 0) { + return false; + } + + if ((authorized_chrc_ctx.read_cnt != 1) && (authorized_chrc_ctx.write_cnt != 1)) { + return false; + } + + if ((authorized_chrc_ctx.auth_read_cnt != 1) && + (authorized_chrc_ctx.auth_write_cnt != 1)) { + return false; + } + + return true; +} + +static ssize_t write_cp_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) +{ + static uint16_t cp_write_cnt; + bool pass; + char *log_str; + + if (cp_write_cnt == 0) { + pass = unhandled_chrc_operation_validate(); + log_str = "unhandled"; + } else if (cp_write_cnt == 1) { + pass = unauthorized_chrc_operation_validate(); + log_str = "unauthorized"; + } else if (cp_write_cnt == 2) { + pass = authorized_chrc_operation_validate(); + log_str = "authorized"; + } else { + FAIL("Invalid value of CP write counter %u\n", cp_write_cnt); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + if (pass) { + printk("Correct context for %s chrc\n", log_str); + } else { + FAIL("Invalid context for %s chrc\n", log_str); + return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY); + } + + memset(&unhandled_chrc_ctx, 0, sizeof(unhandled_chrc_ctx)); + memset(&unauthorized_chrc_ctx, 0, sizeof(unauthorized_chrc_ctx)); + memset(&authorized_chrc_ctx, 0, sizeof(authorized_chrc_ctx)); + + cp_write_cnt++; + + if (cp_write_cnt == 3) { + SET_FLAG(flag_is_chrc_ctx_validated); + } + + return len; +} + +BT_GATT_SERVICE_DEFINE(test_svc, + BT_GATT_PRIMARY_SERVICE(TEST_SERVICE_UUID), + BT_GATT_CHARACTERISTIC(TEST_UNHANDLED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_unhandled_chrc, + write_test_unhandled_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_UNAUTHORIZED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_unauthorized_chrc, + write_test_unauthorized_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_AUTHORIZED_CHRC_UUID, + BT_GATT_CHRC_WRITE | BT_GATT_CHRC_READ, + BT_GATT_PERM_WRITE | BT_GATT_PERM_READ, + read_test_authorized_chrc, + write_test_authorized_chrc, NULL), + BT_GATT_CHARACTERISTIC(TEST_CP_CHRC_UUID, + BT_GATT_CHRC_WRITE, + BT_GATT_PERM_WRITE, + NULL, write_cp_chrc, NULL), +); + +static bool gatt_read_operation_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (bt_uuid_cmp(attr->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + unauthorized_chrc_ctx.auth_read_cnt++; + return false; + } else if (bt_uuid_cmp(attr->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + authorized_chrc_ctx.auth_read_cnt++; + return true; + } else { + return true; + } +} + +static bool gatt_write_operation_authorize(struct bt_conn *conn, + const struct bt_gatt_attr *attr) +{ + if (bt_uuid_cmp(attr->uuid, TEST_UNAUTHORIZED_CHRC_UUID) == 0) { + unauthorized_chrc_ctx.auth_write_cnt++; + return false; + } else if (bt_uuid_cmp(attr->uuid, TEST_AUTHORIZED_CHRC_UUID) == 0) { + authorized_chrc_ctx.auth_write_cnt++; + return true; + } else { + return true; + } +} + +static const struct bt_gatt_authorization_cb gatt_authorization_callbacks = { + .read_operation_authorize = gatt_read_operation_authorize, + .write_operation_authorize = gatt_write_operation_authorize, +}; + +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)) + }; + + err = bt_gatt_authorization_cb_register(&gatt_authorization_callbacks); + if (err) { + FAIL("Registering GATT authorization callbacks failed (err %d)\n", err); + return; + } + + err = bt_enable(NULL); + if (err != 0) { + FAIL("Bluetooth init failed (err %d)\n", err); + return; + } + + printk("Bluetooth initialized\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("Advertising successfully started\n"); + + WAIT_FOR_FLAG(flag_is_chrc_ctx_validated); + + PASS("GATT server passed\n"); +} + +static const struct bst_test_instance test_gatt_server[] = { + { + .test_id = "gatt_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_gatt_server_install(struct bst_test_list *tests) +{ + return bst_add_tests(tests, test_gatt_server); +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/src/main.c b/tests/bsim/bluetooth/host/gatt/authorization/src/main.c new file mode 100644 index 00000000000..a95f0285e75 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/src/main.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "bstests.h" + +extern struct bst_test_list *test_gatt_server_install(struct bst_test_list *tests); +extern struct bst_test_list *test_gatt_client_install(struct bst_test_list *tests); + +bst_test_install_t test_installers[] = { + test_gatt_server_install, + test_gatt_client_install, + NULL +}; + +int main(void) +{ + bst_main(); + return 0; +} diff --git a/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh b/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh new file mode 100755 index 00000000000..edad0eb86c9 --- /dev/null +++ b/tests/bsim/bluetooth/host/gatt/authorization/test_scripts/gatt.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# Copyright 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +simulation_id="gatt_authorization" +verbosity_level=2 +EXECUTE_TIMEOUT=120 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_gatt_authorization_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=gatt_client + +Execute ./bs_${BOARD}_tests_bsim_bluetooth_host_gatt_authorization_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=gatt_server + +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/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/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..a1258ecf1f2 --- /dev/null +++ b/tests/bsim/bluetooth/ll/cis/sysbuild.cmake @@ -0,0 +1,24 @@ +# 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 "" + ) + + native_simulator_set_primary_mcu_index(${DEFAULT_IMAGE} ${NET_APP}) + + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) +endif() + +native_simulator_set_final_executable(${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 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}) diff --git a/tests/bsim/bluetooth/ll/multiple_id/tests_scripts/multiple.sh b/tests/bsim/bluetooth/ll/multiple_id/tests_scripts/multiple.sh index 1bdd2874916..cfbac8c313f 100755 --- a/tests/bsim/bluetooth/ll/multiple_id/tests_scripts/multiple.sh +++ b/tests/bsim/bluetooth/ll/multiple_id/tests_scripts/multiple.sh @@ -18,6 +18,6 @@ Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_multiple_id_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=4500e6 $@ + -D=2 -sim_length=4500e6 $@ -argschannel -at=40 wait_for_background_jobs diff --git a/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh index df82f924fb8..64a3dabac3b 100755 --- a/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh +++ b/tests/bsim/bluetooth/ll/throughput/tests_scripts/gatt_write.sh @@ -17,6 +17,6 @@ Execute ./bs_${BOARD}_tests_bsim_bluetooth_ll_throughput_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=60e6 $@ + -D=2 -sim_length=60e6 $@ -argschannel -at=40 wait_for_background_jobs diff --git a/tests/bsim/bluetooth/mesh/CMakeLists.txt b/tests/bsim/bluetooth/mesh/CMakeLists.txt index 44c72dd9cbb..17bcb3f208f 100644 --- a/tests/bsim/bluetooth/mesh/CMakeLists.txt +++ b/tests/bsim/bluetooth/mesh/CMakeLists.txt @@ -9,30 +9,21 @@ target_sources(app PRIVATE src/main.c src/mesh_test.c src/friendship_common.c + src/gatt_common.c + src/dfu_blob_common.c ) -if(CONFIG_BT_MESH_V1d1) - target_sources(app PRIVATE - src/dfu_blob_common.c - ) -endif() - if(CONFIG_SETTINGS) target_sources(app PRIVATE src/test_persistence.c src/test_replay_cache.c src/test_provision.c - ) - - if(CONFIG_BT_MESH_V1d1) - target_sources(app PRIVATE - src/test_dfu.c - src/test_blob.c - src/test_sar.c - src/test_lcd.c - ) - endif() + src/test_dfu.c + src/test_blob.c + src/test_sar.c + src/test_lcd.c +) if(CONFIG_BT_MESH_USES_MBEDTLS_PSA) target_sources(app PRIVATE @@ -45,13 +36,9 @@ elseif(CONFIG_BT_MESH_GATT_PROXY) target_sources(app PRIVATE src/test_advertiser.c - ) - - if(CONFIG_BT_MESH_V1d1) - target_sources(app PRIVATE + src/test_suspend.c src/test_beacon.c - ) - endif() + ) elseif(CONFIG_BT_CTLR_LOW_LAT) @@ -72,17 +59,13 @@ else() src/test_access.c src/test_iv_index.c src/test_advertiser.c + src/test_suspend.c + src/test_blob.c + src/test_op_agg.c + src/test_sar.c + src/test_cdp1.c ) - if(CONFIG_BT_MESH_V1d1) - target_sources(app PRIVATE - src/test_blob.c - src/test_op_agg.c - src/test_sar.c - src/test_cdp1.c - ) - endif() - endif() zephyr_include_directories( diff --git a/tests/bsim/bluetooth/mesh/README.rst b/tests/bsim/bluetooth/mesh/README.rst index 787b0084f0b..1ae78887b71 100644 --- a/tests/bsim/bluetooth/mesh/README.rst +++ b/tests/bsim/bluetooth/mesh/README.rst @@ -1,7 +1,7 @@ -Bluetooth mesh BabbleSim tests +Bluetooth Mesh BabbleSim tests ############################## -This directory contains a set of high level system tests for the Bluetooth mesh +This directory contains a set of high level system tests for the Bluetooth Mesh subsystem. The tests run on the BabbleSim simulator, using the BabbleSim test framework. @@ -10,7 +10,7 @@ subfolder of test_scripts contains tests for a specific module in the Bluetooth mesh subsystem, and each folder has a corresponding test_.c under the src/ directory containing the necessary test harnesses to execute the tests. -There's only a single test application for all the Bluetooth mesh BabbleSim +There's only a single test application for all the Bluetooth Mesh BabbleSim tests. The test application is built from this directory, and includes all test harnesses in every build. The overlying bsim test framework selects the harness to use at runtime, using the test identifiers passed in the test scripts. @@ -18,7 +18,7 @@ to use at runtime, using the test identifiers passed in the test scripts. Running the tests ***************** -The Bluetooth mesh tests have no extra requirements, and can be run using the +The Bluetooth Mesh tests have no extra requirements, and can be run using the procedure described in the parent folder. To only run the mesh tests, set ``SEARCH_PATH`` to point to this folder before @@ -57,13 +57,13 @@ Then separately, call Framework ********* -The Bluetooth mesh BabbleSim tests mainly operate on the test framework for the +The Bluetooth Mesh BabbleSim tests mainly operate on the test framework for the BabbleSim platform, but with some mesh specific additions: mesh_test.sh ============= -All test scripts in the Bluetooth mesh BabbleSim test suite follow a common +All test scripts in the Bluetooth Mesh BabbleSim test suite follow a common pattern for running a single test across N devices with different test harnesses. ``mesh_test.sh`` is sourced in each test script, and its ``RunTest`` function is called once in each script with the following parameters: @@ -113,6 +113,6 @@ has been called - otherwise, it will fail. The Bluetooth stack must be initialized in the ``test_main_f`` function of the harness, as the previous callbacks are all executed in hardware threads. -The Bluetooth mesh tests include the entire Bluetooth host and controller +The Bluetooth Mesh tests include the entire Bluetooth host and controller subsystems, so timing requirements should generally be kept fairly liberal to avoid regressions on changes in the underlying layers. diff --git a/tests/bsim/bluetooth/mesh/compile.sh b/tests/bsim/bluetooth/mesh/compile.sh index de9b4bd6af0..06557ef0ebb 100755 --- a/tests/bsim/bluetooth/mesh/compile.sh +++ b/tests/bsim/bluetooth/mesh/compile.sh @@ -18,22 +18,13 @@ mkdir -p ${WORK_DIR} source ${ZEPHYR_BASE}/tests/bsim/compile.source app=tests/bsim/bluetooth/mesh compile -app=tests/bsim/bluetooth/mesh conf_overlay=overlay_low_lat.conf compile app=tests/bsim/bluetooth/mesh conf_overlay=overlay_pst.conf compile app=tests/bsim/bluetooth/mesh conf_overlay=overlay_gatt.conf compile -app=tests/bsim/bluetooth/mesh conf_file=prj_mesh1d1.conf compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay=overlay_pst.conf compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay=overlay_gatt.conf compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay=overlay_low_lat.conf compile -app=tests/bsim/bluetooth/mesh conf_file=prj_mesh1d1.conf conf_overlay=overlay_psa.conf compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay="overlay_pst.conf;overlay_psa.conf" compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay="overlay_gatt.conf;overlay_psa.conf" compile -app=tests/bsim/bluetooth/mesh \ - conf_file=prj_mesh1d1.conf conf_overlay="overlay_low_lat.conf;overlay_psa.conf" compile +app=tests/bsim/bluetooth/mesh conf_overlay=overlay_low_lat.conf compile +app=tests/bsim/bluetooth/mesh conf_overlay=overlay_psa.conf compile +app=tests/bsim/bluetooth/mesh conf_overlay="overlay_pst.conf;overlay_psa.conf" compile +app=tests/bsim/bluetooth/mesh conf_overlay="overlay_gatt.conf;overlay_psa.conf" compile +app=tests/bsim/bluetooth/mesh conf_overlay="overlay_low_lat.conf;overlay_psa.conf" compile +app=tests/bsim/bluetooth/mesh conf_overlay="overlay_gatt.conf;overlay_low_lat.conf" compile wait_for_background_jobs diff --git a/tests/bsim/bluetooth/mesh/overlay_gatt.conf b/tests/bsim/bluetooth/mesh/overlay_gatt.conf index f94a26d623f..7660313b700 100644 --- a/tests/bsim/bluetooth/mesh/overlay_gatt.conf +++ b/tests/bsim/bluetooth/mesh/overlay_gatt.conf @@ -6,3 +6,4 @@ CONFIG_BT_MESH_LOW_POWER=n CONFIG_BT_MESH_FRIEND=n CONFIG_BT_CENTRAL=y CONFIG_BT_MESH_PROXY_CLIENT=y +CONFIG_BT_MESH_PROXY_SOLICITATION=y diff --git a/tests/bsim/bluetooth/mesh/overlay_pst.conf b/tests/bsim/bluetooth/mesh/overlay_pst.conf index 6a56ec8065b..e02c0ec2b93 100644 --- a/tests/bsim/bluetooth/mesh/overlay_pst.conf +++ b/tests/bsim/bluetooth/mesh/overlay_pst.conf @@ -18,5 +18,4 @@ CONFIG_BT_MESH_SUBNET_COUNT=2 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/prj.conf b/tests/bsim/bluetooth/mesh/prj.conf index b0738c4fa05..1c343bb512f 100644 --- a/tests/bsim/bluetooth/mesh/prj.conf +++ b/tests/bsim/bluetooth/mesh/prj.conf @@ -15,15 +15,16 @@ CONFIG_BT_BROADCASTER=y CONFIG_BT_CTLR_DUP_FILTER_LEN=0 CONFIG_BT_CTLR_PRIVACY=n -# Bluetooth mesh configuration +# Bluetooth Mesh configuration CONFIG_BT_MESH=y CONFIG_BT_MESH_LOG_LEVEL_DBG=y CONFIG_BT_MESH_RELAY=y -CONFIG_BT_MESH_ADV_BUF_COUNT=32 +CONFIG_BT_MESH_ADV_BUF_COUNT=64 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 @@ -37,10 +38,35 @@ CONFIG_BT_MESH_LABEL_COUNT=3 CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_PB_ADV=y CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=y +CONFIG_BT_MESH_PROVISIONEE=y CONFIG_BT_MESH_CDB=y 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_MESH_SAR_CFG_CLI=y +CONFIG_BT_MESH_SAR_CFG_SRV=y +CONFIG_BT_MESH_BLOB_SRV=y +CONFIG_BT_MESH_BLOB_CLI=y +CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN=256 +CONFIG_BT_MESH_RPR_CLI=y +CONFIG_BT_MESH_RPR_SRV=y +CONFIG_BT_MESH_OP_AGG_CLI=y +CONFIG_BT_MESH_OP_AGG_SRV=y +CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y +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_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 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/prj_mesh1d1.conf b/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf deleted file mode 100644 index ab6066e01bf..00000000000 --- a/tests/bsim/bluetooth/mesh/prj_mesh1d1.conf +++ /dev/null @@ -1,73 +0,0 @@ -CONFIG_LOG_MODE_IMMEDIATE=y -CONFIG_ASSERT=y -CONFIG_SYS_CLOCK_TICKS_PER_SEC=32768 - -# Bluetooth configuration -CONFIG_BT=y -CONFIG_LOG=y -CONFIG_BT_PRIVACY=n -CONFIG_BT_COMPANY_ID=0x0059 -CONFIG_BT_DEVICE_NAME="Mesh test" -CONFIG_BT_OBSERVER=y -CONFIG_BT_BROADCASTER=y - -# Disable unused Bluetooth features -CONFIG_BT_CTLR_DUP_FILTER_LEN=0 -CONFIG_BT_CTLR_PRIVACY=n - -# Bluetooth mesh configuration -CONFIG_BT_MESH=y -CONFIG_BT_MESH_V1d1=y -CONFIG_BT_MESH_LOG_LEVEL_DBG=y -CONFIG_BT_MESH_RELAY=y -CONFIG_BT_MESH_ADV_BUF_COUNT=64 -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 -CONFIG_BT_MESH_LPN_AUTO=n -CONFIG_BT_MESH_FRIEND=y -CONFIG_BT_MESH_FRIEND_ENABLED=n -CONFIG_BT_MESH_FRIEND_LPN_COUNT=5 -CONFIG_BT_MESH_APP_KEY_COUNT=2 -CONFIG_BT_MESH_MODEL_KEY_COUNT=2 -CONFIG_BT_MESH_LABEL_COUNT=3 -CONFIG_BT_MESH_IV_UPDATE_TEST=y -CONFIG_BT_MESH_PB_ADV=y -CONFIG_BT_MESH_PROVISIONER=y -CONFIG_BT_MESH_PROV_DEVICE=y -CONFIG_BT_MESH_CDB=y -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_MESH_SAR_CFG_CLI=y -CONFIG_BT_MESH_SAR_CFG_SRV=y -CONFIG_BT_MESH_BLOB_SRV=y -CONFIG_BT_MESH_BLOB_CLI=y -CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN=256 -CONFIG_BT_MESH_RPR_CLI=y -CONFIG_BT_MESH_RPR_SRV=y -CONFIG_BT_MESH_OP_AGG_CLI=y -CONFIG_BT_MESH_OP_AGG_SRV=y -CONFIG_BT_MESH_LARGE_COMP_DATA_CLI=y -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_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 -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/main.c b/tests/bsim/bluetooth/mesh/src/main.c index 127e52faa49..a3dfb59373f 100644 --- a/tests/bsim/bluetooth/mesh/src/main.c +++ b/tests/bsim/bluetooth/mesh/src/main.c @@ -11,18 +11,14 @@ extern struct bst_test_list *test_persistence_install(struct bst_test_list *tests); extern struct bst_test_list *test_rpc_install(struct bst_test_list *tests); extern struct bst_test_list *test_provision_pst_install(struct bst_test_list *tests); -#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) 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_suspend_install(struct bst_test_list *test); 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); @@ -36,30 +32,26 @@ extern struct bst_test_list *test_heartbeat_install(struct bst_test_list *test); extern struct bst_test_list *test_access_install(struct bst_test_list *test); extern struct bst_test_list *test_ivi_install(struct bst_test_list *test); 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_suspend_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 bst_test_install_t test_installers[] = { #if defined(CONFIG_SETTINGS) test_persistence_install, test_rpc_install, -#if defined(CONFIG_BT_MESH_V1d1) 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) test_adv_install, -#if defined(CONFIG_BT_MESH_V1d1) + test_suspend_install, test_beacon_install, -#endif /* defined(CONFIG_BT_MESH_V1d1) */ #elif defined(CONFIG_BT_CTLR_LOW_LAT) test_transport_install, test_friendship_install, @@ -73,12 +65,11 @@ bst_test_install_t test_installers[] = { test_access_install, test_ivi_install, test_adv_install, -#if defined(CONFIG_BT_MESH_V1d1) + test_suspend_install, 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/mesh_test.h b/tests/bsim/bluetooth/mesh/src/mesh_test.h index a5c8694947b..3dcaa5f784a 100644 --- a/tests/bsim/bluetooth/mesh/src/mesh_test.h +++ b/tests/bsim/bluetooth/mesh/src/mesh_test.h @@ -1,5 +1,5 @@ /** @file - * @brief Common functionality for Bluetooth mesh BabbleSim tests. + * @brief Common functionality for Bluetooth Mesh BabbleSim tests. */ /* diff --git a/tests/bsim/bluetooth/mesh/src/test_access.c b/tests/bsim/bluetooth/mesh/src/test_access.c index b8b10fd7634..6967aa6d71c 100644 --- a/tests/bsim/bluetooth/mesh/src/test_access.c +++ b/tests/bsim/bluetooth/mesh/src/test_access.c @@ -60,6 +60,7 @@ static const struct { uint8_t div; int32_t period_ms; } test_period[] = { + { BT_MESH_PUB_PERIOD_100MS(1), 0, 100 }, { BT_MESH_PUB_PERIOD_100MS(5), 0, 500 }, { BT_MESH_PUB_PERIOD_SEC(2), 0, 2000 }, { BT_MESH_PUB_PERIOD_10SEC(1), 0, 10000 }, @@ -101,11 +102,15 @@ static bool publish_allow; static int model1_update(const struct bt_mesh_model *model) { - model->pub->msg->data[1]++; + if (!publish_allow) { + return -1; + } + model->pub->msg->data[1]++; LOG_DBG("New pub: n: %d t: %d", model->pub->msg->data[1], k_uptime_get_32()); + k_sem_give(&publish_sem); - return publish_allow ? k_sem_give(&publish_sem), 0 : -1; + return 0; } static int test_msgf_handler(const struct bt_mesh_model *model, @@ -522,6 +527,92 @@ static void msgf_publish(void) bt_mesh_model_publish(model); } +static void pub_delayable_check(int32_t interval, uint8_t count) +{ + int64_t timestamp = k_uptime_get(); + int err; + + for (size_t j = 0; j < count; j++) { + /* Every new publication will release semaphore in the update handler and the time + * between two consecutive publications will be measured. + */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Send timed out"); + } + + int32_t time_delta = k_uptime_delta(×tamp); + int32_t pub_delta = time_delta - interval; + + LOG_DBG("Send time: %d delta: %d pub_delta: %d", (int32_t)timestamp, time_delta, + pub_delta); + + if (j == 0) { + /* The first delta will be between the messages published manually and next + * publication (or retransmission). So the time difference should not be + * longer than 500 - 20 + 10 (margin): + * + * |---|-------|--------|-------|----> + * M1 20ms tx(M1) 500ms + * update() + */ + ASSERT_IN_RANGE(pub_delta, 0, 510); + } else { + /* Time difference between the consequtive update callback calls should be + * within a small margin like without random delay as the callbacks should + * be called at the regular interval or immediately (if it passed the next + * period time). + */ + ASSERT_IN_RANGE(pub_delta, 0, 10); + } + } +} + +static void recv_delayable_check(int32_t interval, uint8_t count) +{ + int64_t timestamp; + int err; + + /* The measurement starts by the first received message. */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Recv timed out"); + } + + timestamp = k_uptime_get(); + + for (size_t j = 0; j < count; j++) { + /* Every new received message will release semaphore in the message handler and + * the time between two consecutive publications will be measured. + */ + err = k_sem_take(&publish_sem, K_SECONDS(20)); + if (err) { + FAIL("Recv timed out"); + } + + int32_t time_delta = k_uptime_delta(×tamp); + /* First message can be delayed up to 500ms, others for up to 50ms. */ + int32_t upper_delay = j == 0 ? 500 : 50; + + /* + * Lower boundary: tx2 - tx1 + interval + * |---|-------|---------------|-------|-----> + * M1 tx1(50ms/500ms) M2 tx2(20ms) + * + * Upper boundary: tx2 - tx1 + interval + * |---|-------|--------|-----------|-----> + * M1 tx1(20ms) M2 tx2(50ms/500ms) + */ + int32_t lower_boundary = 20 - upper_delay + interval; + int32_t upper_boundary = upper_delay - 20 + interval; + + LOG_DBG("Recv time: %d delta: %d boundaries: %d/%d", (int32_t)timestamp, time_delta, + lower_boundary, upper_boundary); + ASSERT_IN_RANGE(time_delta, lower_boundary - RX_JITTER_MAX, + upper_boundary + RX_JITTER_MAX); + } +} + static void pub_jitter_check(int32_t interval, uint8_t count) { int64_t timestamp = k_uptime_get(); @@ -578,8 +669,8 @@ static void recv_jitter_check(int32_t interval, uint8_t count) jitter = MAX(pub_delta, jitter); - LOG_DBG("Recv time: %d delta: %d jitter: %d", (int32_t)timestamp, time_delta, - jitter); + LOG_DBG("Recv time: %d delta: %d jitter: %d, j: %d", (int32_t)timestamp, time_delta, + jitter, j); } LOG_INF("Recv jitter: %d", jitter); @@ -589,17 +680,19 @@ static void recv_jitter_check(int32_t interval, uint8_t count) /* Test publish period states by publishing a message and checking interval between update handler * calls. */ -static void test_tx_period(void) +static void tx_period(bool delayable) { const struct bt_mesh_model *model = &models[2]; - bt_mesh_test_cfg_set(NULL, 60); + bt_mesh_test_cfg_set(NULL, 70); bt_mesh_device_setup(&prov, &local_comp); provision(UNICAST_ADDR1); common_configure(UNICAST_ADDR1); k_sem_init(&publish_sem, 0, 1); + model->pub->delayable = delayable; + for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) { pub_param_set(test_period[i].period, 0); @@ -611,7 +704,11 @@ static void test_tx_period(void) /* Start publishing messages and measure jitter. */ msgf_publish(); publish_allow = true; - pub_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + if (delayable) { + pub_delayable_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } else { + pub_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } /* Disable periodic publication before the next test iteration. */ publish_allow = false; @@ -626,9 +723,9 @@ static void test_tx_period(void) /* Receive a periodically published message and check publication period by measuring interval * between message handler calls. */ -static void test_rx_period(void) +static void rx_period(bool delayable) { - bt_mesh_test_cfg_set(NULL, 60); + bt_mesh_test_cfg_set(NULL, 70); bt_mesh_device_setup(&prov, &local_comp); provision(UNICAST_ADDR2); common_configure(UNICAST_ADDR2); @@ -636,16 +733,40 @@ static void test_rx_period(void) k_sem_init(&publish_sem, 0, 1); for (size_t i = 0; i < ARRAY_SIZE(test_period); i++) { - recv_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + if (delayable) { + recv_delayable_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } else { + recv_jitter_check(test_period[i].period_ms, PUB_PERIOD_COUNT); + } } PASS(); } +static void test_tx_period(void) +{ + tx_period(false); +} + +static void test_rx_period(void) +{ + rx_period(false); +} + +static void test_tx_period_delayable(void) +{ + tx_period(true); +} + +static void test_rx_period_delayable(void) +{ + rx_period(true); +} + /* Test publish retransmit interval and count states by publishing a message and checking interval * between update handler calls. */ -static void test_tx_transmit(void) +static void tx_transmit(bool delayable) { const struct bt_mesh_model *model = &models[2]; uint8_t status; @@ -672,6 +793,7 @@ static void test_tx_transmit(void) publish_allow = true; model->pub->retr_update = true; + model->pub->delayable = delayable; for (size_t i = 0; i < ARRAY_SIZE(test_transmit); i++) { pub_param_set(0, test_transmit[i]); @@ -683,7 +805,11 @@ static void test_tx_transmit(void) /* Start publishing messages and measure jitter. */ msgf_publish(); - pub_jitter_check(interval, count); + if (delayable) { + pub_delayable_check(interval, count); + } else { + pub_jitter_check(interval, count); + } /* Let the receiver hit the first semaphore. */ k_sleep(K_SECONDS(1)); @@ -695,7 +821,7 @@ static void test_tx_transmit(void) /* Receive a published message and check retransmission interval by measuring interval between * message handler calls. */ -static void test_rx_transmit(void) +static void rx_transmit(bool delayable) { bt_mesh_test_cfg_set(NULL, 60); bt_mesh_device_setup(&prov, &local_comp); @@ -708,12 +834,36 @@ static void test_rx_transmit(void) int32_t interval = BT_MESH_PUB_TRANSMIT_INT(test_transmit[i]); int count = BT_MESH_PUB_TRANSMIT_COUNT(test_transmit[i]); - recv_jitter_check(interval, count); + if (delayable) { + recv_delayable_check(interval, count); + } else { + recv_jitter_check(interval, count); + } } PASS(); } +static void test_tx_transmit(void) +{ + tx_transmit(false); +} + +static void test_rx_transmit(void) +{ + rx_transmit(false); +} + +static void test_tx_transmit_delayable(void) +{ + tx_transmit(true); +} + +static void test_rx_transmit_delayable(void) +{ + rx_transmit(true); +} + /* Cancel one of messages to be published and check that the next one is published when next period * starts. */ @@ -841,6 +991,13 @@ static const struct bst_test_instance test_access[] = { TEST_CASE(tx, cancel, "Access: Cancel a message during publication"), TEST_CASE(rx, cancel, "Access: Receive published messages except cancelled"), + TEST_CASE(tx, period_delayable, "Access: Test delayable periodic publication"), + TEST_CASE(rx, period_delayable, "Access: Receive delayable periodic publication"), + + TEST_CASE(tx, transmit_delayable, "Access: Test delayable publication with retransmission"), + TEST_CASE(rx, transmit_delayable, "Access: Receive delayable publication with" + " retransmissions"), + BSTEST_END_MARKER }; diff --git a/tests/bsim/bluetooth/mesh/src/test_advertiser.c b/tests/bsim/bluetooth/mesh/src/test_advertiser.c index 073651ae843..47851fc72f4 100644 --- a/tests/bsim/bluetooth/mesh/src/test_advertiser.c +++ b/tests/bsim/bluetooth/mesh/src/test_advertiser.c @@ -7,7 +7,6 @@ #include #include #include "mesh_test.h" -#include "mesh/adv.h" #include "mesh/net.h" #include "mesh/mesh.h" #include "mesh/foundation.h" @@ -78,25 +77,25 @@ static void adv_init(void) ASSERT_OK_MSG(bt_mesh_adv_enable(), "Mesh adv init failed"); } -static void allocate_all_array(struct net_buf **buf, size_t num_buf, uint8_t xmit) +static void allocate_all_array(struct bt_mesh_adv **adv, size_t num_adv, 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, + for (int i = 0; i < num_adv; i++) { + *adv = 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"); - buf++; + ASSERT_FALSE_MSG(!*adv, "Out of advs\n"); + adv++; } } static void verify_adv_queue_overflow(void) { - struct net_buf *dummy_buf; + struct bt_mesh_adv *dummy_adv; /* Verity Queue overflow */ - dummy_buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + dummy_adv = 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"); + ASSERT_TRUE_MSG(!dummy_adv, "Unexpected extra adv\n"); } static bool check_delta_time(uint8_t transmit, uint64_t interval) @@ -157,12 +156,12 @@ static void single_end_cb(int err, void *cb_data) static void realloc_end_cb(int err, void *cb_data) { - struct net_buf *buf = (struct net_buf *)cb_data; + struct bt_mesh_adv *adv = (struct bt_mesh_adv *)cb_data; ASSERT_EQUAL(0, err); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); + ASSERT_FALSE_MSG(!adv, "Out of advs\n"); k_sem_give(&observer_sem); } @@ -305,13 +304,13 @@ static void rx_xmit_adv(void) static void send_order_start_cb(uint16_t duration, int err, void *user_data) { - struct net_buf *buf = (struct net_buf *)user_data; + struct bt_mesh_adv *adv = (struct bt_mesh_adv *)user_data; ASSERT_OK_MSG(err, "Failed adv start cb err (%d)", err); - ASSERT_EQUAL(2, buf->len); + ASSERT_EQUAL(2, adv->b.len); - uint8_t current = buf->data[0]; - uint8_t previous = buf->data[1]; + uint8_t current = adv->b.data[0]; + uint8_t previous = adv->b.data[1]; LOG_INF("tx start: current(%d) previous(%d)", current, previous); @@ -321,10 +320,7 @@ static void send_order_start_cb(uint16_t duration, int err, void *user_data) 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_MSG(!buf->data, "Data not cleared!\n"); seq_checker++; LOG_INF("tx end: seq(%d)", seq_checker); @@ -380,19 +376,19 @@ static void receive_order(int expect_adv) 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) +static void send_adv_buf(struct bt_mesh_adv *adv, uint8_t curr, uint8_t prev) { send_cb.start = send_order_start_cb; send_cb.end = send_order_end_cb; - (void)net_buf_add_u8(buf, curr); - (void)net_buf_add_u8(buf, prev); + (void)net_buf_simple_add_u8(&adv->b, curr); + (void)net_buf_simple_add_u8(&adv->b, prev); - bt_mesh_adv_send(buf, &send_cb, buf); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &send_cb, adv); + bt_mesh_adv_unref(adv); } -static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) +static void send_adv_array(struct bt_mesh_adv **adv, size_t num_buf, bool reverse) { uint8_t previous; int i; @@ -405,13 +401,13 @@ static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) i = num_buf - 1; } while ((!reverse && i < num_buf) || (reverse && i >= 0)) { - send_adv_buf(*buf, (uint8_t)i, previous); + send_adv_buf(*adv, (uint8_t)i, previous); previous = (uint8_t)i; if (!reverse) { - buf++; + adv++; i++; } else { - buf--; + adv--; i--; } } @@ -419,24 +415,24 @@ static void send_adv_array(struct net_buf **buf, size_t num_buf, bool reverse) static void test_tx_cb_single(void) { - struct net_buf *buf; + struct bt_mesh_adv *adv; int err; bt_init(); adv_init(); - buf = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv = 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"); + ASSERT_FALSE_MSG(!adv, "Out of advs\n"); send_cb.start = single_start_cb; send_cb.end = single_end_cb; - net_buf_add_mem(buf, txt_msg, sizeof(txt_msg)); + net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg)); seq_checker = 0; tx_timestamp = k_uptime_get(); - bt_mesh_adv_send(buf, &send_cb, (void *)cb_msg); - net_buf_unref(buf); + bt_mesh_adv_send(adv, &send_cb, (void *)cb_msg); + bt_mesh_adv_unref(adv); err = k_sem_take(&observer_sem, K_SECONDS(1)); ASSERT_OK_MSG(err, "Didn't call end tx cb."); @@ -457,37 +453,37 @@ static void test_rx_xmit(void) static void test_tx_cb_multi(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; int err; bt_init(); adv_init(); - /* Allocate all network buffers. */ - allocate_all_array(buf, ARRAY_SIZE(buf), BT_MESH_TRANSMIT(2, 20)); + /* Allocate all network advs. */ + allocate_all_array(adv, ARRAY_SIZE(adv), BT_MESH_TRANSMIT(2, 20)); - /* Start single adv to reallocate one network buffer in callback. - * Check that the buffer is freed before cb is triggered. + /* Start single adv to reallocate one network adv in callback. + * Check that the adv is freed before cb is triggered. */ send_cb.start = NULL; send_cb.end = realloc_end_cb; - net_buf_add_mem(buf[0], txt_msg, sizeof(txt_msg)); + net_buf_simple_add_mem(&(adv[0]->b), txt_msg, sizeof(txt_msg)); - bt_mesh_adv_send(buf[0], &send_cb, buf[0]); - net_buf_unref(buf[0]); + bt_mesh_adv_send(adv[0], &send_cb, adv[0]); + bt_mesh_adv_unref(adv[0]); err = k_sem_take(&observer_sem, K_SECONDS(1)); - ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates buffer one more time."); + ASSERT_OK_MSG(err, "Didn't call the end tx cb that reallocates adv one more time."); - /* Start multi advs to check that all buffers are sent and cbs are triggered. */ + /* Start multi advs to check that all advs are sent and cbs are triggered. */ send_cb.start = seq_start_cb; send_cb.end = seq_end_cb; seq_checker = 0; for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) { - net_buf_add_le32(buf[i], i); - bt_mesh_adv_send(buf[i], &send_cb, (void *)(intptr_t)i); - net_buf_unref(buf[i]); + net_buf_simple_add_le32(&(adv[i]->b), i); + bt_mesh_adv_send(adv[i], &send_cb, (void *)(intptr_t)i); + bt_mesh_adv_unref(adv[i]); } err = k_sem_take(&observer_sem, K_SECONDS(10)); @@ -530,10 +526,10 @@ 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 bt_mesh_adv *adv = 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); + net_buf_simple_add_mem(&adv->b, txt_msg, sizeof(txt_msg)); + bt_mesh_adv_send(adv, NULL, NULL); k_sleep(K_MSEC(150)); /* Let the tester to measure an interval between advertisements again. */ @@ -577,46 +573,46 @@ static void test_rx_proxy_mixin(void) static void test_tx_send_order(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; uint8_t xmit = BT_MESH_TRANSMIT(2, 20); bt_init(); adv_init(); /* Verify sending order */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); verify_adv_queue_overflow(); - send_adv_array(&buf[0], ARRAY_SIZE(buf), false); + send_adv_array(&adv[0], ARRAY_SIZE(adv), false); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), "Didn't call the last end tx cb."); - /* Verify buffer allocation/deallocation after sending */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + /* Verify adv allocation/deallocation after sending */ + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); verify_adv_queue_overflow(); for (int i = 0; i < CONFIG_BT_MESH_ADV_BUF_COUNT; i++) { - net_buf_unref(buf[i]); - buf[i] = NULL; + bt_mesh_adv_unref(adv[i]); + adv[i] = NULL; } - /* Check that it possible to add just one net buf. */ - allocate_all_array(buf, 1, xmit); + /* Check that it possible to add just one net adv. */ + allocate_all_array(adv, 1, xmit); PASS(); } static void test_tx_reverse_order(void) { - struct net_buf *buf[CONFIG_BT_MESH_ADV_BUF_COUNT]; + struct bt_mesh_adv *adv[CONFIG_BT_MESH_ADV_BUF_COUNT]; uint8_t xmit = BT_MESH_TRANSMIT(2, 20); bt_init(); adv_init(); /* Verify reversed sending order */ - allocate_all_array(buf, ARRAY_SIZE(buf), xmit); + allocate_all_array(adv, ARRAY_SIZE(adv), xmit); - send_adv_array(&buf[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(buf), true); + send_adv_array(&adv[CONFIG_BT_MESH_ADV_BUF_COUNT - 1], ARRAY_SIZE(adv), true); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), @@ -627,31 +623,31 @@ static void test_tx_reverse_order(void) static void test_tx_random_order(void) { - struct net_buf *buf[3]; + struct bt_mesh_adv *adv[3]; uint8_t xmit = BT_MESH_TRANSMIT(0, 20); bt_init(); adv_init(); /* Verify random order calls */ - num_adv_sent = ARRAY_SIZE(buf); + num_adv_sent = ARRAY_SIZE(adv); previous_checker = 0xff; - buf[0] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv[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_ADV_TAG_LOCAL, + ASSERT_FALSE_MSG(!adv[0], "Out of advs\n"); + adv[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"); + ASSERT_FALSE_MSG(!adv[1], "Out of advs\n"); - send_adv_buf(buf[0], 0, 0xff); + send_adv_buf(adv[0], 0, 0xff); - buf[2] = bt_mesh_adv_create(BT_MESH_ADV_DATA, BT_MESH_ADV_TAG_LOCAL, + adv[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"); + ASSERT_FALSE_MSG(!adv[2], "Out of advs\n"); - send_adv_buf(buf[2], 2, 0); + send_adv_buf(adv[2], 2, 0); - send_adv_buf(buf[1], 1, 2); + send_adv_buf(adv[1], 1, 2); /* Wait for no message receive window to end. */ ASSERT_OK_MSG(k_sem_take(&observer_sem, K_SECONDS(10)), diff --git a/tests/bsim/bluetooth/mesh/src/test_beacon.c b/tests/bsim/bluetooth/mesh/src/test_beacon.c index e93c2301e46..869dbd4965f 100644 --- a/tests/bsim/bluetooth/mesh/src/test_beacon.c +++ b/tests/bsim/bluetooth/mesh/src/test_beacon.c @@ -6,7 +6,6 @@ #include #include #include "mesh_test.h" -#include "mesh/adv.h" #include "mesh/net.h" #include "mesh/beacon.h" #include "mesh/mesh.h" @@ -28,11 +27,9 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_INF); #define BEACON_INTERVAL 10 /*seconds*/ #define BEACON_TYPE_SECURE 0x01 -#if CONFIG_BT_MESH_V1d1 #define BEACON_TYPE_PRIVATE 0x02 -#endif -static uint8_t test_net_key_secondary[16] = { 0xca, 0x11, 0xab, 0x1e }; +static uint8_t test_net_key_2[16] = { 0xca, 0x11, 0xab, 0x1e }; static struct { uint8_t primary[16]; uint8_t secondary[16]; @@ -72,7 +69,6 @@ BT_MESH_BEACON_CB_DEFINE(snb) = { /* 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 static struct bt_mesh_cfg_cli cfg_cli; static struct bt_mesh_priv_beacon_cli priv_beacon_cli; @@ -100,7 +96,6 @@ static uint8_t last_random[13]; static bt_addr_le_t last_beacon_adv_addr; static struct bt_mesh_key priv_beacon_key; -#endif /* CONFIG_BT_MESH_V1d1 */ static int random_interval; @@ -331,12 +326,11 @@ static struct k_sem observer_sem; static struct { uint8_t flags; uint32_t iv_index; -#if CONFIG_BT_MESH_V1d1 uint8_t random[13]; uint64_t pp_hash; uint64_t pp_random; + uint64_t net_id; bt_addr_le_t adv_addr; -#endif bool (*process_cb)(const uint8_t *net_id, void *ctx); void *user_ctx; } beacon; @@ -364,7 +358,6 @@ static void beacon_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_ty net_id = net_buf_simple_pull_mem(buf, 8); beacon.iv_index = net_buf_simple_pull_be32(buf); } -#if CONFIG_BT_MESH_V1d1 else if (expected_beacon == BEACON_TYPE_PRIVATE) { uint8_t private_beacon_data[5]; @@ -377,7 +370,7 @@ static void beacon_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_ty beacon.flags = private_beacon_data[0]; beacon.iv_index = sys_get_be32(&private_beacon_data[1]); } -#endif + if (!beacon.process_cb || beacon.process_cb(net_id, beacon.user_ctx)) { k_sem_give(&observer_sem); } @@ -514,8 +507,11 @@ static void corrupted_beacon_test(const uint8_t *offsets, } /* Now the beacon payload is valid and it shall trigger IV Update on the node. It shall also - * increase the beacon interval. + * increase the beacon interval. We delay the outgoing beacon for a couple of seconds to + * avoid near perfect syncing with the beacon interval cycle of the device we just received + * a beacon from. */ + k_sleep(K_SECONDS(3)); send_beacon(buf); /* The beacon interval shall be changed and the node shall skip transmission of the next @@ -626,7 +622,7 @@ static void test_tx_kr_old_key(void) * the new Net Key. The node shall set Key Refresh phase to 2. The beacon interval shall * be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x03, 0x0001); + beacon_create(&buf, test_net_key_2, 0x03, 0x0001); send_beacon(&buf); 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)); @@ -646,7 +642,7 @@ static void test_tx_kr_old_key(void) /* Try the same with the new Net Key. Now the node shall change Key Refresh phase to 0. The * beacon interval shall be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x02, 0x0001); + beacon_create(&buf, test_net_key_2, 0x02, 0x0001); send_beacon(&buf); 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)); @@ -666,7 +662,7 @@ static void test_tx_kr_old_key(void) /* Do the same, but secure beacon with the new Net Key. Now the node shall change IV Update * flag to 0. The beacon interval shall be increased. */ - beacon_create(&buf, test_net_key_secondary, 0x00, 0x0001); + beacon_create(&buf, test_net_key_2, 0x00, 0x0001); send_beacon(&buf); 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)); @@ -687,7 +683,7 @@ static void test_rx_kr_old_key(void) bt_mesh_test_setup(); bt_mesh_iv_update_test(true); - err = bt_mesh_cfg_cli_net_key_update(0, cfg->addr, 0, test_net_key_secondary, &status); + err = bt_mesh_cfg_cli_net_key_update(0, cfg->addr, 0, test_net_key_2, &status); if (err || status) { FAIL("Net Key update failed (err %d, status %u)", err, status); } @@ -1064,8 +1060,6 @@ static void test_tx_beacon_cache(void) PASS(); } -#if CONFIG_BT_MESH_V1d1 - typedef void (*priv_beacon_cb)(const struct bt_mesh_prb *prb); static priv_beacon_cb priv_beacon_cb_ptr; @@ -1374,7 +1368,7 @@ static void test_tx_priv_interleave(void) struct bt_mesh_subnet *sub; - bt_mesh_test_cfg_set(NULL, BEACON_INTERVAL_WAIT_TIME); + bt_mesh_test_cfg_set(NULL, WAIT_TIME); bt_mesh_device_setup(&prov, &prb_comp); provision(&tx_cfg); @@ -1407,6 +1401,8 @@ static void test_tx_priv_interleave(void) k_sleep(K_SECONDS(BEACON_INTERVAL + 5)); toggle_priv_beacon(tx_cfg.addr, 0); + /* Small delay to let beacons complete before subnet update is applied */ + k_sleep(K_MSEC(20)); status = bt_mesh_subnet_update(BT_MESH_KEY_PRIMARY, net_key_new); ASSERT_TRUE(status == STATUS_SUCCESS); @@ -1432,7 +1428,7 @@ 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_test_cfg_set(&rx_cfg, WAIT_TIME); bt_mesh_crypto_init(); k_sem_init(&observer_sem, 0, 1); @@ -1542,60 +1538,73 @@ static void test_tx_priv_beacon_cache(void) #if IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY) +static uint8_t test_net_key_3[16] = {0x12, 0x54, 0xab, 0x1e}; + +#define UNTIL_UPTIME(time) (k_uptime_get() > (time) ? K_NO_WAIT : K_MSEC((time) - k_uptime_get())) +#define BEACON_TYPE_NET_ID 0 +#define BEACON_TYPE_NODE_ID 1 #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 TEST_NET_IDX3 2 #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*/ +#define PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME 151 /*seconds*/ -struct pp_netkey_ctx { +struct netkey_ctx { uint8_t *net_key; uint8_t net_id[8]; + uint8_t net_idx; 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}; +static struct netkey_ctx pp_net0 = {.net_key = (uint8_t *)test_net_key, .net_idx = 0}; +static struct netkey_ctx pp_net1 = {.net_key = (uint8_t *)test_net_key_2, .net_idx = 1}; +static struct netkey_ctx pp_net2 = {.net_key = (uint8_t *)test_net_key_3, .net_idx = 2}; struct priv_test_ctx { uint8_t beacon_type; uint16_t *node_id_addr; }; -static void pp_netkey_ctx_init(struct pp_netkey_ctx *net) +static void pp_netkey_ctx_init(struct 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) +static uint8_t proxy_adv_type_get(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; + uint8_t type; + uint8_t len = buf->len; + + if (adv_type != BT_GAP_ADV_TYPE_ADV_IND || len < 12) { + return 0xFF; } - /* 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; + type = net_buf_simple_pull_u8(buf); + /* BEACON_TYPE_NET_ID is 20 bytes long, while the three other accepted types are 28 bytes*/ + if (len != ((type == BEACON_TYPE_NET_ID) ? 20 : 28)) { + return 0xFF; } - return true; + return type; } -static uint64_t pp_hash_calc(struct pp_netkey_ctx *net, uint64_t random, uint16_t *addr) +static uint64_t proxy_adv_hash_calc(struct netkey_ctx *net, uint64_t random, uint16_t *addr, + bool is_priv) { uint64_t hash; - uint8_t tmp[16] = {0, 0, 0, 0, 0, 3}; + uint8_t tmp[16] = {0}; + + tmp[5] = is_priv ? 3 : 0; if (addr) { memcpy(&tmp[6], &random, 8); @@ -1617,7 +1626,7 @@ 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)); + proxy_adv_hash_calc(&pp_net0, beacon.pp_random, test_ctx->node_id_addr, true)); if (memcmp(beacon.adv_addr.a.val, last_beacon_adv_addr.a.val, BT_ADDR_SIZE) == 0) { return false; @@ -1633,15 +1642,58 @@ static void priv_scan_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type { struct priv_test_ctx *ctx = (struct priv_test_ctx *)beacon.user_ctx; - if (!pp_type_check(ctx->beacon_type, adv_type, buf)) { + if (proxy_adv_type_get(adv_type, buf) != ctx->beacon_type) { /* 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 (ctx->beacon_type == BEACON_TYPE_NET_ID) { + beacon.net_id = net_buf_simple_pull_le64(buf); + } else { + 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); + } +} + +struct proxy_adv_beacon { + uint8_t evt_type; + uint8_t net_idx; + int64_t rx_timestamp; + union { + uint64_t net_id; + struct { + uint64_t hash; + uint64_t random; + } enc; + } ctx; +}; + +static void proxy_adv_scan_all_cb(const bt_addr_le_t *addr, int8_t rssi, uint8_t adv_type, + struct net_buf_simple *buf) +{ + struct proxy_adv_beacon *beac = (struct proxy_adv_beacon *)beacon.user_ctx; + + beac->evt_type = proxy_adv_type_get(adv_type, buf); + if (beac->evt_type == 0xFF) { + /* Not a related beacon type */ + return; + } + + bt_addr_le_copy(&beacon.adv_addr, addr); + beac->rx_timestamp = k_uptime_get(); + + if (beac->evt_type == BEACON_TYPE_NET_ID) { + beac->ctx.net_id = net_buf_simple_pull_le64(buf); + } else { + beac->ctx.enc.hash = net_buf_simple_pull_le64(buf); + beac->ctx.enc.random = net_buf_simple_pull_le64(buf); + } if (!beacon.process_cb || beacon.process_cb(NULL, beacon.user_ctx)) { k_sem_give(&observer_sem); @@ -1657,11 +1709,11 @@ static void rx_priv_common_init(uint16_t wait) ASSERT_OK_MSG(bt_enable(NULL), "Bluetooth init failed"); } -static void tx_priv_common_init(uint16_t wait) +static void tx_proxy_adv_common_init(uint16_t wait, const struct bt_mesh_test_cfg *cfg) { bt_mesh_test_cfg_set(NULL, wait); bt_mesh_device_setup(&prov, &prb_comp); - provision(&tx_cfg); + provision(cfg); /* Disable GATT proxy */ ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), @@ -1670,7 +1722,7 @@ static void tx_priv_common_init(uint16_t wait) static void test_tx_priv_net_id(void) { - tx_priv_common_init(PP_NET_ID_WAIT_TIME); + tx_proxy_adv_common_init(PP_NET_ID_WAIT_TIME, &tx_cfg); /* Enable private GATT proxy */ ASSERT_OK_MSG(bt_mesh_priv_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), @@ -1709,7 +1761,7 @@ static void test_tx_priv_node_id(void) { enum bt_mesh_feat_state state; - tx_priv_common_init(PP_NODE_ID_WAIT_TIME); + tx_proxy_adv_common_init(PP_NODE_ID_WAIT_TIME, &tx_cfg); /* Start first node advertisement */ ASSERT_OK_MSG(bt_mesh_subnet_priv_node_id_set(TEST_NET_IDX1, BT_MESH_NODE_IDENTITY_RUNNING), @@ -1762,16 +1814,10 @@ static void test_rx_priv_node_id(void) 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); + tx_proxy_adv_common_init(PP_MULT_NET_ID_WAIT_TIME, &tx_cfg); /* Add second network */ - ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_secondary), + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), "Failed to add second subnet"); /* Enable private GATT proxy */ @@ -1781,6 +1827,247 @@ static void test_tx_priv_multi_net_id(void) PASS(); } +static void proxy_adv_subnet_find(struct proxy_adv_beacon *beac, struct netkey_ctx **nets, + uint8_t net_cnt) +{ + for (size_t i = 0; i < net_cnt; i++) { + + switch (beac->evt_type) { + case BEACON_TYPE_NET_ID: + if (!memcmp(nets[i]->net_id, &beac->ctx.net_id, 8)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_NODE_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + (uint16_t *)&tx_cfg.addr, false)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_PRIVATE_NET_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + NULL, true)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + case BEACON_TYPE_PRIVATE_NODE_ID: + if (beac->ctx.enc.hash == + proxy_adv_hash_calc(nets[i], beac->ctx.enc.random, + (uint16_t *)&tx_cfg.addr, true)) { + beac->net_idx = nets[i]->net_idx; + return; + } + break; + + default: + FAIL("Unexpected beacon type"); + break; + } + } + + FAIL("Could not find matching subnet for incoming proxy adv beacon"); +} + +static const char *const proxy_adv_str[] = {"Net_ID", "Node_ID", "Priv_Net_ID", "Priv_Node_ID"}; +struct expected_proxy_adv_evt { + uint8_t evt_type; + uint8_t net_idx; + uint16_t evt_cnt; + struct { + int64_t after; + int64_t before; + } time; +}; + +static void proxy_adv_register_evt(struct proxy_adv_beacon *beac, + struct expected_proxy_adv_evt *exp_evts, uint8_t cnt) +{ + for (int i = 0; i < cnt; i++) { + if ((exp_evts[i].evt_cnt) && (beac->evt_type == exp_evts[i].evt_type) && + (beac->net_idx == exp_evts[i].net_idx) && + (beac->rx_timestamp >= exp_evts[i].time.after) && + (beac->rx_timestamp <= exp_evts[i].time.before)) { + exp_evts[i].evt_cnt--; + } + } +} + +static void proxy_adv_confirm_evt(struct expected_proxy_adv_evt *exp_evts, uint8_t cnt) +{ + bool missing_evts = false; + + for (int i = 0; i < cnt; i++) { + if (exp_evts[i].evt_cnt) { + LOG_ERR("Missing %d expected %s idx %d events in period %llums-%llums", + exp_evts[i].evt_cnt, proxy_adv_str[exp_evts[i].evt_type], + exp_evts[i].net_idx, exp_evts[i].time.after, + exp_evts[i].time.before); + missing_evts = true; + } + } + + if (missing_evts) { + FAIL("Test failed due to missing events"); + } +} + +static void proxy_adv_scan_all(struct netkey_ctx **nets, uint16_t net_cnt, + struct expected_proxy_adv_evt *exp_evt, uint16_t exp_evt_cnt, + int64_t timeout) +{ + struct proxy_adv_beacon beac; + + while (k_uptime_get() < timeout) { + + ASSERT_TRUE(wait_for_beacon(proxy_adv_scan_all_cb, 2, NULL, &beac)); + proxy_adv_subnet_find(&beac, nets, net_cnt); + proxy_adv_register_evt(&beac, exp_evt, exp_evt_cnt); + + /** We want to monitor an even distribution of adv events. + * To ensure this, we wait a little less than the minimum + * proxy adv period (1 second) before scanning for the next + * evt. + */ + k_sleep(K_MSEC(990)); + } + + proxy_adv_confirm_evt(exp_evt, exp_evt_cnt); +} + +#define PROXY_ADV_MULTI_CHECKPOINT_1 20000 +#define PROXY_ADV_MULTI_CHECKPOINT_2 50000 +#define PROXY_ADV_MULTI_CHECKPOINT_3 110000 +#define PROXY_ADV_MULTI_CHECKPOINT_4 130000 +#define PROXY_ADV_MULTI_CHECKPOINT_END 150000 + +static void test_tx_proxy_adv_multi_subnet_coex(void) +{ + tx_proxy_adv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME, &tx_cfg); + + /* Enable GATT proxy */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to Enable gatt proxy"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_1)); + /* Add second and third network */ + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), + "Failed to add second subnet"); + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX3, test_net_key_3), + "Failed to add third subnet"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_2)); + /* Start Node Identity on second network */ + bt_mesh_proxy_identity_start(bt_mesh_subnet_get(TEST_NET_IDX2), false); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_3)); + /* Prepare for solicitation */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_DISABLED), + "Failed to Enable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_od_priv_proxy_set(20), "Failed to set OD priv proxy state"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_4)); + /* Re-enable GATT proxy and remove second and third network */ + ASSERT_OK_MSG(bt_mesh_gatt_proxy_set(BT_MESH_GATT_PROXY_ENABLED), + "Failed to Enable gatt proxy"); + ASSERT_OK_MSG(bt_mesh_subnet_del(TEST_NET_IDX2), "Failed to delete subnet"); + ASSERT_OK_MSG(bt_mesh_subnet_del(TEST_NET_IDX3), "Failed to delete subnet"); + + PASS(); +} + +static const struct bt_mesh_test_cfg solicit_trigger_cfg = { + .addr = 0x0003, + .dev_key = { 0x03 }, +}; + +static void test_tx_proxy_adv_solicit_trigger(void) +{ + tx_proxy_adv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME, &solicit_trigger_cfg); + ASSERT_OK_MSG(bt_mesh_subnet_add(TEST_NET_IDX2, test_net_key_2), + "Failed to add second subnet"); + + k_sleep(UNTIL_UPTIME(PROXY_ADV_MULTI_CHECKPOINT_3)); + + /* Solicit first and second network */ + ASSERT_OK_MSG(bt_mesh_proxy_solicit(TEST_NET_IDX1), + "Failed to start solicitation"); + ASSERT_OK_MSG(bt_mesh_proxy_solicit(TEST_NET_IDX2), + "Failed to start solicitation"); + + PASS(); +} + +static void test_rx_proxy_adv_multi_subnet_coex(void) +{ + rx_priv_common_init(PROXY_ADV_MULTI_SUBNET_COEX_WAIT_TIME); + pp_netkey_ctx_init(&pp_net1); + pp_netkey_ctx_init(&pp_net2); + + struct netkey_ctx *nets[] = {&pp_net0, &pp_net1, &pp_net2}; + struct expected_proxy_adv_evt exp_evt[] = { + /** A single subnet is active on the device with GATT Proxy + * enabled. Verify that the single subnet has exclusive + * access to the adv medium. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 19, + .time = {.after = 0, .before = PROXY_ADV_MULTI_CHECKPOINT_1}}, + + /** Two additional subnets are added to the device. + * Check that the subnets are sharing the adv medium, + * advertising NET_ID beacons. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 1, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 2, .evt_cnt = 8, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_1, + .before = PROXY_ADV_MULTI_CHECKPOINT_2}}, + + /** The second subnet enables Node Identity. Check that NODE_ID + * is advertised by this subnet, and that the two others + * continues to advertise NET_ID. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 16, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + {.evt_type = BEACON_TYPE_NODE_ID, .net_idx = 1, .evt_cnt = 16, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 2, .evt_cnt = 16, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_2, + .before = PROXY_ADV_MULTI_CHECKPOINT_3}}, + + /** The first and second subnet gets solicited. Check that + * PRIVATE_NET_ID is advertised by these subnet, + */ + {.evt_type = BEACON_TYPE_PRIVATE_NET_ID, .net_idx = 0, .evt_cnt = 9, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_3, + .before = PROXY_ADV_MULTI_CHECKPOINT_4}}, + {.evt_type = BEACON_TYPE_PRIVATE_NET_ID, .net_idx = 1, .evt_cnt = 9, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_3, + .before = PROXY_ADV_MULTI_CHECKPOINT_4}}, + + /** Second and third subnet are disabled. Verify that the single + * subnet has exclusive access to the adv medium. + */ + {.evt_type = BEACON_TYPE_NET_ID, .net_idx = 0, .evt_cnt = 19, + .time = {.after = PROXY_ADV_MULTI_CHECKPOINT_4, + .before = PROXY_ADV_MULTI_CHECKPOINT_END}}, + }; + + proxy_adv_scan_all(nets, ARRAY_SIZE(nets), exp_evt, ARRAY_SIZE(exp_evt), + PROXY_ADV_MULTI_CHECKPOINT_END); + PASS(); +} + static void test_rx_priv_multi_net_id(void) { rx_priv_common_init(PP_MULT_NET_ID_WAIT_TIME); @@ -1794,7 +2081,7 @@ static void test_rx_priv_multi_net_id(void) uint16_t itr = 4; static uint8_t old_idx = 0xff; static struct { - struct pp_netkey_ctx *net; + struct netkey_ctx *net; uint16_t recv_cnt; int64_t start; } net_ctx[2] = { @@ -1809,7 +2096,7 @@ static void test_rx_priv_multi_net_id(void) 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)) { + proxy_adv_hash_calc(net_ctx[i].net, beacon.pp_random, NULL, true)) { if (old_idx == 0xff) { /* Received first Net ID advertisment */ old_idx = i; @@ -1820,8 +2107,8 @@ static void test_rx_priv_multi_net_id(void) /* 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); + MAX_TIMEOUT - 1000, MAX_TIMEOUT + 1000); + ASSERT_IN_RANGE(net_ctx[old_idx].recv_cnt, 9, 12); net_ctx[old_idx].recv_cnt = 0; old_idx = i; @@ -1906,8 +2193,6 @@ static void test_rx_priv_gatt_proxy(void) #endif -#endif /* CONFIG_BT_MESH_V1d1 */ - #define TEST_CASE(role, name, description) \ { \ .test_id = "beacon_" #role "_" #name, \ @@ -1926,7 +2211,6 @@ static const struct bst_test_instance test_beacon[] = { 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"), TEST_CASE(tx, priv_adv, "Private Beacon: advertise Private Beacons"), @@ -1938,7 +2222,8 @@ static const struct bst_test_instance test_beacon[] = { 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 + TEST_CASE(tx, proxy_adv_multi_subnet_coex, "Proxy Adv: Multi subnet coex proxy adv"), + TEST_CASE(tx, proxy_adv_solicit_trigger, "Proxy Adv: Trigger Solicitation"), #endif TEST_CASE(rx, on_iv_update, "Beacon: receive with IV update flag"), @@ -1948,7 +2233,6 @@ static const struct bst_test_instance test_beacon[] = { 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"), TEST_CASE(rx, priv_interleave, "Private Beacon: interleaved with SNB"), @@ -1958,7 +2242,7 @@ static const struct bst_test_instance test_beacon[] = { 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 + TEST_CASE(rx, proxy_adv_multi_subnet_coex, "Proxy Adv: Multi subnet coex proxy adv"), #endif BSTEST_END_MARKER }; diff --git a/tests/bsim/bluetooth/mesh/src/test_blob.c b/tests/bsim/bluetooth/mesh/src/test_blob.c index 4258ff77c62..0d3a69da2fc 100644 --- a/tests/bsim/bluetooth/mesh/src/test_blob.c +++ b/tests/bsim/bluetooth/mesh/src/test_blob.c @@ -6,9 +6,9 @@ #include "mesh_test.h" #include "dfu_blob_common.h" #include "friendship_common.h" +#include "mesh/adv.h" #include "mesh/blob.h" #include "argparse.h" -#include "mesh/adv.h" #define LOG_MODULE_NAME test_blob diff --git a/tests/bsim/bluetooth/mesh/src/test_dfu.c b/tests/bsim/bluetooth/mesh/src/test_dfu.c index 06f7248a6ad..1b54e873cc5 100644 --- a/tests/bsim/bluetooth/mesh/src/test_dfu.c +++ b/tests/bsim/bluetooth/mesh/src/test_dfu.c @@ -6,7 +6,6 @@ #include "mesh_test.h" #include "mesh/dfd_srv_internal.h" #include "mesh/dfu_slot.h" -#include "mesh/adv.h" #include "mesh/dfu.h" #include "mesh/blob.h" #include "argparse.h" diff --git a/tests/bsim/bluetooth/mesh/src/test_provision.c b/tests/bsim/bluetooth/mesh/src/test_provision.c index f2c98778a3b..789de47837b 100644 --- a/tests/bsim/bluetooth/mesh/src/test_provision.c +++ b/tests/bsim/bluetooth/mesh/src/test_provision.c @@ -28,7 +28,6 @@ #define LOG_MODULE_NAME mesh_prov #include -#include "mesh/adv.h" #include "mesh/rpr.h" LOG_MODULE_REGISTER(LOG_MODULE_NAME); @@ -53,11 +52,9 @@ enum test_flags { static uint8_t static_key1[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F, 0x65, 0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31}; static uint8_t static_key2[] = {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F}; -#if IS_ENABLED(CONFIG_BT_MESH_V1d1) static uint8_t static_key3[] = {0x45, 0x6E, 0x68, 0x61, 0x6E, 0x63, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6F, 0x76, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x20, 0x4F, 0x4F, 0x42}; -#endif static uint8_t private_key_be[32]; static uint8_t public_key_be[64]; @@ -73,9 +70,7 @@ static struct oob_auth_test_vector_s { {NULL, 0, 0, 0, 0, 0}, {static_key1, sizeof(static_key1), 0, 0, 0, 0}, {static_key2, sizeof(static_key2), 0, 0, 0, 0}, -#if IS_ENABLED(CONFIG_BT_MESH_V1d1) {static_key3, sizeof(static_key3), 0, 0, 0, 0}, -#endif {NULL, 0, 3, BT_MESH_BLINK, 0, 0}, {NULL, 0, 5, BT_MESH_BEEP, 0, 0}, {NULL, 0, 6, BT_MESH_VIBRATE, 0, 0}, diff --git a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c index 68dc52a7b5d..57d605fb97a 100644 --- a/tests/bsim/bluetooth/mesh/src/test_replay_cache.c +++ b/tests/bsim/bluetooth/mesh/src/test_replay_cache.c @@ -78,7 +78,6 @@ static void rx_ended(uint8_t *data, size_t len) static void tx_sar_conf(void) { -#ifdef CONFIG_BT_MESH_V1d1 /* Reconfigure SAR Transmitter state so that the transport layer doesn't * retransmit. */ @@ -97,12 +96,10 @@ static void tx_sar_conf(void) #else bt_mesh.sar_tx = tx_set; #endif -#endif } static void rx_sar_conf(void) { -#ifdef CONFIG_BT_MESH_V1d1 /* Reconfigure SAR Receiver state so that the transport layer does * generate Segmented Acks as rarely as possible. */ @@ -119,7 +116,6 @@ static void rx_sar_conf(void) #else bt_mesh.sar_rx = rx_set; #endif -#endif } static void test_tx_immediate_replay_attack(void) diff --git a/tests/bsim/bluetooth/mesh/src/test_scanner.c b/tests/bsim/bluetooth/mesh/src/test_scanner.c index 12557b7e1b2..a63284701df 100644 --- a/tests/bsim/bluetooth/mesh/src/test_scanner.c +++ b/tests/bsim/bluetooth/mesh/src/test_scanner.c @@ -6,7 +6,6 @@ #include #include "mesh_test.h" #include "mesh/net.h" -#include "mesh/adv.h" #include "mesh/mesh.h" #include "mesh/foundation.h" diff --git a/tests/bsim/bluetooth/mesh/src/test_transport.c b/tests/bsim/bluetooth/mesh/src/test_transport.c index 05026f6dcf7..309681ceafe 100644 --- a/tests/bsim/bluetooth/mesh/src/test_transport.c +++ b/tests/bsim/bluetooth/mesh/src/test_transport.c @@ -94,7 +94,6 @@ static void async_send_end(int err, void *data) static void rx_sar_conf(void) { -#ifdef CONFIG_BT_MESH_V1d1 /* Reconfigure SAR Receiver state so that the transport layer does * generate Segmented Acks as rarely as possible. */ @@ -111,7 +110,6 @@ static void rx_sar_conf(void) #else bt_mesh.sar_rx = rx_set; #endif -#endif } static const struct bt_mesh_send_cb async_send_cb = { diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_cancel.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_cancel.sh index 6a56a084c60..85b76062b60 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_cancel.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_cancel.sh @@ -7,11 +7,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_access_publication_cancel \ access_tx_cancel access_rx_cancel -conf=prj_mesh1d1_conf -RunTest mesh_access_publication_cancel_1d1 \ - access_tx_cancel access_rx_cancel - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_access_publication_cancel_psa \ access_tx_cancel access_rx_cancel diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub.sh index 862291b4c76..66caf516bb2 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub.sh @@ -7,11 +7,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_access_extended_model_subs \ access_tx_ext_model access_sub_ext_model -conf=prj_mesh1d1_conf -RunTest mesh_access_extended_model_subs_1d1 \ - access_tx_ext_model access_sub_ext_model - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_access_extended_model_subs_psa \ access_tx_ext_model access_sub_ext_model diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub_cap.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub_cap.sh index 2a4f9ccc247..91576f34aa0 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub_cap.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_ext_sub_cap.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_access_extended_model_subs_cap access_sub_capacity_ext_model -conf=prj_mesh1d1_conf -RunTest mesh_access_extended_model_subs_cap_1d1 access_sub_capacity_ext_model - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_access_extended_model_subs_cap_psa access_sub_capacity_ext_model diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period.sh index d2bb07c6de7..f2e72085ac7 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period.sh @@ -7,11 +7,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_access_per_pub \ access_tx_period access_rx_period -conf=prj_mesh1d1_conf -RunTest mesh_access_per_pub_1d1 \ - access_tx_period access_rx_period - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_access_per_pub_psa \ access_tx_period access_rx_period diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh new file mode 100755 index 00000000000..0148026fc6f --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_period_delayable.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +RunTest mesh_access_pub_period_delayable_retr \ + access_tx_period_delayable access_rx_period_delayable + +overlay=overlay_psa_conf +RunTest mesh_access_pub_period_delayable_retr_psa \ + access_tx_period_delayable access_rx_period_delayable diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit.sh index c2f4a27ddbd..0a0ec47da15 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit.sh @@ -7,11 +7,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_access_pub_retr \ access_tx_transmit access_rx_transmit -conf=prj_mesh1d1_conf -RunTest mesh_access_pub_retr_1d1 \ - access_tx_transmit access_rx_transmit - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_access_pub_retr_psa \ access_tx_period access_rx_period diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh new file mode 100755 index 00000000000..2dba89f2d76 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/access/access_transmit_delayable.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +RunTest mesh_access_pub_transmit_delayable_retr \ + access_tx_transmit_delayable access_rx_transmit_delayable + +overlay=overlay_psa_conf +RunTest mesh_access_pub_transmit_delayable_retr_psa \ + access_tx_transmit_delayable access_rx_transmit_delayable diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/proxy_mixin.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/proxy_mixin.sh index 86255277277..6c49d03fe9f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/proxy_mixin.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/proxy_mixin.sh @@ -21,10 +21,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh overlay=overlay_gatt_conf RunTest mesh_adv_proxy_mixin adv_tx_proxy_mixin adv_rx_proxy_mixin -conf=prj_mesh1d1_conf -overlay=overlay_gatt_conf -RunTest mesh_adv_proxy_mixin_1d1 adv_tx_proxy_mixin adv_rx_proxy_mixin - -conf=prj_mesh1d1_conf overlay="overlay_gatt_conf_overlay_psa_conf" RunTest mesh_adv_proxy_mixin_psa adv_tx_proxy_mixin adv_rx_proxy_mixin diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/random_order.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/random_order.sh index 8cfe0f9366a..a171ffd60f3 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/random_order.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/random_order.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test buffer management by filling buffers and sending them in random order. RunTest mesh_adv_random_order adv_tx_random_order adv_rx_random_order -conf=prj_mesh1d1_conf -RunTest mesh_adv_random_order_1d1 adv_tx_random_order adv_rx_random_order - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_adv_random_order_psa adv_tx_random_order adv_rx_random_order diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/reverse_order.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/reverse_order.sh index 96b30394f12..2b047138109 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/reverse_order.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/reverse_order.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test buffer management by filling all the buffer and sending them in reversed order. RunTest mesh_adv_reverse_order adv_tx_reverse_order adv_rx_receive_order -conf=prj_mesh1d1_conf -RunTest mesh_adv_reverse_order_1d1 adv_tx_reverse_order adv_rx_receive_order - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_adv_reverse_order_psa adv_tx_reverse_order adv_rx_receive_order diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/send_order.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/send_order.sh index e208bf54579..a9e8d1ea861 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/send_order.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/send_order.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test buffer management by filling all the buffer and sending them all in order. RunTest mesh_adv_send_order adv_tx_send_order adv_rx_receive_order -conf=prj_mesh1d1_conf -RunTest mesh_adv_send_order_1d1 adv_tx_send_order adv_rx_receive_order - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_adv_send_order_psa adv_tx_send_order adv_rx_receive_order diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_multi.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_multi.sh index 28827c872f8..4ca2838ddf9 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_multi.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_multi.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test tx callbacks sequence for multiple advs RunTest mesh_adv_tx_cb_multi adv_tx_cb_multi -conf=prj_mesh1d1_conf -RunTest mesh_adv_tx_cb_multi_1d1 adv_tx_cb_multi - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_adv_tx_cb_multi_psa adv_tx_cb_multi diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_single.sh b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_single.sh index edf4ba0996b..a2b1ad0e961 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_single.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/advertiser/tx_cb_single.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test tx callbacks parameters and xmit sequence for single adv RunTest mesh_adv_tx_cb_single adv_tx_cb_single adv_rx_xmit -conf=prj_mesh1d1_conf -RunTest mesh_adv_tx_cb_single_1d1 adv_tx_cb_single adv_rx_xmit - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_adv_tx_cb_single_psa adv_tx_cb_single adv_rx_xmit diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh index c0f741e9aae..ab43e2b74db 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_cache.sh @@ -15,12 +15,6 @@ 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 \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_interval.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_interval.sh index ec70eb2f02c..a671c90d668 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_interval.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/beacon_interval.sh @@ -22,12 +22,6 @@ RunTest mesh_beacon_interval \ beacon_tx_secure_beacon_interval \ beacon_rx_secure_beacon_interval -conf=prj_mesh1d1_conf -RunTest mesh_beacon_interval_1d1 \ - beacon_tx_secure_beacon_interval \ - beacon_rx_secure_beacon_interval - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_interval_psa \ beacon_tx_secure_beacon_interval \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/invalid.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/invalid.sh index ccce8c3a1f5..96d5b0a0f6b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/invalid.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/invalid.sh @@ -8,12 +8,6 @@ RunTest mesh_beacon_invalid \ beacon_tx_invalid \ beacon_rx_invalid -conf=prj_mesh1d1_conf -RunTest mesh_beacon_invalid_1d1 \ - beacon_tx_invalid \ - beacon_rx_invalid - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_invalid_psa \ beacon_tx_invalid \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/iv_update.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/iv_update.sh index 64225fd9cf5..d719aef86bc 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/iv_update.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/iv_update.sh @@ -8,12 +8,6 @@ RunTest mesh_beacon_on_iv_update \ beacon_tx_on_iv_update \ beacon_rx_on_iv_update -conf=prj_mesh1d1_conf -RunTest mesh_beacon_on_iv_update_1d1 \ - beacon_tx_on_iv_update \ - beacon_rx_on_iv_update - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_on_iv_update_psa \ beacon_tx_on_iv_update \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/key_refresh.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/key_refresh.sh index 00f82704718..9223d7d1d29 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/key_refresh.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/key_refresh.sh @@ -8,12 +8,6 @@ RunTest mesh_beacon_on_key_refresh \ beacon_tx_on_key_refresh \ beacon_rx_on_key_refresh -conf=prj_mesh1d1_conf -RunTest mesh_beacon_on_key_refresh_1d1 \ - beacon_tx_on_key_refresh \ - beacon_rx_on_key_refresh - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_on_key_refresh_psa \ beacon_tx_on_key_refresh \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/kr_old_key.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/kr_old_key.sh index 3d6b151a068..ecd83e415a9 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/kr_old_key.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/kr_old_key.sh @@ -8,12 +8,6 @@ RunTest mesh_beacon_kr_old_key \ beacon_tx_kr_old_key \ beacon_rx_kr_old_key -conf=prj_mesh1d1_conf -RunTest mesh_beacon_kr_old_key_1d1 \ - beacon_tx_kr_old_key \ - beacon_rx_kr_old_key - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_kr_old_key_psa \ beacon_tx_kr_old_key \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/multiple_netkeys.sh b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/multiple_netkeys.sh index 677e4227669..a8c154f5204 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/beacon/multiple_netkeys.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/beacon/multiple_netkeys.sh @@ -8,12 +8,6 @@ RunTest mesh_beacon_multiple_netkeys \ beacon_tx_multiple_netkeys \ beacon_rx_multiple_netkeys -conf=prj_mesh1d1_conf -RunTest mesh_beacon_multiple_netkeys_1d1 \ - beacon_tx_multiple_netkeys \ - beacon_rx_multiple_netkeys - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_beacon_multiple_netkeys_psa \ beacon_tx_multiple_netkeys \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_basic.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_basic.sh index 6f1ec61ad27..d8665ac4cfd 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_basic.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_basic.sh @@ -4,9 +4,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_broadcast_basic blob_cli_broadcast_basic -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_broadcast_basic_psa blob_cli_broadcast_basic diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_trans.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_trans.sh index d5d0f60d1ce..25198e70a38 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_trans.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_trans.sh @@ -4,9 +4,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_broadcast_trans blob_cli_broadcast_trans -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_broadcast_trans_psa blob_cli_broadcast_trans diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast.sh index ee86ce33cfa..654753e2188 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast.sh @@ -4,9 +4,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_broadcast_unicast blob_cli_broadcast_unicast -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_broadcast_unicast_psa blob_cli_broadcast_unicast diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast_seq.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast_seq.sh index c356122145c..cb569fdc3b4 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast_seq.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_broadcast_unicast_seq.sh @@ -4,9 +4,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_broadcast_unicast_seq blob_cli_broadcast_unicast_seq -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_broadcast_unicast_seq_psa blob_cli_broadcast_unicast_seq diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_all_rsp.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_all_rsp.sh index bc2aa351987..d7f54a34d22 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_all_rsp.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_all_rsp.sh @@ -5,11 +5,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf RunTest blob_caps_all_rsp \ blob_cli_caps_all_rsp blob_srv_caps_standard blob_srv_caps_standard -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_caps_all_rsp_psa \ blob_cli_caps_all_rsp blob_srv_caps_standard blob_srv_caps_standard diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_cancelled.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_cancelled.sh index 3e1bd343a70..e287dcbd9fc 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_cancelled.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_cancelled.sh @@ -5,11 +5,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance seqence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf RunTest blob_caps_cancelled \ blob_cli_caps_cancelled blob_srv_caps_standard -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_caps_cancelled_psa \ blob_cli_caps_cancelled blob_srv_caps_standard diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_no_rsp.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_no_rsp.sh index e53864f8be4..e5ee44b5a08 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_no_rsp.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_no_rsp.sh @@ -5,11 +5,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf RunTest blob_caps_no_rsp \ blob_cli_caps_no_rsp blob_srv_caps_no_rsp blob_srv_caps_no_rsp -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_caps_no_rsp_psa \ blob_cli_caps_no_rsp blob_srv_caps_no_rsp blob_srv_caps_no_rsp diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_partial_rsp.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_partial_rsp.sh index 9a1675bd279..2da51b0e37e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_partial_rsp.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_caps_partial_rsp.sh @@ -5,11 +5,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf RunTest blob_caps_partial_rsp \ blob_cli_caps_partial_rsp blob_srv_caps_standard blob_srv_caps_no_rsp -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_caps_partial_rsp_psa \ blob_cli_caps_partial_rsp blob_srv_caps_standard blob_srv_caps_no_rsp diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_friend.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_friend.sh index 1c2bde7a109..0e82cf8df11 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_friend.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_friend.sh @@ -7,7 +7,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Establish multiple different friendships concurrently. Perform BLOB transfer with BLOB Client # on friend node and BLOB Server on LPNs. # Note: The number of LPNs must match CONFIG_BT_MESH_FRIEND_LPN_COUNT. -conf=prj_mesh1d1_conf RunTest blob_transfer_lpn \ blob_cli_friend_pull \ blob_srv_lpn_pull \ @@ -16,7 +15,6 @@ RunTest blob_transfer_lpn \ blob_srv_lpn_pull \ blob_srv_lpn_pull -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_transfer_lpn_psa \ blob_cli_friend_pull \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_block.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_block.sh index 73728d1f141..a30a54f79ff 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_block.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_block.sh @@ -4,13 +4,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_no_rsp_block_get \ blob_cli_fail_on_no_rsp \ blob_srv_fail_on_block_get \ blob_srv_fail_on_block_get -- -argstest msg-fail-type=0 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_no_rsp_block_get_psa \ blob_cli_fail_on_no_rsp \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_xfer.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_xfer.sh index 4137deba007..4ecc650aa8f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_xfer.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_no_rsp_xfer.sh @@ -4,13 +4,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf RunTest blob_no_rsp_xfer_get \ blob_cli_fail_on_no_rsp \ blob_srv_fail_on_xfer_get \ blob_srv_fail_on_xfer_get -- -argstest msg-fail-type=1 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_no_rsp_xfer_get_psa \ blob_cli_fail_on_no_rsp \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer.sh index e5bb421af14..a7cfdac206d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer.sh @@ -5,7 +5,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf RunTest blob_fail \ blob_cli_fail_on_persistency \ blob_srv_fail_on_block_start\ @@ -13,7 +12,6 @@ RunTest blob_fail \ blob_srv_fail_on_xfer_get \ blob_srv_fail_on_nothing -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_fail_psa \ blob_cli_fail_on_persistency \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer_pull.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer_pull.sh index 8ead73c4ec7..11bafde8fbc 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer_pull.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_persistent_transfer_pull.sh @@ -5,13 +5,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that BLOB Client continues BLOB Transfer after one target timed out while sending chunks. -conf=prj_mesh1d1_conf RunTest blob_pst_pull \ blob_cli_trans_persistency_pull \ blob_srv_trans_persistency_pull \ blob_srv_trans_persistency_pull -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_pst_pull_psa \ blob_cli_trans_persistency_pull \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_pull.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_pull.sh index fdb1a8020e1..2e89819bb1f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_pull.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_pull.sh @@ -5,13 +5,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that BLOB Transfer completes successfully in Pull mode -conf=prj_mesh1d1_conf RunTest blob_success_pull blob_cli_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete \ -- -argstest use-pull-mode=1 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_success_pull_psa blob_cli_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_push.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_push.sh index 5345eab11e8..9695d1bb941 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_push.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_complete_push.sh @@ -5,12 +5,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that BLOB Transfer completes successfully in Push mode -conf=prj_mesh1d1_conf RunTest blob_success_push blob_cli_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_success_push_psa blob_cli_trans_complete \ blob_srv_trans_complete blob_srv_trans_complete \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_pull.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_pull.sh index 5b05446694b..4459c4419b4 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_pull.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_pull.sh @@ -5,11 +5,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that BLOB Client can resume a suspended BLOB Transfer in Pull mode -conf=prj_mesh1d1_conf RunTest blob_resume_pull \ blob_cli_trans_resume blob_srv_trans_resume -- -argstest use-pull-mode=1 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_resume_pull_psa \ blob_cli_trans_resume blob_srv_trans_resume -- -argstest use-pull-mode=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_push.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_push.sh index 01150c8b0eb..2bbc627b05c 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_push.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_cli_trans_resume_push.sh @@ -5,9 +5,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that BLOB Client can resume a suspended BLOB Transfer in Push mode -conf=prj_mesh1d1_conf RunTest blob_resume_push blob_cli_trans_resume blob_srv_trans_resume -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest blob_resume_push_psa blob_cli_trans_resume blob_srv_trans_resume diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_srv_persistence.sh b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_srv_persistence.sh index 8c59c82da6f..9973a82dc49 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_srv_persistence.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/blob_mdls/blob_srv_persistence.sh @@ -10,65 +10,53 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Tests with -flash_rm clean up stored settings after them # to run tests with -flash_erase correctly. # Test cases are designed to be run using single target. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop -flash_erase blob_srv_stop -flash_erase -- -argstest expected-phase=1 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop blob_srv_stop -- -argstest expected-phase=2 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop blob_srv_stop -- -argstest expected-phase=3 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop -flash_rm blob_srv_stop -flash_rm -- -argstest expected-phase=4 # Test reaching suspended state and continuation after reboot on new procedure. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop -flash_erase blob_srv_stop -flash_erase -- -argstest expected-phase=5 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash blob_recover_phase \ blob_cli_stop -flash_rm blob_srv_stop -flash_rm -- -argstest expected-phase=4 # The same test but with PSA crypto -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop -flash_erase blob_srv_stop -flash_erase -- -argstest expected-phase=1 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop blob_srv_stop -- -argstest expected-phase=2 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop blob_srv_stop -- -argstest expected-phase=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop -flash_rm blob_srv_stop -flash_rm -- -argstest expected-phase=4 # Test reaching suspended state and continuation after reboot on new procedure. -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop -flash_erase blob_srv_stop -flash_erase -- -argstest expected-phase=5 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash blob_recover_phase_psa \ blob_cli_stop -flash_rm blob_srv_stop -flash_rm -- -argstest expected-phase=4 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 index e4f99e80d5d..d2a3c5de696 100755 --- 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 @@ -13,11 +13,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_apply.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_apply.sh index f612119bdee..4f87fb10fef 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_apply.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_apply.sh @@ -8,7 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # callback is called when all targets are lost at this step. # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_all_tgts_lost_on_apply \ dfu_cli_all_targets_lost_on_apply \ @@ -17,7 +16,6 @@ RunTest dfu_all_tgts_lost_on_apply \ dfu_target_fail_on_apply \ -- -argstest targets=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_all_tgts_lost_on_apply_psa \ dfu_cli_all_targets_lost_on_apply \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_caps_get.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_caps_get.sh index 36dcf8f24ae..572445e4779 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_caps_get.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_caps_get.sh @@ -8,7 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # and `ended` callback is called when all targets are lost at this step. # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_all_tgts_lost_on_caps_get \ dfu_cli_all_targets_lost_on_caps_get \ @@ -17,7 +16,6 @@ RunTest dfu_all_tgts_lost_on_caps_get \ dfu_target_fail_on_caps_get \ -- -argstest targets=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_all_tgts_lost_on_caps_get_psa \ dfu_cli_all_targets_lost_on_caps_get \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_metadata.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_metadata.sh index eacb921a214..e4fbe146dcd 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_metadata.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_metadata.sh @@ -8,7 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # called when all targets are lost at this step. # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_all_tgts_lost_on_metadata \ dfu_cli_all_targets_lost_on_metadata \ @@ -17,7 +16,6 @@ RunTest dfu_all_tgts_lost_on_metadata \ dfu_target_fail_on_metadata \ -- -argstest targets=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_all_tgts_lost_on_metadata_psa \ dfu_cli_all_targets_lost_on_metadata \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_update_get.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_update_get.sh index f6c53482834..7b96161eccd 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_update_get.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_update_get.sh @@ -8,7 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Firmware Update Get message and `ended` callback is called when all targets are lost at this step. # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_all_tgts_lost_on_update_get \ dfu_cli_all_targets_lost_on_update_get \ @@ -17,7 +16,6 @@ RunTest dfu_all_tgts_lost_on_update_get \ dfu_target_fail_on_update_get \ -- -argstest targets=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_all_tgts_lost_on_update_get_psa \ dfu_cli_all_targets_lost_on_update_get \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_verify.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_verify.sh index 929ab93b81e..5daedaca71d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_verify.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_all_targets_lost_on_verify.sh @@ -8,7 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # callback is called when all targets are lost at this step. # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_all_tgts_lost_on_verify \ dfu_cli_all_targets_lost_on_verify \ @@ -17,7 +16,6 @@ RunTest dfu_all_tgts_lost_on_verify \ dfu_target_fail_on_verify \ -- -argstest targets=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_all_tgts_lost_on_verify_psa \ dfu_cli_all_targets_lost_on_verify \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_persistent_transfer.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_persistent_transfer.sh index bcc98df48b5..2ff4a696639 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_persistent_transfer.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_cli_persistent_transfer.sh @@ -5,7 +5,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # The test instance sequence must stay as it is due to addressing scheme -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_persistency \ dfu_cli_fail_on_persistency \ @@ -16,7 +15,6 @@ RunTest dfu_persistency \ dfu_target_fail_on_apply \ dfu_target_fail_on_nothing -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_persistency_psa \ dfu_cli_fail_on_persistency \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update.sh index 64f33013e74..5c00349f24e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update.sh @@ -4,10 +4,8 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_self_update dfu_dist_dfu_self_update -- -argstest targets=1 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_self_update_psa dfu_dist_dfu_self_update -- -argstest targets=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update_mult_targets.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update_mult_targets.sh index af7acb10723..42087f1ad13 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update_mult_targets.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_dist_self_update_mult_targets.sh @@ -4,12 +4,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_self_update_no_change \ dfu_dist_dfu_self_update dfu_target_dfu_no_change -- -argstest targets=2 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_self_update_no_change_psa \ dfu_dist_dfu_self_update dfu_target_dfu_no_change -- -argstest targets=2 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed.sh index bcac2cbba5b..1c5ff82d8fb 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed.sh @@ -5,12 +5,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test DFU with all variants of firmware effect -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_mixed dfu_dist_dfu dfu_target_dfu_unprov dfu_target_dfu_no_change \ dfu_target_dfu_new_comp_rpr dfu_target_dfu_new_comp_no_rpr -- -argstest targets=4 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_mixed_psa dfu_dist_dfu dfu_target_dfu_unprov dfu_target_dfu_no_change \ dfu_target_dfu_new_comp_rpr dfu_target_dfu_new_comp_no_rpr -- -argstest targets=4 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed_fail.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed_fail.sh index c5f67e2521e..3382e458b2e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed_fail.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_mixed_fail.sh @@ -5,13 +5,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test that confirm step fails with all variants of firmware effect -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTest dfu_mixed_fail dfu_dist_dfu dfu_target_dfu_unprov dfu_target_dfu_no_change \ dfu_target_dfu_new_comp_rpr dfu_target_dfu_new_comp_no_rpr -- -argstest targets=4 \ fail-confirm=1 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest dfu_mixed_fail_psa dfu_dist_dfu dfu_target_dfu_unprov dfu_target_dfu_no_change \ dfu_target_dfu_new_comp_rpr dfu_target_dfu_new_comp_no_rpr -- -argstest targets=4 \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot.sh index c187d8cfbff..587908c6497 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot.sh @@ -11,7 +11,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # and verifies they do not exist. # - Fourth test is rebooted device that verifies if removing all slots also removed them # from storage. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_slot dfu_dist_dfu_slot_create -flash_erase @@ -21,7 +20,6 @@ RunTestFlash dfu_slot dfu_dist_dfu_slot_delete_all RunTestFlash dfu_slot dfu_dist_dfu_slot_check_delete_all -flash_rm -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_slot_psa dfu_dist_dfu_slot_create -flash_erase 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 index 3f18f1a2651..abce47dba13 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_idempotency.sh @@ -5,10 +5,8 @@ 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 index ddd7d0123f5..0ce234116b2 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_slot_reservation.sh @@ -5,10 +5,8 @@ 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 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_srv_persistence.sh b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_srv_persistence.sh index 6ed7099c987..b18a949b43d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_srv_persistence.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/dfu/dfu_srv_persistence.sh @@ -13,32 +13,27 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # image index were loaded correctly. # Test cases are designed to be run using single target. `dfu_cli_stop` test case in recovery part # plays dummy role, and is there to keep order of settings files being loaded. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop -flash_erase dfu_target_dfu_stop -flash_erase \ -- -argstest recover=0 expected-phase=2 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=3 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=4 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=6 # Use phase `BT_MESH_DFU_PHASE_APPLY_SUCCESS` as marker to bring whole procedure to an end -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop -flash_rm dfu_target_dfu_stop -flash_rm \ @@ -46,45 +41,38 @@ RunTestFlash dfu_dist_recover_phase \ # To test recovery from Verify Fail begin new distribution that will end there, # reboot devices and continue to Applying. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop -flash_erase dfu_target_dfu_stop -flash_erase \ -- -argstest recover=0 expected-phase=5 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash dfu_dist_recover_phase \ dfu_cli_stop -flash_rm dfu_target_dfu_stop -flash_rm \ -- -argstest recover=1 expected-phase=6 # The same test but with PSA crypto -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop -flash_erase dfu_target_dfu_stop -flash_erase \ -- -argstest recover=0 expected-phase=2 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=4 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop dfu_target_dfu_stop \ -- -argstest recover=1 expected-phase=6 # Use phase `BT_MESH_DFU_PHASE_APPLY_SUCCESS` as marker to bring whole procedure to an end -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop -flash_rm dfu_target_dfu_stop -flash_rm \ @@ -92,13 +80,11 @@ RunTestFlash dfu_dist_recover_phase_psa \ # To test recovery from Verify Fail begin new distribution that will end there, # reboot devices and continue to Applying. -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop -flash_erase dfu_target_dfu_stop -flash_erase \ -- -argstest recover=0 expected-phase=5 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash dfu_dist_recover_phase_psa \ dfu_cli_stop -flash_rm dfu_target_dfu_stop -flash_rm \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish.sh index b89ad3af2c7..d1082fa9f29 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_est \ friendship_friend_est \ friendship_lpn_est -conf=prj_mesh1d1_conf -RunTest mesh_friendship_est_1d1 \ - friendship_friend_est \ - friendship_lpn_est - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_est_psa \ friendship_friend_est \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish_multi.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish_multi.sh index 725ddae596e..32e4752123d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish_multi.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/establish_multi.sh @@ -14,16 +14,6 @@ RunTest mesh_friendship_est_multi \ friendship_lpn_est \ friendship_lpn_est -conf=prj_mesh1d1_conf -RunTest mesh_friendship_est_multi_1d1 \ - friendship_friend_est_multi \ - friendship_lpn_est \ - friendship_lpn_est \ - friendship_lpn_est \ - friendship_lpn_est \ - friendship_lpn_est - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_est_multi_psa \ friendship_friend_est_multi \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_disable.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_disable.sh index be22829d615..f8e24e51a3b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_disable.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_disable.sh @@ -16,12 +16,6 @@ RunTest mesh_lpn_disable_check \ friendship_friend_no_est \ friendship_lpn_disable -conf=prj_mesh1d1_conf -RunTest mesh_lpn_disable_check_1d1 \ - friendship_friend_no_est \ - friendship_lpn_disable - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_lpn_disable_check_psa \ friendship_friend_no_est \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_loopback.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_loopback.sh index 676b6b81ccc..7c42d7912ff 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_loopback.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_loopback.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_lpn_loopback \ friendship_lpn_loopback \ friendship_friend_est -conf=prj_mesh1d1_conf -RunTest mesh_friendship_lpn_loopback_1d1 \ - friendship_lpn_loopback \ - friendship_friend_est - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_lpn_loopback_psa \ friendship_lpn_loopback \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_terminate_cb.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_terminate_cb.sh index 75163076af4..e51fec31dd2 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_terminate_cb.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/lpn_terminate_cb.sh @@ -14,12 +14,6 @@ RunTest mesh_lpn_terminate_cb_check \ friendship_friend_est \ friendship_lpn_term_cb_check -conf=prj_mesh1d1_conf -RunTest mesh_lpn_terminate_cb_check_1d1 \ - friendship_friend_est \ - friendship_lpn_term_cb_check - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_lpn_terminate_cb_check_psa \ friendship_friend_est \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_frnd.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_frnd.sh index 94d6224da5b..2329ed289eb 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_frnd.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_frnd.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_msg_frnd \ friendship_friend_msg \ friendship_lpn_msg_frnd -conf=prj_mesh1d1_conf -RunTest mesh_friendship_msg_frnd_1d1 \ - friendship_friend_msg \ - friendship_lpn_msg_frnd - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_msg_frnd_psa \ friendship_friend_msg \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_group.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_group.sh index 6e7287b00ff..d6de655ba5b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_group.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_group.sh @@ -10,13 +10,6 @@ RunTest mesh_friendship_msg_group \ friendship_other_group \ friendship_friend_group -conf=prj_mesh1d1_conf -RunTest mesh_friendship_msg_group_1d1 \ - friendship_lpn_group \ - friendship_other_group \ - friendship_friend_group - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_msg_group_psa \ friendship_lpn_group \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh.sh index 072e427d72a..f05261bb258 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh.sh @@ -10,13 +10,6 @@ RunTest mesh_friendship_msg_mesh \ friendship_other_msg \ friendship_friend_est -conf=prj_mesh1d1_conf -RunTest mesh_friendship_msg_mesh_1d1 \ - friendship_lpn_msg_mesh \ - friendship_other_msg \ - friendship_friend_est - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_msg_mesh_psa \ friendship_lpn_msg_mesh \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh_low_lat.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh_low_lat.sh index d659281e4e9..3352d5812e6 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh_low_lat.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_mesh_low_lat.sh @@ -11,14 +11,6 @@ RunTest mesh_friendship_msg_mesh_low_lat \ friendship_other_msg \ friendship_friend_est -conf=prj_mesh1d1_conf -overlay=overlay_low_lat_conf -RunTest mesh_friendship_msg_mesh_low_lat_1d1 \ - friendship_lpn_msg_mesh \ - friendship_other_msg \ - friendship_friend_est - -conf=prj_mesh1d1_conf overlay="overlay_low_lat_conf_overlay_psa_conf" RunTest mesh_friendship_msg_mesh_low_lat_psa \ friendship_lpn_msg_mesh \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_va_collision.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_va_collision.sh index 360095d2e5f..3ec9cd29162 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_va_collision.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/msg_va_collision.sh @@ -24,12 +24,6 @@ RunTest mesh_friendship_msg_va_collision \ friendship_lpn_va_collision \ friendship_friend_va_collision -conf=prj_mesh1d1_conf -RunTest mesh_friendship_msg_va_collision_1d1 \ - friendship_lpn_va_collision \ - friendship_friend_va_collision - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_msg_va_collision_psa \ friendship_lpn_va_collision \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/overflow.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/overflow.sh index d717be60292..90398fb4d8a 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/overflow.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/overflow.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_overflow \ friendship_friend_overflow \ friendship_lpn_overflow -conf=prj_mesh1d1_conf -RunTest mesh_friendship_overflow_1d1 \ - friendship_friend_overflow \ - friendship_lpn_overflow - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_overflow_psa \ friendship_friend_overflow \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/poll.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/poll.sh index 90e744a7001..328050ba39e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/poll.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/poll.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_poll \ friendship_friend_est \ friendship_lpn_poll -conf=prj_mesh1d1_conf -RunTest mesh_friendship_poll_1d1 \ - friendship_friend_est \ - friendship_lpn_poll - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_poll_psa \ friendship_friend_est \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/re-establish.sh b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/re-establish.sh index 10abb4413ea..27b3e07e5f6 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/friendship/re-establish.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/friendship/re-establish.sh @@ -9,12 +9,6 @@ RunTest mesh_friendship_re_est \ friendship_friend_est \ friendship_lpn_re_est -conf=prj_mesh1d1_conf -RunTest mesh_friendship_re_est_1d1 \ - friendship_friend_est \ - friendship_lpn_re_est - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_friendship_re_est_psa \ friendship_friend_est \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_all.sh b/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_all.sh index eef25d08cf2..5bef1473a07 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_all.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_all.sh @@ -10,13 +10,6 @@ RunTest mesh_heartbeat_sub_cb_api_all \ heartbeat_publish_all \ heartbeat_subscribe_all -conf=prj_mesh1d1_conf -RunTest mesh_heartbeat_sub_cb_api_all_1d1 \ - heartbeat_publish_all \ - heartbeat_publish_all \ - heartbeat_subscribe_all - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_heartbeat_sub_cb_api_all_psa \ heartbeat_publish_all \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_unicast.sh b/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_unicast.sh index fc0660e5676..93b1e2ffe9f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_unicast.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/heartbeat/sub_cb_api_unicast.sh @@ -10,13 +10,6 @@ RunTest mesh_heartbeat_sub_cb_api_unicast \ heartbeat_publish_unicast \ heartbeat_subscribe_unicast -conf=prj_mesh1d1_conf -RunTest mesh_heartbeat_sub_cb_api_unicast_1d1 \ - heartbeat_publish_unicast \ - heartbeat_publish_unicast \ - heartbeat_subscribe_unicast - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_heartbeat_sub_cb_api_unicast_psa \ heartbeat_publish_unicast \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_deferring.sh b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_deferring.sh index cdf39dac438..6696b28ae00 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_deferring.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_deferring.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test deferring of the IV index update procedure RunTest mesh_ivi_deferring ivi_ivu_deferring -conf=prj_mesh1d1_conf -RunTest mesh_ivi_deferring_1d1 ivi_ivu_deferring - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_ivi_deferring_psa ivi_ivu_deferring diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_recovery.sh b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_recovery.sh index 39514bf39e6..a827f9b3abf 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_recovery.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_recovery.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test IV index recovery procedure RunTest mesh_ivi_recovery ivi_ivu_recovery -conf=prj_mesh1d1_conf -RunTest mesh_ivi_recovery_1d1 ivi_ivu_recovery - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_ivi_recovery_psa ivi_ivu_recovery diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_update.sh b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_update.sh index ee2b6b20000..f2f652012b8 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_update.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/iv_index/iv_update.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # test IV index update procedure RunTest mesh_ivi_update ivi_ivu_normal -conf=prj_mesh1d1_conf -RunTest mesh_ivi_update_1d1 ivi_ivu_normal - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_ivi_update_psa ivi_ivu_normal diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh index d65326b3d7f..dcaba598a57 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/large_comp_data/get_comp0_data_split.sh @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ lcd_srv_comp_data_status_respond lcd_cli_split_comp_data_request -- -argstest page=0 -conf=prj_mesh1d1_conf 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 index 6a65a2492ed..004a5224961 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index 77d4a1737a5..f88db1b7391 100755 --- 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 @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 index 9abdfd00dd7..084125c79a4 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index fba1760cb36..ab46d32048f 100755 --- 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 @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 index 282c3425c81..179c052e0ef 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index e3e8f2bad85..eb25353581b 100755 --- 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 @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 index 5daf32c54c0..a667f53abc8 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index bc24a9c9bf9..06312cf558b 100755 --- 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 @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 index 59383bb18f1..61f19ea3dcc 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index 53def43d5a0..3da45434ee1 100755 --- 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 @@ -19,12 +19,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 index f314f00d6ef..8ad929f1374 100755 --- 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 @@ -20,13 +20,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 b050037ccf0..71a692fa22c 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 @@ -14,12 +14,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 3. When server status arrive, remove status field data and compare received # 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_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 9b0be5ea20f..ef0f5712526 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 @@ -15,12 +15,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # is 378 bytes (380 bytes access payload). # 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_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 0e29e7d4219..38e43f88601 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 @@ -18,12 +18,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # received metadata with corresponding bytes in local data. # 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_pst_conf_overlay_psa_conf" RunTest mesh_lcd_test_split_metadata_psa \ lcd_cli_split_metadata_request lcd_srv_metadata_status_respond diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/full_status_msg_list.sh b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/full_status_msg_list.sh index fb60110ad7b..7a226017470 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/full_status_msg_list.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/full_status_msg_list.sh @@ -22,11 +22,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 6. The client keeps track of the number of received status messages. When X messages have been # received, the client pass if the sequence of received status messages corresponds to the order # in which the messages were sent, or the test fails. -conf=prj_mesh1d1_conf RunTest mesh_op_agg_test_max_access_payload \ op_agg_cli_max_len_sequence_msg_send op_agg_srv_max_len_status_msg_send -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_op_agg_test_max_access_payload_psa \ op_agg_cli_max_len_sequence_msg_send op_agg_srv_max_len_status_msg_send diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh index 3a4720bdaf4..7d2c7eec7d2 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/loopback.sh @@ -12,11 +12,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 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 index 08fcdf9f41e..928abd666f9 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/op_agg/model_coex.sh @@ -21,11 +21,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/access.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/access.sh index 0392430adba..cf9ec54faec 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/access.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/access.sh @@ -31,60 +31,25 @@ overlay=overlay_pst_conf RunTestFlash mesh_pst_access_data_check persistence_access_data_load -flash_rm \ -- -argstest access-cfg=not-configured -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_data_save -flash_erase - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_data_load \ - -- -argstest access-cfg=configured - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_sub_overwrite \ - -- -argstest access-cfg=configured - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_data_load \ - -- -argstest access-cfg=new-subs - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_data_remove \ - -- -argstest access-cfg=new-subs - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_access_data_check_1d1 persistence_access_data_load -flash_rm \ - -- -argstest access-cfg=not-configured - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_data_save -flash_erase -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_data_load \ -- -argstest access-cfg=configured -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_sub_overwrite \ -- -argstest access-cfg=configured -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_data_load \ -- -argstest access-cfg=new-subs -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_data_remove \ -- -argstest access-cfg=new-subs -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_access_data_check_psa persistence_access_data_load -flash_rm \ -- -argstest access-cfg=not-configured diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/cfg.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/cfg.sh index bb3074905a9..f9655ef7462 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/cfg.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/cfg.sh @@ -24,42 +24,18 @@ overlay=overlay_pst_conf RunTestFlash mesh_pst_cfg_check persistence_cfg_load -flash_rm \ -- -argstest stack-cfg=1 -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_cfg_check_1d1 persistence_cfg_save -flash_erase \ - -- -argstest stack-cfg=0 - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_cfg_check_1d1 persistence_cfg_load -flash_rm \ - -- -argstest stack-cfg=0 - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_cfg_check_1d1 persistence_cfg_save -flash_erase \ - -- -argstest stack-cfg=1 - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_cfg_check_1d1 persistence_cfg_load -flash_rm \ - -- -argstest stack-cfg=1 - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_cfg_check_psa persistence_cfg_save -flash_erase \ -- -argstest stack-cfg=0 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_cfg_check_psa persistence_cfg_load -flash_rm \ -- -argstest stack-cfg=0 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_cfg_check_psa persistence_cfg_save -flash_erase \ -- -argstest stack-cfg=1 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_cfg_check_psa persistence_cfg_load -flash_rm \ -- -argstest stack-cfg=1 diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh index f1e0591ef13..8dc7baa3e9d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/provisioning.sh @@ -16,18 +16,8 @@ RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_save -flash_ overlay=overlay_pst_conf RunTestFlash mesh_pst_prov_data_check persistence_provisioning_data_load -flash_rm -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_prov_data_check_1d1 persistence_provisioning_data_save -flash_erase - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTestFlash mesh_pst_prov_data_check_1d1 persistence_provisioning_data_load -flash_rm - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_prov_data_check_psa persistence_provisioning_data_save -flash_erase -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_pst_prov_data_check_psa persistence_provisioning_data_load -flash_rm diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/reprovisioning.sh b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/reprovisioning.sh index 922b4c8a513..511c04f766f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/persistence/reprovisioning.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/persistence/reprovisioning.sh @@ -20,25 +20,11 @@ RunTest mesh_pst_repr persistence_reprovisioning_device \ -flash=../results/mesh_pst_repr/flash.bin -flash_rm \ persistence_reprovisioning_provisioner -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_pst_repr_1d1 persistence_reprovisioning_device \ - -flash=../results/mesh_pst_repr_1d1/flash.bin -flash_erase \ - persistence_reprovisioning_provisioner - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_pst_repr_1d1 persistence_reprovisioning_device \ - -flash=../results/mesh_pst_repr_1d1/flash.bin -flash_rm \ - persistence_reprovisioning_provisioner - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_pst_repr_psa persistence_reprovisioning_device \ -flash=../results/mesh_pst_repr_psa/flash.bin -flash_erase \ persistence_reprovisioning_provisioner -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_pst_repr_psa persistence_reprovisioning_device \ -flash=../results/mesh_pst_repr_psa/flash.bin -flash_rm \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_adv.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_adv.sh index 48724dd7fbd..36c322a54da 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_adv.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_adv.sh @@ -6,9 +6,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test Private Beacon advertising on node supporting relay feature. # Test Random value changes for different Random intervals (10s, 0 - on every beacon, 30s). -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_adv beacon_rx_priv_adv beacon_tx_priv_adv -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_adv_psa beacon_rx_priv_adv beacon_tx_priv_adv 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 index 0cb5cdaea0a..46a460c7ec7 100755 --- 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 @@ -12,12 +12,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_interleave.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_interleave.sh index 6d574a72c73..cda94a89d93 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_interleave.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_interleave.sh @@ -15,9 +15,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # - PRB is disabled, SNB enabled: second SNB is advertised # - KR is initiated, third SNB is advertised with new flags (IVU + KR) # - PRB is enabled, SNB is disabled. Third PRB is advertised -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_interleave beacon_rx_priv_interleave beacon_tx_priv_interleave -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_interleave_psa beacon_rx_priv_interleave beacon_tx_priv_interleave diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_invalid.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_invalid.sh index b1983284a51..028ba0eabff 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_invalid.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_invalid.sh @@ -5,9 +5,7 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test if Private Beacons with invalid data do not affect device -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_invalid beacon_rx_priv_invalid beacon_tx_priv_invalid -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_invalid_psa beacon_rx_priv_invalid beacon_tx_priv_invalid diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu.sh index bb9a591fcb0..32232573305 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu.sh @@ -5,13 +5,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test Private Beacon advertising during IV Update procedure -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_on_iv_update \ beacon_rx_on_iv_update \ beacon_tx_priv_on_iv_update \ -- -argstest rand-int=1 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_on_iv_update_psa \ beacon_rx_on_iv_update \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu_long_interval.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu_long_interval.sh index ad0d11dbc96..d44ba297a0e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu_long_interval.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_ivu_long_interval.sh @@ -7,13 +7,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test Private Beacon advertising during IV Update procedure, with long Random Interval set. # Random value is expected to change before Random Interval is reached due to # Flags field change. -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_on_iv_update_long_interval \ beacon_rx_on_iv_update \ beacon_tx_priv_on_iv_update \ -- -argstest rand-int=3 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_on_iv_update_long_interval_psa \ beacon_rx_on_iv_update \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr.sh index eaf6338684f..59fe95658c2 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr.sh @@ -5,13 +5,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test Private Beacon advertising during Key Refresh procedure -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_on_key_refresh \ beacon_rx_on_key_refresh \ beacon_tx_priv_on_key_refresh \ -- -argstest rand-int=1 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_on_key_refresh_psa \ beacon_rx_on_key_refresh \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr_long_interval.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr_long_interval.sh index cc5722e4432..b0ec45b3f1d 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr_long_interval.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/priv_beacon_kr_long_interval.sh @@ -7,13 +7,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test Private Beacon advertising during Key Refresh procedure, with long Random Interval set. # Random value is expected to change before Random Interval is reached due to # Flags field change. -conf=prj_mesh1d1_conf RunTest mesh_priv_beacon_on_key_refresh_long_interval \ beacon_rx_on_key_refresh \ beacon_tx_priv_on_key_refresh \ -- -argstest rand-int=3 -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_priv_beacon_on_key_refresh_long_interval_psa \ beacon_rx_on_key_refresh \ 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 index a1b9ea7d8d6..8080b6ec70f 100755 --- 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 @@ -17,13 +17,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index 02fcf03c001..a431cdd9f6b 100755 --- 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 @@ -18,13 +18,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index 9d89b5af36c..cffb5adbeb0 100755 --- 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 @@ -15,13 +15,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ 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 index 2aff351bd78..2557c9c1506 100755 --- 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 @@ -23,13 +23,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh new file mode 100755 index 00000000000..0a3b5771bfd --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/priv_beacon/proxy_adv_multi_subnet_coex.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Copyright 2023 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh + +# Test Proxy advertisement Coex + +# This test verifies correct Proxy advertisement behavior for a device +# where the Proxy adv requirements changes over time, both for single +# and multiple subnets. The TX device is the DUT in this instance, while +# the RX device scans and verifies that the correct proxy adv messages of +# the different subnets is sent within the expected time delta. + +# Note 1: The maximum allowed timeslot for a subnet to advertise proxy +# in this scenario is 10 seconds when there is more than one subnet that +# has active proxy adv work. This is reflected in the scanning criteria +# on the RX device. + +# Note 2: The expected message received count for each event is based on +# what would be a reasonable/acceptable to receive within a given time +# window. The Mesh Protocol specification does not specify exactly the +# timing for Proxy ADV messages. + +# Note 3: The proxy transmitting device mandates emitting of the secure +# network beacons. This allows to check that proxy goes back to normal +# behavior after the device advertises the secure network beacons. + +# Test procedure: +# 1. (0-20 seconds) A single subnet is active on the TX device with GATT +# Proxy enabled. RX device verifies that the single subnet has exclusive +# access to the adv medium. +# 2. (20-50 seconds) Two additional subnets are added to the TX device. RX +# device checks that the subnets are sharing the adv medium, advertising +# NET_ID beacons. +# 3. (50-110 seconds) The second subnet enables Node Identity. RX device +# checks that NODE_ID is advertised by this subnet, and that the two +# others continues to advertise NET_ID. +# 4. (110-130 seconds) The first and second subnet gets solicited. RX device +# checks that PRIVATE_NET_ID is advertised by these subnets. +# 5. (130-150 seconds) The second and third subnet are disabled on the TX +# device. RX device verifies that the single subnet has exclusive access +# to the adv medium again. + + +overlay=overlay_gatt_conf +RunTest proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_multi_subnet_coex \ + beacon_rx_proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_solicit_trigger + +overlay=overlay_gatt_conf_overlay_psa_conf +RunTest proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_multi_subnet_coex \ + beacon_rx_proxy_adv_multi_subnet_coex \ + beacon_tx_proxy_adv_solicit_trigger diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_one_duration.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_one_duration.sh index 168c2620212..36c996269cf 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_one_duration.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_one_duration.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_prov_iv_update_one_duration prov_provisioner_iv_update_flag_one -conf=prj_mesh1d1_conf -RunTest mesh_prov_iv_update_one_duration_1d1 prov_provisioner_iv_update_flag_one - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_iv_update_one_duration_psa prov_provisioner_iv_update_flag_one diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_zero_duration.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_zero_duration.sh index 07165b31c1d..cb3294950f8 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_zero_duration.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/ivu_flag_zero_duration.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_prov_iv_update_zero_duration prov_provisioner_iv_update_flag_zero -conf=prj_mesh1d1_conf -RunTest mesh_prov_iv_update_zero_duration_1d1 prov_provisioner_iv_update_flag_zero - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_iv_update_zero_duration_psa prov_provisioner_iv_update_flag_zero diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_multi.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_multi.sh index 7d8dfbe6388..61bbbcc1a27 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_multi.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_multi.sh @@ -13,14 +13,6 @@ RunTest mesh_prov_pb_adv_multi \ prov_device_pb_adv_no_oob \ prov_device_pb_adv_no_oob -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_multi_1d1 \ - prov_provisioner_pb_adv_multi \ - prov_device_pb_adv_no_oob \ - prov_device_pb_adv_no_oob \ - prov_device_pb_adv_no_oob - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_multi_psa \ prov_provisioner_pb_adv_multi \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_no_oob.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_no_oob.sh index bfcb8540ae1..91bde356f2b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_no_oob.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_no_oob.sh @@ -8,12 +8,6 @@ RunTest mesh_prov_pb_adv_on_oob \ prov_device_pb_adv_no_oob \ prov_provisioner_pb_adv_no_oob -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_on_oob_1d1 \ - prov_device_pb_adv_no_oob \ - prov_provisioner_pb_adv_no_oob - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_on_oob_psa \ prov_device_pb_adv_no_oob \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ib_pk.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ib_pk.sh index 22d197a0adc..ef8e07f7c80 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ib_pk.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ib_pk.sh @@ -8,11 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_prov_pb_adv_oob_auth \ prov_device_pb_adv_oob_auth prov_provisioner_pb_adv_oob_auth -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_oob_auth_1d1 \ - prov_device_pb_adv_oob_auth prov_provisioner_pb_adv_oob_auth - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_oob_auth_psa \ prov_device_pb_adv_oob_auth prov_provisioner_pb_adv_oob_auth diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ignore_oob_pk.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ignore_oob_pk.sh index 5459997e547..8df3c6a4bf6 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ignore_oob_pk.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_ignore_oob_pk.sh @@ -9,11 +9,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_prov_pb_adv_device_w_oob_pk_prvnr_wt_pk \ prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_auth_no_oob_public_key -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_device_w_oob_pk_prvnr_wt_pk_1d1 \ - prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_auth_no_oob_public_key - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_device_w_oob_pk_prvnr_wt_pk_psa \ prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_auth_no_oob_public_key diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_oob_pk.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_oob_pk.sh index b8ab3a5d899..d24e5afccd4 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_oob_pk.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_oob_auth_oob_pk.sh @@ -8,11 +8,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_prov_pb_adv_oob_public_key \ prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_public_key -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_oob_public_key_1d1 \ - prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_public_key - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_oob_public_key_psa \ prov_device_pb_adv_oob_public_key prov_provisioner_pb_adv_oob_public_key diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_reprovision.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_reprovision.sh index 9c70514a093..0e3b84e3138 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_reprovision.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_adv_reprovision.sh @@ -8,12 +8,6 @@ RunTest mesh_prov_pb_adv_repr \ prov_device_pb_adv_reprovision \ prov_provisioner_pb_adv_reprovision -conf=prj_mesh1d1_conf -RunTest mesh_prov_pb_adv_repr_1d1 \ - prov_device_pb_adv_reprovision \ - prov_provisioner_pb_adv_reprovision - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_adv_repr_psa \ prov_device_pb_adv_reprovision \ 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 index 33de74370e1..9175a9ac015 100755 --- 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 @@ -20,12 +20,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 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 \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_nppi_robustness.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_nppi_robustness.sh index d707fdb6d6c..a59cf04aef4 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_nppi_robustness.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_nppi_robustness.sh @@ -13,13 +13,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 4. Execute composition refresh procedure 3 times for the third device. # 5. Execute address refresh procedure 3 times for the third device. # (Step 3-5 is executed without sending a node reset message) -conf=prj_mesh1d1_conf RunTest mesh_prov_pb_remote_nppi_robustness \ prov_provisioner_pb_remote_client_nppi_robustness \ prov_device_pb_remote_server_unproved \ prov_device_pb_remote_server_nppi_robustness -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_remote_nppi_robustness_psa \ prov_provisioner_pb_remote_client_nppi_robustness \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_parallel.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_parallel.sh index 2c3394381cd..6ecb3292193 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_parallel.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_parallel.sh @@ -11,14 +11,12 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 4. The provisioner scans for an unprovisioned device idx 3 through the node with RPR server; # 5. The provisioner checks scanning and provisioning succeeded; # 6. The provisioner provisions an unprovisioned device idx 3 through the node with RPR server; -conf=prj_mesh1d1_conf RunTest mesh_prov_pb_remote_parallel \ prov_provisioner_pb_remote_client_parallel \ prov_device_pb_remote_server_unproved \ prov_device_pb_adv_no_oob \ prov_device_pb_adv_no_oob -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_remote_parallel_psa \ prov_provisioner_pb_remote_client_parallel \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_pst_ncrp.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_pst_ncrp.sh index ed5f619b310..2bba5147d8f 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_pst_ncrp.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_pst_ncrp.sh @@ -31,7 +31,6 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # - verify that the device is not re-provisioned again. # Step 1 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash mesh_prov_pst_pb_remote_ncrp \ prov_provisioner_pb_remote_client_ncrp_provision -flash_erase \ @@ -39,7 +38,6 @@ RunTestFlash mesh_prov_pst_pb_remote_ncrp \ prov_device_pb_remote_server_ncrp_prepare -flash_erase # Step 2 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash mesh_prov_pst_pb_remote_ncrp \ prov_provisioner_pb_remote_client_ncrp \ @@ -47,7 +45,6 @@ RunTestFlash mesh_prov_pst_pb_remote_ncrp \ prov_device_pb_remote_server_ncrp # Step 3 -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash mesh_prov_pst_pb_remote_ncrp \ prov_provisioner_pb_remote_client_ncrp_second_time -flash_rm \ @@ -56,7 +53,6 @@ RunTestFlash mesh_prov_pst_pb_remote_ncrp \ # The same test but with PSA crypto # Step 1 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_prov_pst_pb_remote_ncrp_psa \ prov_provisioner_pb_remote_client_ncrp_provision -flash_erase \ @@ -64,7 +60,6 @@ RunTestFlash mesh_prov_pst_pb_remote_ncrp_psa \ prov_device_pb_remote_server_ncrp_prepare -flash_erase # Step 2 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_prov_pst_pb_remote_ncrp_psa \ prov_provisioner_pb_remote_client_ncrp \ @@ -72,7 +67,6 @@ RunTestFlash mesh_prov_pst_pb_remote_ncrp_psa \ prov_device_pb_remote_server_ncrp # Step 3 -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash mesh_prov_pst_pb_remote_ncrp_psa \ prov_provisioner_pb_remote_client_ncrp_second_time -flash_rm \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_reprovision.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_reprovision.sh index a49cbcd7ca9..1a2ae89d655 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_reprovision.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_reprovision.sh @@ -12,13 +12,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 5. The provisioner configures the health server on the recently provisioned device and sends Node # Reset; # 6. Repeat steps 3-5 multiple times. -conf=prj_mesh1d1_conf RunTest mesh_prov_pb_remote_reprovision \ prov_provisioner_pb_remote_client_reprovision \ prov_device_pb_remote_server_unproved \ prov_device_pb_adv_reprovision -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_remote_reprovision_psa \ prov_provisioner_pb_remote_client_reprovision \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_timeout.sh b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_timeout.sh index 8ef61c2666b..7feba542c44 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_timeout.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/provision/pb_remote_timeout.sh @@ -24,13 +24,11 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 11. 3rd device opens provisioning link. # 12. 2nd device stops communicating with either devices. # 13. After 60s RPR timeout is reached on 1st device. RPR Client closes provisioning link. -conf=prj_mesh1d1_conf RunTest mesh_prov_pb_remote_provisioning_timeout \ prov_provisioner_pb_remote_client_provision_timeout \ prov_device_pb_remote_server_unproved_unresponsive \ prov_device_unresponsive -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_prov_pb_remote_provisioning_timeout_psa \ prov_provisioner_pb_remote_client_provision_timeout \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/replay_attack.sh b/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/replay_attack.sh index 50387776dfb..d09e014bd0e 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/replay_attack.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/replay_attack.sh @@ -14,25 +14,11 @@ RunTest mesh_replay_attack \ rpc_tx_power_replay_attack \ rpc_rx_power_replay_attack -flash=../results/mesh_replay_attack/flash.bin -flash_rm -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_replay_attack_1d1 \ - rpc_tx_immediate_replay_attack \ - rpc_rx_immediate_replay_attack -flash=../results/mesh_replay_attack_1d1/flash.bin -flash_erase - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_replay_attack_1d1 \ - rpc_tx_power_replay_attack \ - rpc_rx_power_replay_attack -flash=../results/mesh_replay_attack_1d1/flash.bin -flash_rm - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_replay_attack_psa \ rpc_tx_immediate_replay_attack \ rpc_rx_immediate_replay_attack -flash=../results/mesh_replay_attack_psa/flash.bin -flash_erase -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_replay_attack_psa \ rpc_tx_power_replay_attack \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/rpl_frag.sh b/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/rpl_frag.sh index 8c7a7866eb3..7212b567a24 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/rpl_frag.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/replay_cache/rpl_frag.sh @@ -21,24 +21,11 @@ overlay=overlay_pst_conf RunTest mesh_replay_fragmentation \ rpc_rx_reboot_after_defrag -flash=../results/mesh_replay_fragmentation/flash.bin -flash_rm -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_replay_fragmentation_1d1 \ - rpc_rx_rpl_frag -flash=../results/mesh_replay_fragmentation_1d1/flash.bin -flash_erase \ - rpc_tx_rpl_frag - -conf=prj_mesh1d1_conf -overlay=overlay_pst_conf -RunTest mesh_replay_fragmentation_1d1 \ - rpc_rx_reboot_after_defrag -flash=../results/mesh_replay_fragmentation_1d1/flash.bin -flash_rm - -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_replay_fragmentation_psa \ rpc_rx_rpl_frag -flash=../results/mesh_replay_fragmentation_psa/flash.bin -flash_erase \ rpc_tx_rpl_frag -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTest mesh_replay_fragmentation_psa \ rpc_rx_reboot_after_defrag -flash=../results/mesh_replay_fragmentation_psa/flash.bin -flash_rm diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/sar/sar_cfg_persistent_storage.sh b/tests/bsim/bluetooth/mesh/tests_scripts/sar/sar_cfg_persistent_storage.sh index dc27c4dceda..0e67d5ab4d5 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/sar/sar_cfg_persistent_storage.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/sar/sar_cfg_persistent_storage.sh @@ -8,12 +8,10 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Tests must be added in sequence. # First test sets SAR TX/RX configuration. # Second test restores it from flash and checks if configuration persisted. -conf=prj_mesh1d1_conf overlay=overlay_pst_conf RunTestFlash sar_persistence sar_srv_cfg_store -flash_erase RunTestFlash sar_persistence sar_srv_cfg_restore -flash_rm -conf=prj_mesh1d1_conf overlay="overlay_pst_conf_overlay_psa_conf" RunTestFlash sar_persistence_psa sar_srv_cfg_store -flash_erase RunTestFlash sar_persistence_psa sar_srv_cfg_restore -flash_rm diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/sar/slow_transfer_test.sh b/tests/bsim/bluetooth/mesh/tests_scripts/sar/slow_transfer_test.sh index a022c23c3f4..db8f8f9dc21 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/sar/slow_transfer_test.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/sar/slow_transfer_test.sh @@ -14,11 +14,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 4. The Client sends a Get-message with a maximum length SDU, targeting the server. # 5. The Server responds with a maximum length SDU Status-message. # 6. The test passes when the Client successfully receives the Status response. -conf=prj_mesh1d1_conf RunTest sar_slow_test \ sar_cli_max_len_sdu_slow_send sar_srv_max_len_sdu_slow_receive -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest sar_slow_test_psa \ sar_cli_max_len_sdu_slow_send sar_srv_max_len_sdu_slow_receive diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/sar/stress_test.sh b/tests/bsim/bluetooth/mesh/tests_scripts/sar/stress_test.sh index 89707adf031..34b05446702 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/sar/stress_test.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/sar/stress_test.sh @@ -13,11 +13,9 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # 4. The Client sends a Get-message with a maximum length SDU, targeting the server. # 5. The Server responds with a maximum length SDU Status-message. # 6. The test passes when the Client successfully receives the Status response. -conf=prj_mesh1d1_conf RunTest sar_test \ sar_cli_max_len_sdu_send sar_srv_max_len_sdu_receive -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest sar_test_psa \ sar_cli_max_len_sdu_send sar_srv_max_len_sdu_receive diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/scanner/invalid_ad_type.sh b/tests/bsim/bluetooth/mesh/tests_scripts/scanner/invalid_ad_type.sh index 9199ac69da8..c46088c5a15 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/scanner/invalid_ad_type.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/scanner/invalid_ad_type.sh @@ -8,12 +8,6 @@ RunTest mesh_scanner_invalid_ad_type \ scanner_tx_invalid_ad_type \ scanner_rx_invalid_packet -conf=prj_mesh1d1_conf -RunTest mesh_scanner_invalid_ad_type_1d1 \ - scanner_tx_invalid_ad_type \ - scanner_rx_invalid_packet - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_scanner_invalid_ad_type_psa \ scanner_tx_invalid_ad_type \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/scanner/wrong_packet_length.sh b/tests/bsim/bluetooth/mesh/tests_scripts/scanner/wrong_packet_length.sh index 8f0919058ed..80f8cacca83 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/scanner/wrong_packet_length.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/scanner/wrong_packet_length.sh @@ -8,12 +8,6 @@ RunTest mesh_scanner_wrong_packet_length \ scanner_tx_wrong_packet_length \ scanner_rx_invalid_packet -conf=prj_mesh1d1_conf -RunTest mesh_scanner_wrong_packet_length_1d1 \ - scanner_tx_wrong_packet_length \ - scanner_rx_invalid_packet - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_scanner_wrong_packet_length_psa \ scanner_tx_wrong_packet_length \ diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_disable_resume.sh b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_disable_resume.sh new file mode 100755 index 00000000000..711f92f4007 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_disable_resume.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 GATT advertisement is stopped when suspending Mesh and disabling +# Bluetooth, and that it is started again when Bluetooth is re-enabled and Mesh is resumed. +# +# Test procedure: +# 0. DUT (Device 0) initializes the Mesh stack, and starts provisioning procedure using +# bt_mesh_prov_enable(BT_MESH_PROV_GATT). +# 1. Tester (Device 1) observes PB-GATT advs, and will fail the test if the expected +# amount of advs is not received. +# 2. DUT is provisioned, and Tester observes GATT proxy advs. +# 3. DUT notifies the Tester that it will be suspended, and Tester observes for advs after a +# brief delay. Receiving an adv while DUT is suspended will cause the test to fail. +# 4. After a delay, the DUT resumes and notifies the Tester, which checks that the +# advertising resumes. + +overlay=overlay_gatt_conf +RunTest mesh_gatt_suspend_disable_resume \ + suspend_dut_gatt_suspend_disable_resume suspend_tester_gatt + +overlay="overlay_gatt_conf_overlay_low_lat_conf" +RunTest mesh_gatt_suspend_disable_resume_low_lat \ + suspend_dut_gatt_suspend_disable_resume suspend_tester_gatt + +overlay="overlay_gatt_conf_overlay_psa_conf" +RunTest mesh_gatt_suspend_disable_resume_psa \ + suspend_dut_gatt_suspend_disable_resume suspend_tester_gatt diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_resume.sh b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_resume.sh new file mode 100755 index 00000000000..f0e4fb23502 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/gatt_suspend_resume.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 GATT advertisement is stopped when suspending Mesh, and that it is started again +# when Mesh is resumed. +# +# Test procedure: +# 0. DUT (Device 0) initializes the Mesh stack, and starts provisioning procedure using +# bt_mesh_prov_enable(BT_MESH_PROV_GATT). +# 1. Tester (Device 1) observes PB-GATT advs, and will fail the test if the expected +# amount of advs is not received. +# 2. DUT is provisioned, and Tester observes GATT proxy advs. +# 3. DUT notifies the Tester that it will be suspended, and Tester observes for advs after a +# brief delay. Receiving an adv while DUT is suspended will cause the test to fail. +# 4. After a delay, the DUT resumes and notifies the Tester, which checks that the +# advertising resumes. + +overlay=overlay_gatt_conf +RunTest mesh_gatt_suspend_resume \ + suspend_dut_gatt_suspend_resume suspend_tester_gatt + +overlay="overlay_gatt_conf_overlay_low_lat_conf" +RunTest mesh_gatt_suspend_resume_low_lat \ + suspend_dut_gatt_suspend_resume suspend_tester_gatt + +overlay="overlay_gatt_conf_overlay_psa_conf" +RunTest mesh_gatt_suspend_resume_psa \ + suspend_dut_gatt_suspend_resume suspend_tester_gatt diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_disable_resume.sh b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_disable_resume.sh new file mode 100755 index 00000000000..bfe42e15c16 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_disable_resume.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 that periodic publication is stopped when suspending Mesh and disabling +# Bluetooth, and that it is started again when Bluetooth is re-enabled and Mesh is resumed. +# The test will fail under two conditions; if no publication is received while +# Mesh is enabled, or if a publication is received while Mesh is suspended. +# +# Test procedure: +# 0. Provisioning and setup. +# 1. Start publication. +# 2. Suspend Mesh and disable Bluetooth, checking that publication stops. +# 3. Enable Bluetooth and resume Mesh a specified time after suspension. +# Check that publication resumes. + +RunTest mesh_suspend_disable_resume \ + suspend_dut_suspend_disable_resume suspend_tester_pub + +overlay=overlay_low_lat_conf +RunTest mesh_suspend_disable_resume_low_lat \ + suspend_dut_suspend_disable_resume suspend_tester_pub + +overlay=overlay_psa_conf +RunTest mesh_suspend_disable_resume_psa \ + suspend_dut_suspend_disable_resume suspend_tester_pub diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_resume.sh b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_resume.sh new file mode 100755 index 00000000000..31d151201a8 --- /dev/null +++ b/tests/bsim/bluetooth/mesh/tests_scripts/suspend/suspend_resume.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 that periodic publication is stopped when suspending Mesh, and that it +# is started again when Mesh is resumed. The test will fail under two +# conditions; if no publication is received while Mesh is enabled, +# or if a publication is received while Mesh is suspended. +# +# Test procedure: +# 0. Provisioning and setup. +# 1. Start publication. +# 2. Suspend Mesh, checking that publication stops. +# 3. Resume Mesh a specified time after suspension. Check that publication resumes. + +RunTest mesh_suspend_resume \ + suspend_dut_suspend_resume suspend_tester_pub + +overlay=overlay_low_lat_conf +RunTest mesh_suspend_resume_low_lat \ + suspend_dut_suspend_resume suspend_tester_pub + +overlay=overlay_psa_conf +RunTest mesh_suspend_resume_psa \ + suspend_dut_suspend_resume suspend_tester_pub diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/fixed.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/fixed.sh index d4b86d2f98a..f4d0cfc0cac 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/fixed.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/fixed.sh @@ -15,9 +15,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # model; RunTest mesh_transport_fixed transport_tx_fixed transport_rx_fixed -conf=prj_mesh1d1_conf -RunTest mesh_transport_fixed_1d1 transport_tx_fixed transport_rx_fixed - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_fixed_1d1 transport_tx_fixed transport_rx_fixed diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/group.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/group.sh index d85d7cf8604..7b7c6a559fc 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/group.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/group.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_group transport_tx_group transport_rx_group -conf=prj_mesh1d1_conf -RunTest mesh_transport_group_1d1 transport_tx_group transport_rx_group - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_group_psa transport_tx_group transport_rx_group diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback.sh index 9cc1fb33041..e2812efda23 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest transport_loopback transport_tx_loopback transport_rx_none -conf=prj_mesh1d1_conf -RunTest transport_loopback_1d1 transport_tx_loopback transport_rx_none - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest transport_loopback_psa transport_tx_loopback transport_rx_none diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group.sh index 3be2bb24367..38b6c8dd906 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_loopback_group transport_tx_loopback_group transport_rx_group -conf=prj_mesh1d1_conf -RunTest mesh_transport_loopback_group_1d1 transport_tx_loopback_group transport_rx_group - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_loopback_group_psa transport_tx_loopback_group transport_rx_group diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group_low_lat.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group_low_lat.sh index 63829e012a5..3972edd3034 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group_low_lat.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/loopback_group_low_lat.sh @@ -7,10 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh overlay=overlay_low_lat_conf RunTest mesh_transport_loopback_group_low_lat transport_tx_loopback_group transport_rx_group -conf=prj_mesh1d1_conf -overlay=overlay_low_lat_conf -RunTest mesh_transport_loopback_group_low_lat_1d1 transport_tx_loopback_group transport_rx_group - -conf=prj_mesh1d1_conf overlay="overlay_low_lat_conf_overlay_psa_conf" RunTest mesh_transport_loopback_group_low_lat_psa transport_tx_loopback_group transport_rx_group diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_block.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_block.sh index 21a56f37478..788d3eeebdf 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_block.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_block.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_seg_block transport_tx_seg_block transport_rx_seg_block -conf=prj_mesh1d1_conf -RunTest mesh_transport_seg_block_1d1 transport_tx_seg_block transport_rx_seg_block - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_seg_block_psa transport_tx_seg_block transport_rx_seg_block diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_concurrent.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_concurrent.sh index 40ba38aae12..d07c90c8d22 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_concurrent.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_concurrent.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_seg_concurrent transport_tx_seg_concurrent transport_rx_seg_concurrent -conf=prj_mesh1d1_conf -RunTest mesh_transport_seg_concurrent_1d1 transport_tx_seg_concurrent transport_rx_seg_concurrent - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_seg_concurrent_psa transport_tx_seg_concurrent transport_rx_seg_concurrent diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_fail.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_fail.sh index ca650ede1f4..72639370b93 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_fail.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_fail.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_seg_fail transport_tx_seg_fail -conf=prj_mesh1d1_conf -RunTest mesh_transport_seg_fail_1d1 transport_tx_seg_fail - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_seg_fail_psa transport_tx_seg_fail diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_ivu.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_ivu.sh index 9268e42029e..0ef30273341 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_ivu.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/seg_ivu.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_seg_ivu transport_tx_seg_ivu transport_rx_seg_ivu -conf=prj_mesh1d1_conf -RunTest mesh_transport_seg_ivu_1d1 transport_tx_seg_ivu transport_rx_seg_ivu - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_seg_ivu_psa transport_tx_seg_ivu transport_rx_seg_ivu diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast.sh index a107a86146c..c91397f4f4b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_unicast transport_tx_unicast transport_rx_unicast -conf=prj_mesh1d1_conf -RunTest mesh_transport_unicast_1d1 transport_tx_unicast transport_rx_unicast - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_unicast_psa transport_tx_unicast transport_rx_unicast diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast_low_lat.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast_low_lat.sh index cbfc8ea5ce7..981347a3385 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast_low_lat.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unicast_low_lat.sh @@ -7,10 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh overlay=overlay_low_lat_conf RunTest mesh_transport_unicast_low_lat transport_tx_unicast transport_rx_unicast -conf=prj_mesh1d1_conf -overlay=overlay_low_lat_conf -RunTest mesh_transport_unicast_low_lat_1d1 transport_tx_unicast transport_rx_unicast - -conf=prj_mesh1d1_conf overlay="overlay_low_lat_conf_overlay_psa_conf" RunTest mesh_transport_unicast_low_lat_psa transport_tx_unicast transport_rx_unicast diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unknown_app.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unknown_app.sh index 2a1b2741b60..6f077ee0c8b 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/unknown_app.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/unknown_app.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_unknown_app transport_tx_unknown_app transport_rx_none -conf=prj_mesh1d1_conf -RunTest mesh_transport_unknown_app_1d1 transport_tx_unknown_app transport_rx_none - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_unknown_app_psa transport_tx_unknown_app transport_rx_none diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/va.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/va.sh index 698bd164485..4336a2aa042 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/va.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/va.sh @@ -6,9 +6,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh RunTest mesh_transport_va transport_tx_va transport_rx_va -conf=prj_mesh1d1_conf -RunTest mesh_transport_va_1d1 transport_tx_va transport_rx_va - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_va_psa transport_tx_va transport_rx_va diff --git a/tests/bsim/bluetooth/mesh/tests_scripts/transport/va_collision.sh b/tests/bsim/bluetooth/mesh/tests_scripts/transport/va_collision.sh index 631c43790ef..dbcc3c64bc7 100755 --- a/tests/bsim/bluetooth/mesh/tests_scripts/transport/va_collision.sh +++ b/tests/bsim/bluetooth/mesh/tests_scripts/transport/va_collision.sh @@ -7,9 +7,5 @@ source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh # Test transmission to virtual addresses with collision RunTest mesh_transport_va_collision transport_tx_va_collision transport_rx_va_collision -conf=prj_mesh1d1_conf -RunTest mesh_transport_va_collision_1d1 transport_tx_va_collision transport_rx_va_collision - -conf=prj_mesh1d1_conf overlay=overlay_psa_conf RunTest mesh_transport_va_collision_psa transport_tx_va_collision transport_rx_va_collision diff --git a/tests/drivers/build_all/adc/boards/native_posix.overlay b/tests/drivers/build_all/adc/boards/native_sim.overlay similarity index 100% rename from tests/drivers/build_all/adc/boards/native_posix.overlay rename to tests/drivers/build_all/adc/boards/native_sim.overlay diff --git a/tests/drivers/build_all/adc/boards/native_posix_64.overlay b/tests/drivers/build_all/adc/boards/native_sim_64.overlay similarity index 74% rename from tests/drivers/build_all/adc/boards/native_posix_64.overlay rename to tests/drivers/build_all/adc/boards/native_sim_64.overlay index b5655714d89..16e56822d5f 100644 --- a/tests/drivers/build_all/adc/boards/native_posix_64.overlay +++ b/tests/drivers/build_all/adc/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/build_all/adc/testcase.yaml b/tests/drivers/build_all/adc/testcase.yaml index a8102364b60..3b8995e1769 100644 --- a/tests/drivers/build_all/adc/testcase.yaml +++ b/tests/drivers/build_all/adc/testcase.yaml @@ -7,8 +7,8 @@ tests: drivers.adc.build: # will cover I2C, SPI, and emul based drivers platform_allow: - - native_posix - - native_posix_64 + - native_sim + - native_sim_64 extra_args: "CONFIG_GPIO=y" drivers.adc.cc32xx.build: platform_allow: cc3220sf_launchxl diff --git a/tests/drivers/build_all/charger/testcase.yaml b/tests/drivers/build_all/charger/testcase.yaml index f2005d9f238..0a29ccc7b39 100644 --- a/tests/drivers/build_all/charger/testcase.yaml +++ b/tests/drivers/build_all/charger/testcase.yaml @@ -7,4 +7,6 @@ tests: - drivers - charger build_only: true - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim diff --git a/tests/drivers/build_all/dac/testcase.yaml b/tests/drivers/build_all/dac/testcase.yaml index 12252b8661f..a298ded77b4 100644 --- a/tests/drivers/build_all/dac/testcase.yaml +++ b/tests/drivers/build_all/dac/testcase.yaml @@ -6,7 +6,9 @@ common: tests: drivers.dac.build: # will cover I2C, SPI based drivers - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim extra_args: "CONFIG_GPIO=y" drivers.dac.mcux.build: platform_allow: frdm_k22f diff --git a/tests/drivers/build_all/fpga/testcase.yaml b/tests/drivers/build_all/fpga/testcase.yaml index 33cccf76dde..ad0d3e8123e 100644 --- a/tests/drivers/build_all/fpga/testcase.yaml +++ b/tests/drivers/build_all/fpga/testcase.yaml @@ -2,7 +2,9 @@ common: tags: - drivers - sensors - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim build_only: true tests: drivers.fpga.build: diff --git a/tests/drivers/build_all/gnss/CMakeLists.txt b/tests/drivers/build_all/gnss/CMakeLists.txt new file mode 100644 index 00000000000..518596a02f7 --- /dev/null +++ b/tests/drivers/build_all/gnss/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/gnss/app.overlay b/tests/drivers/build_all/gnss/app.overlay new file mode 100644 index 00000000000..1d43fa61525 --- /dev/null +++ b/tests/drivers/build_all/gnss/app.overlay @@ -0,0 +1,22 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_uart: uart@0 { + compatible = "vnd,serial"; + reg = <0x0 0x1000>; + status = "okay"; + + gnss: gnss-nmea-generic { + compatible = "gnss-nmea-generic"; + }; + }; + }; +}; diff --git a/tests/drivers/build_all/gnss/prj.conf b/tests/drivers/build_all/gnss/prj.conf new file mode 100644 index 00000000000..945eb0df717 --- /dev/null +++ b/tests/drivers/build_all/gnss/prj.conf @@ -0,0 +1,3 @@ +CONFIG_SERIAL=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_GNSS=y diff --git a/tests/drivers/build_all/gnss/src/main.c b/tests/drivers/build_all/gnss/src/main.c new file mode 100644 index 00000000000..ccbdca6d36b --- /dev/null +++ b/tests/drivers/build_all/gnss/src/main.c @@ -0,0 +1,10 @@ +/* + * Copyright 2023 Google LLC + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + return 0; +} diff --git a/tests/drivers/build_all/gnss/testcase.yaml b/tests/drivers/build_all/gnss/testcase.yaml new file mode 100644 index 00000000000..faaec12c745 --- /dev/null +++ b/tests/drivers/build_all/gnss/testcase.yaml @@ -0,0 +1,8 @@ +common: + tags: + - drivers + - gnss + build_only: true + platform_allow: native_sim +tests: + drivers.gnss.default: {} diff --git a/tests/drivers/build_all/ieee802154/testcase.yaml b/tests/drivers/build_all/ieee802154/testcase.yaml index fd9fb07e062..399f3fac3cf 100644 --- a/tests/drivers/build_all/ieee802154/testcase.yaml +++ b/tests/drivers/build_all/ieee802154/testcase.yaml @@ -5,7 +5,9 @@ common: build_only: true tests: ieee802154.build.external: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim ieee802154.build.cc13xx_cc26xx: platform_allow: cc1352r_sensortag ieee802154.build.kw41z: diff --git a/tests/drivers/build_all/input/testcase.yaml b/tests/drivers/build_all/input/testcase.yaml index 32fe44b883f..80a60399464 100644 --- a/tests/drivers/build_all/input/testcase.yaml +++ b/tests/drivers/build_all/input/testcase.yaml @@ -3,7 +3,9 @@ common: - drivers - input build_only: true - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim tests: drivers.input.default: {} diff --git a/tests/drivers/build_all/mfd/testcase.yaml b/tests/drivers/build_all/mfd/testcase.yaml index 80864481bdf..126fdb40e55 100644 --- a/tests/drivers/build_all/mfd/testcase.yaml +++ b/tests/drivers/build_all/mfd/testcase.yaml @@ -5,4 +5,6 @@ common: - mfd tests: drivers.mfd.build: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim diff --git a/tests/drivers/build_all/modem/modem_cellular.conf b/tests/drivers/build_all/modem/modem_cellular.conf index 3366fcf32d4..4582216f772 100644 --- a/tests/drivers/build_all/modem/modem_cellular.conf +++ b/tests/drivers/build_all/modem/modem_cellular.conf @@ -1,10 +1,8 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_GPIO=y CONFIG_SERIAL=y +CONFIG_MODEM=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 diff --git a/tests/drivers/build_all/modem/modem_esp_at.conf b/tests/drivers/build_all/modem/modem_esp_at.conf index 01d4b62ba50..e24bee337af 100644 --- a/tests/drivers/build_all/modem/modem_esp_at.conf +++ b/tests/drivers/build_all/modem/modem_esp_at.conf @@ -1,8 +1,9 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_SERIAL=y CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y CONFIG_NET_SOCKETS=y CONFIG_NET_IPV4=y CONFIG_WIFI=y +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_NET_CONNECTION_MANAGER_CONNECTIVITY_WIFI_MGMT=y diff --git a/tests/drivers/build_all/modem/modem_gsm.conf b/tests/drivers/build_all/modem/modem_gsm.conf index a7c4e492bc3..dd5b37afb9e 100644 --- a/tests/drivers/build_all/modem/modem_gsm.conf +++ b/tests/drivers/build_all/modem/modem_gsm.conf @@ -1,10 +1,9 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_GPIO=y CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y CONFIG_NET_IPV4=y CONFIG_NET_DRIVERS=y CONFIG_NET_PPP=y CONFIG_NET_L2_PPP=y -CONFIG_MODEM=y CONFIG_MODEM_GSM_PPP=y diff --git a/tests/drivers/build_all/modem/modem_gsm_mux.conf b/tests/drivers/build_all/modem/modem_gsm_mux.conf new file mode 100644 index 00000000000..952ace2466d --- /dev/null +++ b/tests/drivers/build_all/modem/modem_gsm_mux.conf @@ -0,0 +1,11 @@ +CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_DRIVERS=y +CONFIG_NET_PPP=y +CONFIG_NET_L2_PPP=y +CONFIG_MODEM_GSM_PPP=y +CONFIG_GSM_MUX=y +CONFIG_UART_MUX=y diff --git a/tests/drivers/build_all/modem/modem.conf b/tests/drivers/build_all/modem/modem_hl7800.conf similarity index 79% rename from tests/drivers/build_all/modem/modem.conf rename to tests/drivers/build_all/modem/modem_hl7800.conf index 0143f6fcd7f..5cc44bb71ea 100644 --- a/tests/drivers/build_all/modem/modem.conf +++ b/tests/drivers/build_all/modem/modem_hl7800.conf @@ -1,10 +1,8 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_TEST_USERSPACE=y +CONFIG_GPIO=y CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y CONFIG_NET_IPV4=y -CONFIG_MODEM=y CONFIG_MODEM_HL7800=y CONFIG_MODEM_HL7800_FW_UPDATE=y CONFIG_MODEM_HL7800_SET_APN_NAME_ON_STARTUP=y diff --git a/tests/drivers/build_all/modem/modem_quectel_bg9x.conf b/tests/drivers/build_all/modem/modem_quectel_bg9x.conf index 9fb71bbe412..f868a0ef77a 100644 --- a/tests/drivers/build_all/modem/modem_quectel_bg9x.conf +++ b/tests/drivers/build_all/modem/modem_quectel_bg9x.conf @@ -1,9 +1,7 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_SERIAL=y CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y CONFIG_NET_SOCKETS=y -CONFIG_MODEM=y CONFIG_MODEM_QUECTEL_BG9X=y CONFIG_MODEM_QUECTEL_BG9X_APN="hologram" diff --git a/tests/drivers/build_all/modem/modem_simcom_sim7080.conf b/tests/drivers/build_all/modem/modem_simcom_sim7080.conf index dc4645a2455..b6f1530f8a2 100644 --- a/tests/drivers/build_all/modem/modem_simcom_sim7080.conf +++ b/tests/drivers/build_all/modem/modem_simcom_sim7080.conf @@ -1,8 +1,7 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_SERIAL=y CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y +CONFIG_GPIO=y CONFIG_NET_SOCKETS=y -CONFIG_MODEM=y CONFIG_MODEM_SIM7080=y diff --git a/tests/drivers/build_all/modem/modem_ublox_sara.conf b/tests/drivers/build_all/modem/modem_ublox_sara.conf index 21e61c8ec54..8cef947f051 100644 --- a/tests/drivers/build_all/modem/modem_ublox_sara.conf +++ b/tests/drivers/build_all/modem/modem_ublox_sara.conf @@ -1,8 +1,6 @@ -CONFIG_TEST=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_SERIAL=y CONFIG_GPIO=y +CONFIG_SERIAL=y +CONFIG_MODEM=y CONFIG_NETWORKING=y CONFIG_NET_SOCKETS=y -CONFIG_MODEM=y CONFIG_MODEM_UBLOX_SARA=y diff --git a/tests/drivers/build_all/modem/prj.conf b/tests/drivers/build_all/modem/prj.conf deleted file mode 100644 index bb5ccbec1ba..00000000000 --- a/tests/drivers/build_all/modem/prj.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_TEST=y -CONFIG_TEST_USERSPACE=y -CONFIG_SERIAL=y diff --git a/tests/drivers/build_all/modem/src/main.c b/tests/drivers/build_all/modem/src/main.c index 90b910a7799..527f64e3f1e 100644 --- a/tests/drivers/build_all/modem/src/main.c +++ b/tests/drivers/build_all/modem/src/main.c @@ -8,3 +8,15 @@ int main(void) { return 0; } + +#ifdef CONFIG_CONNECTIVITY_WIFI_MGMT_APPLICATION + +#include +#include + +/* Bind L2 connectity APIs. */ +static struct conn_mgr_conn_api conn_api = { 0 }; + +CONN_MGR_CONN_DEFINE(CONNECTIVITY_WIFI_MGMT, &conn_api); + +#endif /* CONFIG_CONNECTIVITY_WIFI_MGMT_APPLICATION */ diff --git a/tests/drivers/build_all/modem/testcase.yaml b/tests/drivers/build_all/modem/testcase.yaml index 89abfbd79df..303e0ee44e8 100644 --- a/tests/drivers/build_all/modem/testcase.yaml +++ b/tests/drivers/build_all/modem/testcase.yaml @@ -1,84 +1,73 @@ common: build_only: true - tags: - - drivers - - net - - modem + platform_allow: + - native_sim + - native_sim_64 + - qemu_x86 + - qemu_x86_64 + tests: - drivers.modem.build: - extra_args: CONF_FILE=modem.conf - platform_exclude: - - serpente - - particle_boron - - rak5010_nrf52840 - - litex_vexriscv - - ip_k66f - min_ram: 68 - min_flash: 115 - drivers.modem.ublox_sara.build: + drivers.modem.modem_hl7800.interrupt_driven.build: + extra_args: CONF_FILE=modem_hl7800.conf + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_hl7800.async.build: + extra_args: CONF_FILE=modem_hl7800.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_ublox_sara.interrupt_driven.build: extra_args: CONF_FILE=modem_ublox_sara.conf - platform_exclude: - - serpente - - pinnacle_100_dvk - - litex_vexriscv - - ip_k66f - - mg100 - drivers.modem.simcom_sim7080.build: - extra_args: CONF_FILE=modem_simcom_sim7080.conf - platform_exclude: - - serpente - - pinnacle_100_dvk - - litex_vexriscv - - ip_k66f - - mg100 - drivers.modem.quectel_bg9x.build: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_ublox_sara.async.build: + extra_args: CONF_FILE=modem_ublox_sara.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_quectel_bg9x.interrupt_driven.build: extra_args: CONF_FILE=modem_quectel_bg9x.conf - platform_exclude: - - serpente - - pinnacle_100_dvk - - litex_vexriscv - - ip_k66f - - mg100 - min_ram: 36 - drivers.modem.gsm.build: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_quectel_bg9x.async.build: + extra_args: CONF_FILE=modem_quectel_bg9x.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_gsm.interrupt_driven.build: extra_args: CONF_FILE=modem_gsm.conf - platform_exclude: - - serpente - - particle_boron - - rak5010_nrf52840 - - litex_vexriscv - - ip_k66f - min_ram: 36 - drivers.modem.gsm_mux.build: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_gsm.async.build: extra_args: CONF_FILE=modem_gsm.conf - platform_exclude: - - serpente - - particle_boron - - rak5010_nrf52840 - - litex_vexriscv - - ip_k66f - min_ram: 36 - extra_configs: - - CONFIG_GSM_MUX=y - - CONFIG_UART_MUX=y - drivers.modem.esp_at.build: + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_gsm_mux.interrupt_driven.build: + extra_args: CONF_FILE=modem_gsm_mux.conf + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_gsm_mux.async.build: + extra_args: CONF_FILE=modem_gsm_mux.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_esp_at.interrupt_driven.build: extra_args: CONF_FILE=modem_esp_at.conf - platform_exclude: - - ip_k66f - - cy8cproto_062_4343w - filter: CONFIG_SERIAL - min_ram: 36 - drivers.modem.esp_at.async.build: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_esp_at.async.build: extra_args: CONF_FILE=modem_esp_at.conf - filter: CONFIG_SERIAL and CONFIG_QEMU_TARGET - min_ram: 36 extra_configs: - - CONFIG_MODEM_IFACE_UART_ASYNC=y - drivers.modem.modem_cellular.build: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_cellular.interrupt_driven.build: + extra_args: CONF_FILE=modem_cellular.conf + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_cellular.async.build: extra_args: CONF_FILE=modem_cellular.conf - platform_allow: - - native_posix_64 - - native_posix - - qemu_x86 - - qemu_x86_64 - min_ram: 36 + extra_configs: + - CONFIG_UART_ASYNC_API=y + drivers.modem.modem_simcom_sim7080.interrupt_driven.build: + extra_args: CONF_FILE=modem_simcom_sim7080.conf + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + drivers.modem.modem_simcom_sim7080.async.build: + extra_args: CONF_FILE=modem_simcom_sim7080.conf + extra_configs: + - CONFIG_UART_ASYNC_API=y diff --git a/tests/drivers/build_all/modem/uart.dtsi b/tests/drivers/build_all/modem/uart.dtsi index 3d649a2ff60..08da2c325d3 100644 --- a/tests/drivers/build_all/modem/uart.dtsi +++ b/tests/drivers/build_all/modem/uart.dtsi @@ -70,3 +70,9 @@ test_telit_me910g1: telit_me910g1 { test_esp_at: esp_at { compatible = "espressif,esp-at"; }; + +test_nordic_nrf91_slm: nordic_nrf91_slm { + compatible = "nordic,nrf91-slm"; + + mdm-power-gpios = <&test_gpio 0 0>; +}; diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml index 9b9c25511c4..8214a2ca33a 100644 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -3,8 +3,8 @@ tests: drivers.regulator.build: - tags: - - drivers - - regulator + tags: drivers regulator build_only: true - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim diff --git a/tests/drivers/build_all/video/testcase.yaml b/tests/drivers/build_all/video/testcase.yaml index 22595c7be54..08dd430da73 100644 --- a/tests/drivers/build_all/video/testcase.yaml +++ b/tests/drivers/build_all/video/testcase.yaml @@ -5,7 +5,9 @@ common: - video tests: drivers.video.build: - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim min_ram: 32 depends_on: - gpio diff --git a/tests/drivers/console_switching/CMakeLists.txt b/tests/drivers/console_switching/CMakeLists.txt new file mode 100644 index 00000000000..3ba70cc081e --- /dev/null +++ b/tests/drivers/console_switching/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_console_switching) + +target_sources(app PRIVATE + src/main.c + ) diff --git a/tests/drivers/console_switching/boards/qemu_riscv64.overlay b/tests/drivers/console_switching/boards/qemu_riscv64.overlay new file mode 100644 index 00000000000..47bd7945189 --- /dev/null +++ b/tests/drivers/console_switching/boards/qemu_riscv64.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,console = &devmux0; + zephyr,shell_uart = &devmux0; + }; + + euart0: uart_emul0 { + compatible = "zephyr,uart-emul"; + current-speed = <0>; + status = "okay"; + }; + + euart1: uart_emul1 { + compatible = "zephyr,uart-emul"; + current-speed = <0>; + status = "okay"; + }; + + devmux0: dev_mux_0 { + compatible = "zephyr,devmux"; + devices = <&uart0 &euart0 &euart1>; + zephyr,mutable; + status = "okay"; + }; + + devmux1: dev_mux_1 { + compatible = "zephyr,devmux"; + devices = <&uart0 &euart0 &euart1>; + zephyr,mutable; + selected = <2>; + status = "okay"; + }; +}; diff --git a/tests/drivers/console_switching/prj.conf b/tests/drivers/console_switching/prj.conf new file mode 100644 index 00000000000..fcdd67928c4 --- /dev/null +++ b/tests/drivers/console_switching/prj.conf @@ -0,0 +1,9 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_CONSOLE_SUBSYS=y +CONFIG_CONSOLE_GETLINE=y +CONFIG_DEVICE_MUTABLE=y +CONFIG_DEVMUX=y +CONFIG_UART_EMUL=y diff --git a/tests/drivers/console_switching/src/main.c b/tests/drivers/console_switching/src/main.c new file mode 100644 index 00000000000..95cde150c9b --- /dev/null +++ b/tests/drivers/console_switching/src/main.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023, Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define BUF_SIZE 32 + +/* array of const struct device* */ +#define PHANDLE_TO_DEVICE(node_id, prop, idx) DEVICE_DT_GET(DT_PHANDLE_BY_IDX(node_id, prop, idx)) +static const struct device *devs[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_DEVICE, (,))}; + +/* array of names, e.g. "euart0" */ +#define PHANDLE_TO_NAME(node_id, prop, idx) DT_NODE_FULL_NAME(DT_PHANDLE_BY_IDX(node_id, prop, idx)) +static const char *const name[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_NAME, (,))}; + +/* array of greetings, e.g. "Hello, euart0!" */ +#define PHANDLE_TO_TEXT(node_id, prop, idx) \ + "Hello, " DT_NODE_FULL_NAME(DT_PHANDLE_BY_IDX(node_id, prop, idx)) "!" +static const char *const text[] = { + DT_FOREACH_PROP_ELEM_SEP(DT_NODELABEL(devmux0), devices, PHANDLE_TO_TEXT, (,))}; + +ZTEST(console_switching, test_write) +{ + size_t normal_uart = DT_PROP(DT_NODELABEL(devmux0), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + /* for each uart_emul device */ + for (size_t i = 0, j = 0, N = ARRAY_SIZE(devs); i < 2 * N; i++, j++, j %= N) { + if (j == normal_uart) { + /* skip testing non-emul uart */ + continue; + } + + int ret[4]; + char buf[BUF_SIZE] = {0}; + + /* write text[j] to dev[j] */ + ret[0] = devmux_select_set(devmux_dev, j); + printk("%s", text[j]); + ret[1] = uart_emul_get_tx_data(devs[j], buf, ARRAY_SIZE(buf)); + ret[2] = devmux_select_set(devmux_dev, normal_uart); + + zassert_ok(ret[0], "Failed to select devmux %zu", j); + zassert_ok(ret[2], "Switching back to selection %zu failed", normal_uart); + + /* verify that text[j] was written to dev[j] */ + TC_PRINT("wrote '%s' to %s\n", buf, name[j]); + + zassert_equal(ret[1], strlen(text[j]), "Only wrote %zu/%zu bytes of '%s'", + ret[1], strlen(text[j]), text[j]); + zassert_equal(0, strcmp(text[j], buf), "Strings '%s' and '%s' do not match", + text[j], buf); + } +} + +ZTEST(console_switching, test_read) +{ + size_t normal_uart = DT_PROP(DT_NODELABEL(devmux0), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + /* for each uart_emul device */ + for (size_t i = 0, j = 0, N = ARRAY_SIZE(devs); i < 2 * N; i++, j++, j %= N) { + if (j == normal_uart) { + /* skip testing non-emul uart */ + continue; + } + + int ret[4]; + char buf[BUF_SIZE] = {0}; + + /* read text[j] from dev[j] */ + ret[0] = devmux_select_set(devmux_dev, j); + console_getline_init(); + ret[1] = uart_emul_put_rx_data(devs[j], (uint8_t *)text[j], strlen(text[j])); + ret[3] = uart_emul_put_rx_data(devs[j], "\n", 1); + snprintf(buf, BUF_SIZE, "%s", console_getline()); + ret[2] = devmux_select_set(devmux_dev, normal_uart); + + zassert_ok(ret[0], "Failed to select devmux %zu", j); + zassert_ok(ret[2], "Switching back to selection %zu failed", normal_uart); + + /* verify that text[j] was written to dev[j] */ + TC_PRINT("read '%s' from %s\n", buf, name[j]); + + zassert_equal(ret[1], strlen(text[j]), "Only put %zu/%zu bytes of '%s'", + ret[1], strlen(text[j]), text[j]); + zassert_equal(0, strcmp(text[j], buf), "Strings '%s' and '%s' do not match", + text[j], buf); + } +} + +static void *setup(void) +{ + size_t selected = DT_PROP(DT_NODELABEL(devmux1), selected); + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux1)); + + /* ensure that non-default initial selection via DT works */ + zassert_equal(devmux_select_get(devmux_dev), selected); + + return NULL; +} + +static void before(void *arg) +{ + struct device *const devmux_dev = DEVICE_DT_GET(DT_NODELABEL(devmux0)); + + zassert_ok(devmux_select_set(devmux_dev, 0)); + zassert_ok(devmux_select_get(devmux_dev)); + + for (size_t i = 1; i < ARRAY_SIZE(devs); ++i) { + uart_emul_flush_tx_data(devs[i]); + } +} + +ZTEST_SUITE(console_switching, NULL, setup, before, NULL, NULL); diff --git a/tests/drivers/console_switching/testcase.yaml b/tests/drivers/console_switching/testcase.yaml new file mode 100644 index 00000000000..0d24b5e596e --- /dev/null +++ b/tests/drivers/console_switching/testcase.yaml @@ -0,0 +1,16 @@ +common: + tags: + - drivers + - console + - emul + platform_allow: + - qemu_riscv64 + integration_platforms: + - qemu_riscv64 + +tests: + drivers.console_switching: {} + drivers.console_switching.user: + tags: userspace + extra_configs: + - CONFIG_USERSPACE=y 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"; diff --git a/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf new file mode 100644 index 00000000000..821a5e77e5b --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf b/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf new file mode 100644 index 00000000000..821a5e77e5b --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf9160dk_nrf9160_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf b/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf new file mode 100644 index 00000000000..821a5e77e5b --- /dev/null +++ b/tests/drivers/flash/common/boards/nrf9161dk_nrf9161_ns.conf @@ -0,0 +1,4 @@ +CONFIG_FCB=y +CONFIG_FLASH_MAP=y +CONFIG_SETTINGS=y +CONFIG_SETTINGS_FCB=y diff --git a/tests/drivers/flash/common/src/main.c b/tests/drivers/flash/common/src/main.c index 4e73617ba41..79d75ca9b13 100644 --- a/tests/drivers/flash/common/src/main.c +++ b/tests/drivers/flash/common/src/main.c @@ -14,9 +14,6 @@ #define TEST_AREA_DEV_NODE DT_INST(0, nordic_qspi_nor) #elif defined(CONFIG_SPI_NOR) #define TEST_AREA_DEV_NODE DT_INST(0, jedec_spi_nor) -#elif defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) -/* SoC embedded NVM */ -#define TEST_AREA slot1_ns_partition #else #define TEST_AREA storage_partition #endif diff --git a/tests/drivers/flash/common/testcase.yaml b/tests/drivers/flash/common/testcase.yaml index f7ee0b7fc6d..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: @@ -38,7 +38,7 @@ tests: drivers.flash.common.tfm_ns: build_only: true filter: (CONFIG_FLASH_HAS_DRIVER_ENABLED and CONFIG_TRUSTED_EXECUTION_NONSECURE - and dt_label_with_parent_compat_enabled("slot1_ns_partition", "fixed-partitions")) + and dt_label_with_parent_compat_enabled("storage_partition", "fixed-partitions")) integration_platforms: - nrf9161dk_nrf9161_ns drivers.flash.common.stm32: @@ -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 diff --git a/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..97702240047 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + + / { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio1 10 0>; + in-gpios = <&gpio1 11 0>; + }; +}; + +&gpiote20 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt new file mode 100644 index 00000000000..1079605a2b4 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(gpio_ite_it8xxx2_v2) + +target_include_directories(app PRIVATE + include +) + +zephyr_include_directories( + include + ${ZEPHYR_BASE}/soc/riscv/ite_ec/common + ${ZEPHYR_BASE}/soc/riscv/ite_ec/it8xxx2 +) + +target_sources(app + PRIVATE + src/main.c +) diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig new file mode 100644 index 00000000000..bb5e43e8e20 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/Kconfig @@ -0,0 +1,12 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config SOC_IT8XXX2_GPIO_GROUP_K_L_DEFAULT_PULL_DOWN + bool + default n +config HAS_ITE_INTC + bool + default y diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay new file mode 100644 index 00000000000..7f22c83ffb1 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/boards/native_sim.overlay @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/ { + intc: interrupt-controller@f03f00 { + compatible = "vnd,intc"; + #address-cells = <0>; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0x00f03f00 0x0100>; + }; + + gpioa: gpio@f01601 { + compatible = "ite,it8xxx2-gpio-v2"; + reg = <0x00f01601 1 /* GPDR (set) */ + 0x00f01618 1 /* GPDMR (get) */ + 0x00f01630 1 /* GPOTR */ + 0x00f01648 1 /* P18SCR */ + 0x00f01660 8>; /* GPCR */ + ngpios = <8>; + gpio-controller; + interrupts = <9 IRQ_TYPE_LEVEL_HIGH + 2 IRQ_TYPE_LEVEL_HIGH + 3 IRQ_TYPE_LEVEL_HIGH + 4 IRQ_TYPE_LEVEL_HIGH + 5 IRQ_TYPE_LEVEL_HIGH + 6 IRQ_TYPE_LEVEL_HIGH + 7 IRQ_TYPE_LEVEL_HIGH + 8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&intc>; + wuc-base = <0xf01b20 0xf01b20 0xf01b20 0xf01b1c + 0xf01b1c 0xf01b1c 0xf01b1c 0xf01b24>; + wuc-mask = ; + has-volt-sel = <1 1 1 1 1 1 1 1>; + #gpio-cells = <2>; + }; +}; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h new file mode 100644 index 00000000000..d3c1f7c827e --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/chip_chipregs.h @@ -0,0 +1,20 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include <../soc/riscv/ite_ec/common/chip_chipregs.h> + +/* + * Macros for emulated hardware registers access. + */ +#undef ECREG +#undef ECREG_u16 +#undef ECREG_u32 +#define ECREG(x) (*((volatile unsigned char *)fake_ecreg((intptr_t)x))) +#define ECREG_u16(x) (*((volatile unsigned short *)fake_ecreg((intptr_t)x))) +#define ECREG_u32(x) (*((volatile unsigned long *)fake_ecreg((intptr_t)x))) + +unsigned int *fake_ecreg(intptr_t r); +uint8_t ite_intc_get_irq_num(void); diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h new file mode 100644 index 00000000000..ab921224676 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/include/zephyr/arch/cpu.h @@ -0,0 +1,16 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int arch_irq_connect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags); +int arch_irq_disconnect_dynamic(unsigned int irq, unsigned int priority, + void (*routine)(const void *parameter), + const void *parameter, uint32_t flags); +typedef struct z_thread_stack_element k_thread_stack_t; diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf new file mode 100644 index 00000000000..cf7d90e583c --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/prj.conf @@ -0,0 +1,9 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_ZTEST=y +CONFIG_GPIO_ITE_IT8XXX2_V2=y +CONFIG_GPIO=y +CONFIG_DYNAMIC_INTERRUPTS=y +CONFIG_GPIO_GET_CONFIG=y diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c new file mode 100644 index 00000000000..4272fbe42f9 --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/src/main.c @@ -0,0 +1,460 @@ +/* + * Copyright 2023 The ChromiumOS Authors + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define MY_GPIO DT_NODELABEL(gpioa) + +const struct device *const gpio_dev = DEVICE_DT_GET(MY_GPIO); +static struct { + uint8_t fake; + uint8_t gpdmr; + uint8_t gpdr; + uint8_t gpotr; + uint8_t p18scr; + uint8_t wuemr, wuesr, wubemr; + uint8_t gpcr[DT_REG_SIZE_BY_IDX(MY_GPIO, 4)]; + bool clear_gpcr_before_read; +} registers; +static int callback_called; +static struct gpio_callback callback_struct; + +/* These values must match what is set in the dts overlay. */ +#define TEST_PIN 1 +#define TEST_IRQ DT_IRQ_BY_IDX(MY_GPIO, TEST_PIN, irq) +#define TEST_MASK DT_PROP_BY_IDX(MY_GPIO, wuc_mask, TEST_PIN) + +DEFINE_FFF_GLOBALS; + +uint8_t ite_intc_get_irq_num(void) +{ + return posix_get_current_irq(); +} + +unsigned int *fake_ecreg(intptr_t r) +{ + switch (r) { + case DT_REG_ADDR_BY_IDX(MY_GPIO, 0): /* GPDR */ + return (unsigned int *)®isters.gpdr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 1): /* GPDMR */ + return (unsigned int *)®isters.gpdmr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 2): /* GPOTR */ + return (unsigned int *)®isters.gpotr; + case DT_REG_ADDR_BY_IDX(MY_GPIO, 3): /* P18SCR */ + return (unsigned int *)®isters.p18scr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN): + return (unsigned int *)®isters.wuemr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN) + 1: + return (unsigned int *)®isters.wuesr; + case DT_PROP_BY_IDX(MY_GPIO, wuc_base, TEST_PIN) + 3: + return (unsigned int *)®isters.wubemr; + } + if (r >= DT_REG_ADDR_BY_IDX(MY_GPIO, 4) && + r < DT_REG_ADDR_BY_IDX(MY_GPIO, 4) + DT_REG_SIZE_BY_IDX(MY_GPIO, 4)) { + if (registers.clear_gpcr_before_read) { + registers.gpcr[r - DT_REG_ADDR_BY_IDX(MY_GPIO, 4)] = 0; + } + return (unsigned int *)®isters.gpcr[r - DT_REG_ADDR_BY_IDX(MY_GPIO, 4)]; + } + zassert_unreachable("Register access: %x", r); + return (unsigned int *)®isters.fake; +} + +static void callback(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) +{ + callback_called++; + zexpect_equal(pins, BIT(TEST_PIN)); +} + +static void before_test(void *fixture) +{ + callback_called = 0; + memset(®isters, 0, sizeof(registers)); +} + +static void after_test(void *fixture) +{ + if (callback_struct.handler != NULL) { + zassert_ok(gpio_remove_callback(gpio_dev, &callback_struct)); + } + callback_struct.handler = NULL; +} + +ZTEST_SUITE(gpio_ite_it8xxx2_v2, NULL, NULL, before_test, after_test, NULL); + +ZTEST(gpio_ite_it8xxx2_v2, test_get_active_high) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + zassert_false(gpio_pin_get(gpio_dev, TEST_PIN)); + registers.gpdmr = BIT(TEST_PIN); + zassert_true(gpio_pin_get(gpio_dev, TEST_PIN)); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_get_active_low) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_LOW)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + zassert_true(gpio_pin_get(gpio_dev, TEST_PIN)); + registers.gpdmr = BIT(TEST_PIN); + zassert_false(gpio_pin_get(gpio_dev, TEST_PIN)); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_rising) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_enable_disable) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + registers.gpdmr = 0; + + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_MODE_DISABLED)); + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt, should be ignored */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + /* Clear the missed interrupt */ + posix_sw_clear_pending_IRQ(TEST_IRQ); + registers.gpdmr = 0; + + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_ACTIVE)); + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 2, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_falling) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_TO_INACTIVE)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, TEST_MASK, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = (uint8_t)~BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_edge_both) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + + gpio_init_callback(&callback_struct, &callback, BIT(TEST_PIN)); + zassert_ok(gpio_add_callback(gpio_dev, &callback_struct)); + zassert_ok(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_EDGE_BOTH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, TEST_MASK, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, TEST_MASK, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, TEST_MASK, "wuesr=%x", registers.wuesr); + registers.wuesr = 0; + + registers.gpdmr = BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 1, "callback_called=%d", callback_called); + registers.gpdmr &= ~BIT(TEST_PIN); + /* Mock the hardware interrupt. */ + posix_sw_set_pending_IRQ(TEST_IRQ); + k_sleep(K_MSEC(100)); + zassert_equal(callback_called, 2, "callback_called=%d", callback_called); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_level_active) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zassert_equal(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_LEVEL_ACTIVE), + -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, 0, "wuesr=%x", registers.wuesr); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_interrupt_level_inactive) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH)); + zassert_equal(gpio_pin_interrupt_configure(gpio_dev, TEST_PIN, GPIO_INT_LEVEL_INACTIVE), + -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + zexpect_equal(registers.wubemr, 0, "wubemr=%x", registers.wubemr); + zexpect_equal(registers.wuemr, 0, "wuemr=%x", registers.wuemr); + zexpect_equal(registers.wuesr, 0, "wuesr=%x", registers.wuesr); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_set_active_high) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT_INACTIVE | GPIO_ACTIVE_HIGH)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, true)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, false)); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_port_toggle_bits(gpio_dev, BIT(TEST_PIN))); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 0; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 255)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 255; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 0)); + zexpect_equal(registers.gpdr, (uint8_t)~BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + + registers.gpdr = BIT(TEST_PIN); + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_HIGH, "flags=%x", flags); + registers.gpdr = 0; + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_set_active_low) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT_INACTIVE | GPIO_ACTIVE_LOW)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, true)); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + zassert_ok(gpio_pin_set(gpio_dev, TEST_PIN, false)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + zassert_ok(gpio_port_toggle_bits(gpio_dev, BIT(TEST_PIN))); + zexpect_equal(registers.gpdr, 0, "gpdr=%x", registers.gpdr); + registers.gpdr = 255; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 255)); + zexpect_equal(registers.gpdr, (uint8_t)~BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + registers.gpdr = 0; + zassert_ok(gpio_port_set_masked(gpio_dev, BIT(TEST_PIN), 0)); + zexpect_equal(registers.gpdr, BIT(TEST_PIN), "gpdr=%x", registers.gpdr); + + registers.gpdr = 0; + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW, "flags=%x", flags); + registers.gpdr = BIT(TEST_PIN); + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_HIGH, "flags=%x", flags); +} + +/* The next few tests just verify that the registers are set as expected on configure. */ + +ZTEST(gpio_ite_it8xxx2_v2, test_open_source) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OPEN_SOURCE), -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], 0, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_open_drain_output) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_OUTPUT | GPIO_OPEN_DRAIN)); + zexpect_equal(registers.gpotr, BIT(TEST_PIN), "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_OUTPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_OUTPUT_LOW | GPIO_OPEN_DRAIN, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_pull_up_input) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_PULL_UP)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], + GPCR_PORT_PIN_MODE_INPUT | GPCR_PORT_PIN_MODE_PULLUP, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | GPIO_PULL_UP, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_pull_down_input) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | GPIO_PULL_DOWN)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], + GPCR_PORT_PIN_MODE_INPUT | GPCR_PORT_PIN_MODE_PULLDOWN, "gpcr[%d]=%x", + TEST_PIN, registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | GPIO_PULL_DOWN, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_disconnected_tristate_supported) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_DISCONNECTED)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_TRISTATE, "gpcr[%d]=%x", + TEST_PIN, registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_PULL_UP | GPIO_PULL_DOWN | GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3, + "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_disconnected_tristate_unsupported) +{ + registers.clear_gpcr_before_read = true; + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_DISCONNECTED), -ENOTSUP); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_1P8V) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_1P8)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, BIT(TEST_PIN)); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_1P8, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_3P3V) +{ + gpio_flags_t flags; + + zassert_true(device_is_ready(gpio_dev)); + zassert_ok(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3)); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], GPCR_PORT_PIN_MODE_INPUT, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); + + zassert_ok(gpio_pin_get_config(gpio_dev, TEST_PIN, &flags)); + zexpect_equal(flags, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_3P3, "flags=%x", flags); +} + +ZTEST(gpio_ite_it8xxx2_v2, test_input_5V) +{ + zassert_true(device_is_ready(gpio_dev)); + zassert_equal(gpio_pin_configure(gpio_dev, TEST_PIN, GPIO_INPUT | IT8XXX2_GPIO_VOLTAGE_5P0), + -EINVAL); + zexpect_equal(registers.gpotr, 0, "gpotr=%x", registers.gpotr); + zexpect_equal(registers.p18scr, 0); + zexpect_equal(registers.gpcr[TEST_PIN], 0, "gpcr[%d]=%x", TEST_PIN, + registers.gpcr[TEST_PIN]); +} diff --git a/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml new file mode 100644 index 00000000000..67cc43b474b --- /dev/null +++ b/tests/drivers/gpio/gpio_ite_it8xxx2_v2/testcase.yaml @@ -0,0 +1,14 @@ +# Copyright 2023 The ChromiumOS Authors +# +# SPDX-License-Identifier: Apache-2.0 + +tests: + gpio.gpio_ite_it8xxx2_v2: + tags: + - drivers + - gpio + depends_on: gpio + platform_allow: + - native_sim + integration_platforms: + - native_sim diff --git a/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..8b82825a0f2 --- /dev/null +++ b/tests/drivers/i2s/i2s_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* i2s-node0 is the transmitter/receiver */ + +/ { + aliases { + i2s-node0 = &i2s20; + }; +}; + +&pinctrl { + i2s20_default_alt: i2s20_default_alt { + group1 { + psels = , + , + , + ; + }; + }; +}; + +&i2s20 { + status = "okay"; + pinctrl-0 = <&i2s20_default_alt>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..8b82825a0f2 --- /dev/null +++ b/tests/drivers/i2s/i2s_speed/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* i2s-node0 is the transmitter/receiver */ + +/ { + aliases { + i2s-node0 = &i2s20; + }; +}; + +&pinctrl { + i2s20_default_alt: i2s20_default_alt { + group1 { + psels = , + , + , + ; + }; + }; +}; + +&i2s20 { + status = "okay"; + pinctrl-0 = <&i2s20_default_alt>; + pinctrl-names = "default"; +}; diff --git a/tests/drivers/mbox/mbox_data/CMakeLists.txt b/tests/drivers/mbox/mbox_data/CMakeLists.txt new file mode 100644 index 00000000000..a410ac3d214 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +set(REMOTE_ZEPHYR_DIR ${CMAKE_CURRENT_BINARY_DIR}/../remote/zephyr) + +if(("${BOARD}" STREQUAL "mimxrt1170_evkb_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm7") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm7") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu0")) + message(STATUS "${BOARD} compile as Main in this sample") +else() + message(FATAL_ERROR "${BOARD} is not supported for this sample") +endif() + +project(mbox_data_ipc) + +enable_language(C ASM) + +if(CONFIG_INCLUDE_REMOTE_DIR) + target_include_directories(zephyr_interface + INTERFACE ${REMOTE_ZEPHYR_DIR}/include/public) +endif() + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/mbox/mbox_data/Kconfig b/tests/drivers/mbox/mbox_data/Kconfig new file mode 100644 index 00000000000..ee3874c39f9 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/Kconfig @@ -0,0 +1,11 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +source "Kconfig.zephyr" + +config INCLUDE_REMOTE_DIR + bool "Include remote core header directory" + help + Include remote build header files. Can be used if primary image + needs to be aware of size or base address of secondary image diff --git a/tests/drivers/mbox/mbox_data/Kconfig.sysbuild b/tests/drivers/mbox/mbox_data/Kconfig.sysbuild new file mode 100644 index 00000000000..2ddab228177 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/Kconfig.sysbuild @@ -0,0 +1,12 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config REMOTE_BOARD +string + default "mimxrt1170_evkb_cm4" if $(BOARD) = "mimxrt1170_evkb_cm7" + default "mimxrt1170_evk_cm4" if $(BOARD) = "mimxrt1170_evk_cm7" + default "mimxrt1160_evk_cm4" if $(BOARD) = "mimxrt1160_evk_cm7" + default "lpcxpresso55s69_cpu1" if $(BOARD) = "lpcxpresso55s69_cpu0" diff --git a/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.conf b/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.conf new file mode 100644 index 00000000000..5077d775881 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.conf @@ -0,0 +1,3 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_MBOX_NXP_MAILBOX=y +CONFIG_BUILD_OUTPUT_HEX=y diff --git a/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.overlay b/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.overlay new file mode 100644 index 00000000000..b5919c4fd72 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/lpcxpresso55s69_cpu0.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mailbox0@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.conf b/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.overlay b/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1160_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.conf b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.conf new file mode 100644 index 00000000000..583b4950360 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_INCLUDE_REMOTE_DIR=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.overlay b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evk_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.conf b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.conf new file mode 100644 index 00000000000..0dfb100ed70 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.conf @@ -0,0 +1,3 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_SECOND_CORE_MCUX=y +CONFIG_INCLUDE_REMOTE_DIR=y diff --git a/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.overlay b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.overlay new file mode 100644 index 00000000000..870b9928faf --- /dev/null +++ b/tests/drivers/mbox/mbox_data/boards/mimxrt1170_evkb_cm7.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c48000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c48000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c48000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/mbox/mbox_data/prj.conf b/tests/drivers/mbox/mbox_data/prj.conf new file mode 100644 index 00000000000..c4c2b474a7d --- /dev/null +++ b/tests/drivers/mbox/mbox_data/prj.conf @@ -0,0 +1,3 @@ +CONFIG_PRINTK=y +CONFIG_MBOX=y +CONFIG_ZTEST=y diff --git a/tests/drivers/mbox/mbox_data/remote/CMakeLists.txt b/tests/drivers/mbox/mbox_data/remote/CMakeLists.txt new file mode 100644 index 00000000000..47e1cae8628 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright 2024 NXP +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +if(("${BOARD}" STREQUAL "mimxrt1170_evkb_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1170_evk_cm4") OR + ("${BOARD}" STREQUAL "mimxrt1160_evk_cm4") OR + ("${BOARD}" STREQUAL "lpcxpresso55s69_cpu1")) + message(STATUS "${BOARD} compile as remote in this sample") +else() + message(FATAL_ERROR "${BOARD} is not supported for this sample") +endif() + +project(mbox_data_ipc_remote) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf b/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf new file mode 100644 index 00000000000..14ed92ba8f4 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.conf @@ -0,0 +1,3 @@ +CONFIG_SECOND_CORE_MCUX=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_MBOX_NXP_MAILBOX=y diff --git a/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay b/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay new file mode 100644 index 00000000000..96bd5aa1c3a --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/lpcxpresso55s69_cpu1.overlay @@ -0,0 +1,29 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /* Delete IPM Driver node nxp,lpc-mailbox */ + /delete-node/ mailbox@8b000; + + /* Attach MBOX driver to Mailbox Unit */ + mbox:mbox@5008b000 { + compatible = "nxp,mbox-mailbox"; + reg = <0x5008b000 0xEC>; + interrupts = <31 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay new file mode 100644 index 00000000000..3f6115b9c58 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1160_evk_cm4.overlay @@ -0,0 +1,54 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay new file mode 100644 index 00000000000..3f6115b9c58 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evk_cm4.overlay @@ -0,0 +1,54 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf new file mode 100644 index 00000000000..0d36a72aec6 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.conf @@ -0,0 +1,4 @@ +CONFIG_MBOX_NXP_IMX_MU=y +CONFIG_BUILD_OUTPUT_INFO_HEADER=y +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_SECOND_CORE_MCUX=y diff --git a/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay new file mode 100644 index 00000000000..e3576826702 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/boards/mimxrt1170_evkb_cm4.overlay @@ -0,0 +1,55 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,flash = &ocram; + zephyr,console = &lpuart2; + zephyr,shell-uart = &lpuart2; + + /* Delete ipc chosen property where old IPM mailbox driver bellow is + * configured. + */ + /delete-property/ zephyr,ipc; + }; + + soc { + /delete-node/ gpt@400f0000; + + /* Replace GPT2 with another GPT kernel timer */ + gpt2_hw_timer:gpt@400f0000 { + compatible = "nxp,gpt-hw-timer"; + reg = <0x400f0000 0x4000>; + interrupts = <120 0>; + status = "okay"; + }; + + /* Delete IPM Driver node nxp,imx-mu */ + /delete-node/ mailbox@40c4c000; + + /* Attach MBOX driver to MU Unit */ + mbox:mbox@40c4c000 { + compatible = "nxp,mbox-imx-mu"; + reg = <0x40c4c000 0x4000>; + interrupts = <118 0>; + rx-channels = <4>; + #mbox-cells = <1>; + status = "okay"; + }; + }; + +}; + +/* Enable secondary LPUART */ +&lpuart2 { + status = "okay"; + current-speed = <115200>; +}; + +/* Disable primary GPT timer */ +&gpt_hw_timer { + status = "disabled"; +}; diff --git a/tests/drivers/mbox/mbox_data/remote/prj.conf b/tests/drivers/mbox/mbox_data/remote/prj.conf new file mode 100644 index 00000000000..f2859becbe9 --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/prj.conf @@ -0,0 +1,3 @@ +CONFIG_STDOUT_CONSOLE=n +CONFIG_MBOX=y +# CONFIG_NO_OPTIMIZATIONS=y diff --git a/tests/drivers/mbox/mbox_data/remote/src/main.c b/tests/drivers/mbox/mbox_data/remote/src/main.c new file mode 100644 index 00000000000..d9eba4d3b7c --- /dev/null +++ b/tests/drivers/mbox/mbox_data/remote/src/main.c @@ -0,0 +1,99 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +static K_SEM_DEFINE(g_mbox_data_rx_sem, 0, 1); + +static uint32_t g_mbox_received_data; +static uint32_t g_mbox_received_channel; + +#define TX_ID0 (2) +#define RX_ID0 (3) +#define TX_ID1 (0) +#define RX_ID1 (1) +#define TX_ID2 (3) +#define RX_ID2 (2) +#define TX_ID3 (1) +#define RX_ID3 (0) + +#define CHANNELS_TO_TEST (4) +#define TX_CHANNEL_INDEX (0) +#define RX_CHANNEL_INDEX (1) +const static uint32_t TEST_CHANNELS[CHANNELS_TO_TEST][2] = { + {TX_ID0, RX_ID0}, {TX_ID1, RX_ID1}, {TX_ID2, RX_ID2}, {TX_ID3, RX_ID3}}; + +static void callback(const struct device *dev, uint32_t channel, void *user_data, + struct mbox_msg *data) +{ + if (data != NULL) { + memcpy(&g_mbox_received_data, data->data, data->size); + g_mbox_received_channel = channel; + } + + k_sem_give(&g_mbox_data_rx_sem); +} + +int main(void) +{ + struct mbox_channel tx_channel; + struct mbox_channel rx_channel; + const struct device *dev; + struct mbox_msg msg = {0}; + uint32_t message = 0; + + dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); + + const int max_transfer_size_bytes = mbox_mtu_get(dev); + /* Sample currently supports only transfer size up to 4 bytes */ + if ((max_transfer_size_bytes <= 0) || (max_transfer_size_bytes > 4)) { + printk("mbox_mtu_get() error\n"); + return 0; + } + + for (int i_test_channel = 0; i_test_channel < CHANNELS_TO_TEST; i_test_channel++) { + mbox_init_channel(&tx_channel, dev, + TEST_CHANNELS[i_test_channel][TX_CHANNEL_INDEX]); + mbox_init_channel(&rx_channel, dev, + TEST_CHANNELS[i_test_channel][RX_CHANNEL_INDEX]); + + if (mbox_register_callback(&rx_channel, callback, NULL)) { + printk("mbox_register_callback() error\n"); + return 0; + } + + if (mbox_set_enabled(&rx_channel, 1)) { + printk("mbox_set_enable() error\n"); + return 0; + } + + int test_count = 0; + + while (test_count < 100) { + test_count++; + + k_sem_take(&g_mbox_data_rx_sem, K_FOREVER); + message = g_mbox_received_data; + + message++; + + msg.data = &message; + msg.size = max_transfer_size_bytes; + + if (mbox_send(&tx_channel, &msg) < 0) { + printk("mbox_send() error\n"); + return 0; + } + } + + /* Disable current rx channel after channel loop */ + mbox_set_enabled(&rx_channel, 0); + } +} diff --git a/tests/drivers/mbox/mbox_data/src/main.c b/tests/drivers/mbox/mbox_data/src/main.c new file mode 100644 index 00000000000..82cce00ae7f --- /dev/null +++ b/tests/drivers/mbox/mbox_data/src/main.c @@ -0,0 +1,197 @@ +/* + * Copyright 2024 NXP + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +static K_SEM_DEFINE(g_mbox_data_rx_sem, 0, 1); + +static uint32_t g_mbox_received_data; +static uint32_t g_mbox_expected_data; +static uint32_t g_mbox_received_channel; +static uint32_t g_mbox_expected_channel; + +static bool g_received_size_error; +static size_t g_received_size; +static int g_max_transfer_size_bytes; + +static struct mbox_channel g_tx_channel; +static struct mbox_channel g_rx_channel; + +#define TX_ID0 (3) +#define RX_ID0 (2) +#define TX_ID1 (1) +#define RX_ID1 (0) +#define TX_ID2 (2) +#define RX_ID2 (3) +#define TX_ID3 (0) +#define RX_ID3 (1) + +#define CHANNELS_TO_TEST (4) +#define TX_CHANNEL_INDEX (0) +#define RX_CHANNEL_INDEX (1) +const static uint32_t TEST_CHANNELS[CHANNELS_TO_TEST][2] = { + {TX_ID0, RX_ID0}, {TX_ID1, RX_ID1}, {TX_ID2, RX_ID2}, {TX_ID3, RX_ID3}}; +static uint32_t current_channel_index; + +static void callback(const struct device *dev, uint32_t channel, void *user_data, + struct mbox_msg *data) +{ + /* Handle the case if received invalid size */ + if (data->size > sizeof(g_mbox_received_data)) { + g_received_size_error = true; + g_received_size = data->size; + } else { + memcpy(&g_mbox_received_data, data->data, data->size); + } + + g_mbox_received_channel = channel; + + k_sem_give(&g_mbox_data_rx_sem); +} + +static void mbox_data_tests_before(void *f) +{ + zassert_false(current_channel_index >= CHANNELS_TO_TEST, "Channel to test is out of range"); + + const struct device *dev; + int ret_val = 0; + + dev = DEVICE_DT_GET(DT_NODELABEL(mbox)); + + g_max_transfer_size_bytes = mbox_mtu_get(dev); + /* Test currently supports only transfer size up to 4 bytes */ + if ((g_max_transfer_size_bytes < 0) || (g_max_transfer_size_bytes > 4)) { + printk("mbox_mtu_get() error\n"); + zassert_false(1, "mbox invalid maximum transfer unit: %d", + g_max_transfer_size_bytes); + } + + mbox_init_channel(&g_tx_channel, dev, + TEST_CHANNELS[current_channel_index][TX_CHANNEL_INDEX]); + mbox_init_channel(&g_rx_channel, dev, + TEST_CHANNELS[current_channel_index][RX_CHANNEL_INDEX]); + + ret_val = mbox_register_callback(&g_rx_channel, callback, NULL); + zassert_false(ret_val != 0, "mbox failed to register callback. ret_val", ret_val); + + ret_val = mbox_set_enabled(&g_rx_channel, 1); + zassert_false(ret_val != 0, "mbox failed to enable mbox. ret_val: %d", ret_val); +} + +static void mbox_data_tests_after(void *f) +{ + /* Disable channel after test end */ + int ret_val = mbox_set_enabled(&g_rx_channel, 0); + + zassert_false(ret_val != 0, "mbox failed to disable mbox. ret_val: %d", ret_val); + + /* Increment current channel index to its prepared for next test */ + current_channel_index++; +} + +static void mbox_test(const uint32_t data) +{ + struct mbox_msg msg = {0}; + uint32_t test_data = data; + int test_count = 0; + int ret_val = 0; + + while (test_count < 100) { + /* Main core prepare test data */ + msg.data = &test_data; + msg.size = g_max_transfer_size_bytes; + + /* Main core send test data */ + ret_val = mbox_send(&g_tx_channel, &msg); + zassert_false(ret_val < 0, "mbox failed to send. ret_val: %d", ret_val); + + /* Expect next received data will be incremented by one. + * And based on Maximum Transfer Unit determine expected data. + * Currently supported MTU's are 1, 2, 3, and 4 bytes. + */ + g_mbox_expected_data = test_data & ~(0xFFFFFFFF << (g_max_transfer_size_bytes * 8)); + g_mbox_expected_data++; + + k_sem_take(&g_mbox_data_rx_sem, K_FOREVER); + + if (g_received_size_error) { + zassert_false(1, "mbox received invalid size in callback: %d", + g_received_size); + } + + test_data = g_mbox_received_data; + + /* Main core check received data */ + zassert_equal(g_mbox_expected_data, test_data, + "Received test_data does not match!: Expected: %08X, Got: %08X", + g_mbox_expected_data, test_data); + + /* Expect reception of data on current RX channel */ + g_mbox_expected_channel = TEST_CHANNELS[current_channel_index][RX_CHANNEL_INDEX]; + zassert_equal(g_mbox_expected_channel, g_mbox_received_channel, + "Received channel does not match!: Expected: %d, Got: %d", + g_mbox_expected_channel, g_mbox_received_channel); + + /* Increment for next send */ + test_data++; + test_count++; + } +} + +/** + * @brief MBOX Data transfer by ping pong for first set of channels + * + * This test verifies that the data transfer via MBOX. + * Main core will transfer test data to remote core. + * Remote core will increment data by one and transfer it back to Main core. + * Main core will check that data it sent to remote core was incremented by one. + * Main core will again increment test data by one, send it to remote core and repeat 100 times. + */ +ZTEST(mbox_data_tests, test_ping_pong_1) +{ + mbox_test(0xADADADAD); +} + +/** + * @brief MBOX Data transfer by ping pong for second set of channels + * + * Description same as for test_ping_pong_1 + * + */ +ZTEST(mbox_data_tests, test_ping_pong_2) +{ + mbox_test(0xDADADADA); +} + +/** + * @brief MBOX Data transfer by ping pong for third set of channels + * + * Description same as for test_ping_pong_1 + * + */ +ZTEST(mbox_data_tests, test_ping_pong_3) +{ + mbox_test(0xADADADAD); +} + +/** + * @brief MBOX Data transfer by ping pong for forth set of channels + * + * Description same as for test_ping_pong_1 + * + */ +ZTEST(mbox_data_tests, test_ping_pong_4) +{ + mbox_test(0xDADADADA); +} + +ZTEST_SUITE(mbox_data_tests, NULL, NULL, mbox_data_tests_before, mbox_data_tests_after, NULL); diff --git a/tests/drivers/mbox/mbox_data/sysbuild.cmake b/tests/drivers/mbox/mbox_data/sysbuild.cmake new file mode 100644 index 00000000000..5c536a6229a --- /dev/null +++ b/tests/drivers/mbox/mbox_data/sysbuild.cmake @@ -0,0 +1,28 @@ +# Copyright 2024 NXP +# +# 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 "mimxrt1170_evkb_cm7" OR + "${BOARD}" STREQUAL "mimxrt1170_evk_cm7" OR + "${BOARD}" STREQUAL "mimxrt1160_evk_cm7" + ) + # For these NXP boards the main core application is dependent on + # 'zephyr_image_info.h' generated by remote application. + + # Let's build the remote application first + add_dependencies(${DEFAULT_IMAGE} ${REMOTE_APP}) +endif() diff --git a/tests/drivers/mbox/mbox_data/testcase.yaml b/tests/drivers/mbox/mbox_data/testcase.yaml new file mode 100644 index 00000000000..72aff63ac3a --- /dev/null +++ b/tests/drivers/mbox/mbox_data/testcase.yaml @@ -0,0 +1,14 @@ +tests: + drivers.mbox_data: + tags: + - drivers + - mbox + sysbuild: true + platform_allow: + - mimxrt1170_evkb_cm7 + - mimxrt1170_evk_cm7 + - mimxrt1160_evk_cm7 + - lpcxpresso55s69_cpu0 + integration_platforms: + - mimxrt1170_evkb_cm7 + - lpcxpresso55s69_cpu0 diff --git a/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..f2e84b72f9b --- /dev/null +++ b/tests/drivers/spi/spi_loopback/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spi00_default: spi00_default { + group1 { + psels = , + , + ; + }; + }; + + spi00_sleep: spi00_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; +}; + +&spi00 { + status = "okay"; + pinctrl-0 = <&spi00_default>; + pinctrl-1 = <&spi00_sleep>; + pinctrl-names = "default", "sleep"; + overrun-character = <0x00>; + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = ; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = ; + }; +}; + +&gpio2 { + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..033aab401ac --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + chosen { + zephyr,console = &uart20; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/drivers/uart/uart_async_api/testcase.yaml b/tests/drivers/uart/uart_async_api/testcase.yaml index e9914d48d99..3c5f2d5583e 100644 --- a/tests/drivers/uart/uart_async_api/testcase.yaml +++ b/tests/drivers/uart/uart_async_api/testcase.yaml @@ -13,6 +13,7 @@ tests: harness_config: fixture: gpio_loopback depends_on: gpio + tags: bsim_skip_CI drivers.uart.wide: filter: CONFIG_UART_CONSOLE and CONFIG_SERIAL_SUPPORT_ASYNC and not CONFIG_UART_MCUX_LPUART harness: ztest @@ -25,6 +26,15 @@ tests: platform_allow: nucleo_h743zi integration_platforms: - nucleo_h743zi + drivers.uart.async_api.nrf_uarte_legacy: + platform_allow: nrf52840dk_nrf52840 nrf52_bsim + filter: CONFIG_SERIAL_SUPPORT_ASYNC + harness: ztest + harness_config: + fixture: gpio_loopback + depends_on: gpio + extra_configs: + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.async_api.nrf_uart: filter: CONFIG_UART_CONSOLE and CONFIG_SERIAL_SUPPORT_ASYNC harness: ztest diff --git a/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..945b8628e7a --- /dev/null +++ b/tests/drivers/uart/uart_mix_fifo_poll/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; + hw-flow-control; +}; + +counter_dev: &timer00 { + status = "okay"; +}; + +&grtc { + interrupts = <228 2>; +}; diff --git a/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml b/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml index 65848e6603e..c2196c1058d 100644 --- a/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml +++ b/tests/drivers/uart/uart_mix_fifo_poll/testcase.yaml @@ -18,22 +18,22 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_fifo: extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=y - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_async_api: extra_configs: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + tags: bsim_skip_CI drivers.uart.uart_mix_poll_async_api_const: extra_args: TEST_CONST_BUFFER=1 @@ -41,22 +41,9 @@ tests: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - - CONFIG_UART_0_ENHANCED_POLL_OUT=n - - CONFIG_UART_ASYNC_TX_CACHE_SIZE=2 - - drivers.uart.uart_mix_poll_async_api_low_power: - extra_configs: - - CONFIG_UART_ASYNC_API=y - - CONFIG_UART_0_INTERRUPT_DRIVEN=n - - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_0_TX_CACHE_SIZE=2 + tags: bsim_skip_CI # We skip a few tests to save CI time, as they give little extra coverage drivers.uart.uart_mix_poll_with_ppi: extra_configs: @@ -75,18 +62,29 @@ tests: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=y - drivers.uart.uart_mix_poll_async_api_with_ppi_low_power: + drivers.uart.legacy.uart_mix_poll: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=n + - CONFIG_UART_ASYNC_API=n + - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y + + drivers.uart.legacy.uart_mix_poll_fifo: + extra_configs: + - CONFIG_UART_INTERRUPT_DRIVEN=y + - CONFIG_UART_0_INTERRUPT_DRIVEN=y + - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y + + drivers.uart.legacy.uart_mix_poll_async_api: extra_configs: - CONFIG_UART_ASYNC_API=y - CONFIG_UART_0_INTERRUPT_DRIVEN=n - CONFIG_UART_0_ASYNC=y + - CONFIG_UART_0_ENHANCED_POLL_OUT=n - CONFIG_UART_0_NRF_HW_ASYNC=y - - CONFIG_UART_0_NRF_ASYNC_LOW_POWER=y - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y diff --git a/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..033aab401ac --- /dev/null +++ b/tests/drivers/uart/uart_pm/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + chosen { + zephyr,console = &uart20; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/tests/drivers/uart/uart_pm/testcase.yaml b/tests/drivers/uart/uart_pm/testcase.yaml index efb76ecf2c1..4d71ed881cd 100644 --- a/tests/drivers/uart/uart_pm/testcase.yaml +++ b/tests/drivers/uart/uart_pm/testcase.yaml @@ -13,12 +13,14 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.no_rxpin: extra_configs: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y extra_args: DTC_OVERLAY_FILE="boards/nrf52840dk_nrf52840.overlay;nrf_rx_disable.overlay" drivers.uart.pm.enhanced_poll: @@ -26,6 +28,7 @@ tests: - CONFIG_UART_INTERRUPT_DRIVEN=n - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.int_driven: extra_configs: @@ -33,6 +36,7 @@ tests: - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.int_driven.enhanced_poll: extra_configs: @@ -40,6 +44,7 @@ tests: - CONFIG_UART_0_INTERRUPT_DRIVEN=y - CONFIG_UART_ASYNC_API=n - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.async: extra_configs: @@ -50,6 +55,7 @@ tests: - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=n + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y drivers.uart.pm.async.enhanced_poll: extra_configs: @@ -60,3 +66,4 @@ tests: - CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 - CONFIG_NRFX_TIMER2=y - CONFIG_UART_0_ENHANCED_POLL_OUT=y + - CONFIG_UART_NRFX_UARTE_LEGACY_SHIM=y diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..aa2789dd45e --- /dev/null +++ b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wdt30 { + status = "okay"; +}; diff --git a/tests/kernel/common/testcase.yaml b/tests/kernel/common/testcase.yaml index 721d4bb9c3d..ae9c39c8fb5 100644 --- a/tests/kernel/common/testcase.yaml +++ b/tests/kernel/common/testcase.yaml @@ -43,3 +43,10 @@ tests: tags: picolibc extra_configs: - CONFIG_PICOLIBC=y + kernel.common.lto: + filter: CONFIG_ISR_TABLES_LOCAL_DECLARATION_SUPPORTED + tags: lto + extra_configs: + - CONFIG_TEST_USERSPACE=n + - CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + - CONFIG_LTO=y diff --git a/tests/kernel/context/src/main.c b/tests/kernel/context/src/main.c index 2e3ad1a36c9..a138e012280 100644 --- a/tests/kernel/context/src/main.c +++ b/tests/kernel/context/src/main.c @@ -72,11 +72,10 @@ extern const int32_t z_sys_timer_irq_for_test; #endif -/* Cortex-M1, Nios II, and RISCV without CONFIG_RISCV_HAS_CPU_IDLE - * do have a power saving instruction, so k_cpu_idle() returns immediately +/* Cortex-M1 and Nios II do have a power saving instruction, so k_cpu_idle() + * returns immediately */ -#if !defined(CONFIG_CPU_CORTEX_M1) && !defined(CONFIG_NIOS2) && \ - (!defined(CONFIG_RISCV) || defined(CONFIG_RISCV_HAS_CPU_IDLE)) +#if !defined(CONFIG_CPU_CORTEX_M1) && !defined(CONFIG_NIOS2) #define HAS_POWERSAVE_INSTRUCTION #endif diff --git a/tests/kernel/gen_isr_table/testcase.yaml b/tests/kernel/gen_isr_table/testcase.yaml index cd8c95e2584..eb8babe3635 100644 --- a/tests/kernel/gen_isr_table/testcase.yaml +++ b/tests/kernel/gen_isr_table/testcase.yaml @@ -4,12 +4,12 @@ common: - interrupt - isr_table tests: - arch.interrupt.gen_isr_table.arm_baseline: + arch.interrupt.gen_isr_table.arm_baseline: &arm-baseline platform_allow: qemu_cortex_m3 filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV6_M_ARMV8_M_BASELINE extra_configs: - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y - arch.interrupt.gen_isr_table.arm_baseline.linker_generator: + arch.interrupt.gen_isr_table.arm_baseline.linker_generator: &arm-baseline-linker-generator platform_allow: qemu_cortex_m3 filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV6_M_ARMV8_M_BASELINE tags: @@ -17,7 +17,7 @@ tests: extra_configs: - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y - CONFIG_CMAKE_LINKER_GENERATOR=y - arch.interrupt.gen_isr_table.arm_mainline: + arch.interrupt.gen_isr_table.arm_mainline: &arm-mainline platform_allow: qemu_cortex_m3 platform_exclude: - stmf103_mini @@ -40,6 +40,27 @@ tests: - CONFIG_GEN_ISR_TABLES=n - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y build_only: true + + arch.interrupt.gen_isr_table_local.arm_baseline: + <<: *arm-baseline + filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV6_M_ARMV8_M_BASELINE and not CONFIG_USERSPACE + extra_configs: + - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + - CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + arch.interrupt.gen_isr_table_local.arm_baseline.linker_generator: + <<: *arm-baseline-linker-generator + filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV6_M_ARMV8_M_BASELINE and not CONFIG_USERSPACE + extra_configs: + - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + - CONFIG_CMAKE_LINKER_GENERATOR=y + - CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + arch.interrupt.gen_isr_table_local.arm_mainline: + <<: *arm-mainline + filter: CONFIG_GEN_ISR_TABLES and CONFIG_ARMV6_M_ARMV8_M_BASELINE and not CONFIG_USERSPACE + extra_configs: + - CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + - CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + arch.interrupt.gen_isr_table.arc: arch_allow: arc filter: CONFIG_RGF_NUM_BANKS > 1 @@ -53,7 +74,7 @@ tests: platform_exclude: - m2gl025_miv - adp_xc7k_ae350 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_GEN_IRQ_VECTOR_TABLE=y arch.interrupt.gen_isr_table.riscv_no_direct: @@ -61,18 +82,18 @@ tests: arch_allow: - riscv32 - riscv64 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_GEN_IRQ_VECTOR_TABLE=n arch.interrupt.gen_isr_table.bit_shift_2nd_level: platform_allow: qemu_riscv32 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_1ST_LEVEL_INTERRUPT_BITS=10 - CONFIG_2ND_LEVEL_INTERRUPT_BITS=10 arch.interrupt.gen_isr_table.bit_shift_3rd_level: platform_allow: qemu_riscv32 - filter: CONFIG_SOC_FAMILY_RISCV_PRIVILEGED + filter: CONFIG_RISCV_PRIVILEGED extra_configs: - CONFIG_MULTI_LEVEL_INTERRUPTS=y - CONFIG_2ND_LEVEL_INTERRUPTS=y diff --git a/tests/kernel/interrupt/src/test_shared_irq.h b/tests/kernel/interrupt/src/test_shared_irq.h index fd3c4c4a624..5ddd50a16e1 100644 --- a/tests/kernel/interrupt/src/test_shared_irq.h +++ b/tests/kernel/interrupt/src/test_shared_irq.h @@ -41,7 +41,7 @@ static inline bool client_exists_at_index(void (*routine)(const void *arg), { size_t i; struct z_shared_isr_table_entry *shared_entry; - struct z_shared_isr_client *client; + struct _isr_table_entry *client; shared_entry = &z_shared_sw_isr_table[irq]; diff --git a/tests/kernel/interrupt/testcase.yaml b/tests/kernel/interrupt/testcase.yaml index cbe58c65e47..47cbba93e0d 100644 --- a/tests/kernel/interrupt/testcase.yaml +++ b/tests/kernel/interrupt/testcase.yaml @@ -52,3 +52,23 @@ tests: extra_configs: - CONFIG_SHARED_INTERRUPTS=y filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE + arch.shared_interrupt.lto: + # 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 + - lto + extra_configs: + - CONFIG_SHARED_INTERRUPTS=y + - CONFIG_TEST_USERSPACE=n + - CONFIG_ISR_TABLES_LOCAL_DECLARATION=y + - CONFIG_LTO=y + filter: not CONFIG_TRUSTED_EXECUTION_NONSECURE and CONFIG_ISR_TABLES_LOCAL_DECLARATION_SUPPORTED diff --git a/tests/kernel/sched/schedule_api/prj.conf b/tests/kernel/sched/schedule_api/prj.conf index fe5125047e3..785e9a3987b 100644 --- a/tests/kernel/sched/schedule_api/prj.conf +++ b/tests/kernel/sched/schedule_api/prj.conf @@ -7,3 +7,4 @@ CONFIG_MAX_THREAD_BYTES=5 CONFIG_TEST_USERSPACE=y CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/kernel/sched/schedule_api/prj_dumb.conf b/tests/kernel/sched/schedule_api/prj_dumb.conf index c0ddfbd7c3f..a1d0cf6dced 100644 --- a/tests/kernel/sched/schedule_api/prj_dumb.conf +++ b/tests/kernel/sched/schedule_api/prj_dumb.conf @@ -5,3 +5,4 @@ CONFIG_SCHED_DUMB=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/kernel/sched/schedule_api/prj_multiq.conf b/tests/kernel/sched/schedule_api/prj_multiq.conf index 18d04dd8656..77b3a49fd34 100644 --- a/tests/kernel/sched/schedule_api/prj_multiq.conf +++ b/tests/kernel/sched/schedule_api/prj_multiq.conf @@ -5,3 +5,4 @@ CONFIG_SCHED_MULTIQ=y CONFIG_MAX_THREAD_BYTES=5 CONFIG_MP_MAX_NUM_CPUS=1 CONFIG_ZTEST_FATAL_HOOK=y +CONFIG_MINIMAL_LIBC=y diff --git a/tests/lib/cpp/cxx/testcase.yaml b/tests/lib/cpp/cxx/testcase.yaml index 77d1b06dbb2..d1a7235a84c 100644 --- a/tests/lib/cpp/cxx/testcase.yaml +++ b/tests/lib/cpp/cxx/testcase.yaml @@ -34,6 +34,11 @@ tests: # -std=c++98) cpp.main.cpp98: arch_exclude: posix + # Exclude nRF54L15 and nRF54H20 as Nordic HAL is not compatible with C++98. + platform_exclude: + - nrf54l15pdk_nrf54l15_cpuapp + - nrf54h20pdk_nrf54h20_cpuapp + - nrf54h20pdk_nrf54h20_cpurad build_only: true extra_configs: - CONFIG_STD_CPP98=y 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 diff --git a/tests/misc/iterable_sections/CMakeLists.txt b/tests/misc/iterable_sections/CMakeLists.txt index 24472eb8574..1a187eace6d 100644 --- a/tests/misc/iterable_sections/CMakeLists.txt +++ b/tests/misc/iterable_sections/CMakeLists.txt @@ -12,9 +12,11 @@ zephyr_iterable_section(NAME test_ram GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} zephyr_iterable_section(NAME test_ram2 GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME test_ram_named GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_iterable_section(NAME test_ram_numeric NUMERIC GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +zephyr_iterable_section(NAME ramn_alt GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) zephyr_linker_sources(SECTIONS sections-rom.ld) zephyr_iterable_section(NAME test_rom KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom2 KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom_named KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) zephyr_iterable_section(NAME test_rom_numeric NUMERIC KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) +zephyr_iterable_section(NAME romn_alt KVMA RAM_REGION GROUP RODATA_REGION SUBALIGN 4) diff --git a/tests/misc/iterable_sections/sections-ram.ld b/tests/misc/iterable_sections/sections-ram.ld index c7c86a8d97c..96454fb282d 100644 --- a/tests/misc/iterable_sections/sections-ram.ld +++ b/tests/misc/iterable_sections/sections-ram.ld @@ -4,3 +4,4 @@ ITERABLE_SECTION_RAM(test_ram, 4) ITERABLE_SECTION_RAM(test_ram2, 4) ITERABLE_SECTION_RAM(test_ram_named, 4) ITERABLE_SECTION_RAM_NUMERIC(test_ram_numeric, 4) +ITERABLE_SECTION_RAM(ramn_alt, 4) diff --git a/tests/misc/iterable_sections/sections-rom.ld b/tests/misc/iterable_sections/sections-rom.ld index c837cbfbc4b..525c480c7bf 100644 --- a/tests/misc/iterable_sections/sections-rom.ld +++ b/tests/misc/iterable_sections/sections-rom.ld @@ -4,3 +4,4 @@ ITERABLE_SECTION_ROM(test_rom, 4) ITERABLE_SECTION_ROM(test_rom2, 4) ITERABLE_SECTION_ROM(test_rom_named, 4) ITERABLE_SECTION_ROM_NUMERIC(test_rom_numeric, 4) +ITERABLE_SECTION_ROM(romn_alt, 4) diff --git a/tests/misc/iterable_sections/src/main.c b/tests/misc/iterable_sections/src/main.c index e5d697b8a80..a2dde51bd23 100644 --- a/tests/misc/iterable_sections/src/main.c +++ b/tests/misc/iterable_sections/src/main.c @@ -44,6 +44,12 @@ const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_10) = {0x03}; const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_11) = {0x04}; const STRUCT_SECTION_ITERABLE(test_ram_numeric, ramn_3) = {0x02}; +#define NAMED_ALT_EXPECT 0x4273 + +/* alternate naming */ +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, R, ramn_42) = {0x42}; +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_ram_named, ramn_alt, W, ramn_73) = {0x73}; + /** * * @brief Test iterable in read write section. @@ -89,6 +95,13 @@ ZTEST(iterable_sections, test_ram) } zassert_equal(out, RAM_EXPECT, "Check value incorrect (got: 0x%x)", out); + + out = 0; + STRUCT_SECTION_FOREACH_ALTERNATE(ramn_alt, test_ram_named, t) { + out = (out << 8) | t->i; + } + + zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out); } struct test_rom { @@ -126,6 +139,10 @@ const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_10) = {0x30}; const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_11) = {0x40}; const STRUCT_SECTION_ITERABLE(test_rom_numeric, romn_3) = {0x20}; +/* alternate naming */ +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, R, romn_73) = {0x73}; +const STRUCT_SECTION_ITERABLE_NAMED_ALTERNATE(test_rom_named, romn_alt, O, romn_42) = {0x42}; + /** * * @brief Test iterable in read only section. @@ -161,6 +178,13 @@ ZTEST(iterable_sections, test_rom) } zassert_equal(out, ROM_EXPECT, "Check value incorrect (got: 0x%x)", out); + + out = 0; + STRUCT_SECTION_FOREACH_ALTERNATE(romn_alt, test_rom_named, t) { + out = (out << 8) | t->i; + } + + zassert_equal(out, NAMED_ALT_EXPECT, "Check value incorrect (got: 0x%x)", out); } ZTEST_SUITE(iterable_sections, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/lib/coap/src/main.c b/tests/net/lib/coap/src/main.c index c9d0456d332..d1903dea10c 100644 --- a/tests/net/lib/coap/src/main.c +++ b/tests/net/lib/coap/src/main.c @@ -779,7 +779,7 @@ ZTEST(coap, test_retransmit_second_round) zassert_not_null(pending, "No free pending"); r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, - CONFIG_COAP_MAX_RETRANSMIT); + NULL); zassert_equal(r, 0, "Could not initialize packet"); /* We "send" the packet the first time here */ @@ -1718,4 +1718,57 @@ ZTEST(coap, test_coap_packet_set_path) COAP_OPTION_URI_PATH); } +ZTEST(coap, test_transmission_parameters) +{ + struct coap_packet cpkt; + struct coap_pending *pending; + struct coap_transmission_parameters params; + uint8_t *data = data_buf[0]; + int r; + uint16_t id; + + params = coap_get_transmission_parameters(); + zassert_equal(params.ack_timeout, CONFIG_COAP_INIT_ACK_TIMEOUT_MS, "Wrong ACK timeout"); + zassert_equal(params.coap_backoff_percent, CONFIG_COAP_BACKOFF_PERCENT, + "Wrong backoff percent"); + zassert_equal(params.max_retransmission, CONFIG_COAP_MAX_RETRANSMIT, + "Wrong max retransmission value"); + + params.ack_timeout = 1000; + params.coap_backoff_percent = 150; + params.max_retransmission = 2; + + coap_set_transmission_parameters(¶ms); + + id = coap_next_id(); + + r = coap_packet_init(&cpkt, data, COAP_BUF_SIZE, COAP_VERSION_1, + COAP_TYPE_CON, 0, coap_next_token(), + COAP_METHOD_GET, id); + zassert_equal(r, 0, "Could not initialize packet"); + + pending = coap_pending_next_unused(pendings, NUM_PENDINGS); + zassert_not_null(pending, "No free pending"); + + params.ack_timeout = 3000; + params.coap_backoff_percent = 250; + params.max_retransmission = 3; + + r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, + ¶ms); + zassert_equal(r, 0, "Could not initialize packet"); + + zassert_equal(pending->params.ack_timeout, 3000, "Wrong ACK timeout"); + zassert_equal(pending->params.coap_backoff_percent, 250, "Wrong backoff percent"); + zassert_equal(pending->params.max_retransmission, 3, "Wrong max retransmission value"); + + r = coap_pending_init(pending, &cpkt, (struct sockaddr *) &dummy_addr, + NULL); + zassert_equal(r, 0, "Could not initialize packet"); + + zassert_equal(pending->params.ack_timeout, 1000, "Wrong ACK timeout"); + zassert_equal(pending->params.coap_backoff_percent, 150, "Wrong backoff percent"); + zassert_equal(pending->params.max_retransmission, 2, "Wrong max retransmission value"); +} + ZTEST_SUITE(coap, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/lib/coap_client/CMakeLists.txt b/tests/net/lib/coap_client/CMakeLists.txt index 2e94112f0b0..cb86d78f611 100644 --- a/tests/net/lib/coap_client/CMakeLists.txt +++ b/tests/net/lib/coap_client/CMakeLists.txt @@ -27,3 +27,5 @@ add_compile_definitions(CONFIG_COAP_LOG_LEVEL=4) 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) +add_compile_definitions(CONFIG_COAP_MAX_RETRANSMIT=4) +add_compile_definitions(CONFIG_COAP_BACKOFF_PERCENT=200) diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c index e1240c5e2ed..7d99c738950 100644 --- a/tests/net/lib/coap_client/src/main.c +++ b/tests/net/lib/coap_client/src/main.c @@ -378,7 +378,7 @@ ZTEST(coap_client, test_get_request) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -409,7 +409,7 @@ ZTEST(coap_client, test_resend_request) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(300)); set_socket_events(ZSOCK_POLLIN); @@ -441,7 +441,7 @@ ZTEST(coap_client, test_echo_option) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -472,7 +472,7 @@ ZTEST(coap_client, test_echo_option_next_req) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -487,7 +487,7 @@ ZTEST(coap_client, test_echo_option_next_req) client_request.len = strlen(payload); LOG_INF("Send next request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -516,7 +516,7 @@ ZTEST(coap_client, test_get_no_path) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_equal(ret, -EINVAL, "Get request without path"); } @@ -541,7 +541,7 @@ ZTEST(coap_client, test_send_large_data) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -563,6 +563,11 @@ ZTEST(coap_client, test_no_response) .payload = NULL, .len = 0 }; + struct coap_transmission_parameters params = { + .ack_timeout = 200, + .coap_backoff_percent = 200, + .max_retransmission = 0 + }; client_request.payload = short_payload; client_request.len = strlen(short_payload); @@ -571,7 +576,7 @@ ZTEST(coap_client, test_no_response) LOG_INF("Send request"); clear_socket_events(); - ret = coap_client_req(&client, 0, &address, &client_request, 0); + ret = coap_client_req(&client, 0, &address, &client_request, ¶ms); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(300)); @@ -601,7 +606,7 @@ ZTEST(coap_client, test_separate_response) k_sleep(K_MSEC(1)); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -632,10 +637,10 @@ ZTEST(coap_client, test_multiple_requests) set_socket_events(ZSOCK_POLLIN); LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); - ret = coap_client_req(&client, 0, &address, &client_request, -1); + ret = coap_client_req(&client, 0, &address, &client_request, NULL); zassert_true(ret >= 0, "Sending request failed, %d", ret); k_sleep(K_MSEC(5)); @@ -660,6 +665,11 @@ ZTEST(coap_client, test_unmatching_tokens) .payload = NULL, .len = 0 }; + struct coap_transmission_parameters params = { + .ack_timeout = 200, + .coap_backoff_percent = 200, + .max_retransmission = 0 + }; client_request.payload = short_payload; client_request.len = strlen(short_payload); @@ -667,7 +677,7 @@ ZTEST(coap_client, test_unmatching_tokens) z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_unmatching; LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, 0); + ret = coap_client_req(&client, 0, &address, &client_request, ¶ms); zassert_true(ret >= 0, "Sending request failed, %d", ret); set_socket_events(ZSOCK_POLLIN); @@ -675,4 +685,5 @@ ZTEST(coap_client, test_unmatching_tokens) k_sleep(K_MSEC(1)); clear_socket_events(); k_sleep(K_MSEC(500)); + zassert_equal(last_response_code, -ETIMEDOUT, "Unexpected response"); } diff --git a/tests/net/lib/coap_server/common/src/main.c b/tests/net/lib/coap_server/common/src/main.c index 7af940c5360..20c4b7c0317 100644 --- a/tests/net/lib/coap_server/common/src/main.c +++ b/tests/net/lib/coap_server/common/src/main.c @@ -48,7 +48,7 @@ COAP_RESOURCE_DEFINE(resource_1, service_A, { }); static uint16_t service_B_port; -COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, COAP_SERVICE_AUTOSTART); +COAP_SERVICE_DEFINE(service_B, "b.service.com", &service_B_port, 0); static const char * const resource_2_path[] = { "res2", "sub", NULL }; COAP_RESOURCE_DEFINE(resource_2, service_B, { @@ -132,7 +132,7 @@ ZTEST(coap_service, test_COAP_SERVICE_FOREACH) 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); + zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0); } else if (svc == &service_C) { have_service_C = 1; zassert_equal(svc->flags & COAP_SERVICE_AUTOSTART, 0); diff --git a/tests/net/lib/lwm2m/interop/README.md b/tests/net/lib/lwm2m/interop/README.md index bda38924d26..7df931203aa 100644 --- a/tests/net/lib/lwm2m/interop/README.md +++ b/tests/net/lib/lwm2m/interop/README.md @@ -125,9 +125,17 @@ Tests are written from test spec; |---------|------|-----| |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-2 - Client Initiated Bootstrap Full (Cert) | |testcase not implemented | +|LightweightM2M-1.1-int-3 – Simple Bootstrap from Smartcard |:large_orange_diamond:|We don't have any smartcard support.| +|LightweightM2M-1.1-int-4 - Bootstrap Delete |:white_check_mark:| | +|LightweightM2M-1.1-int-5 - Server Initiated Bootstrap |:white_check_mark:| | +|LightweightM2M-1.1-int-6 - Bootstrap Sequence |:white_check_mark:| | +|LightweightM2M-1.1-int-7 - Fallback to bootstrap |:white_check_mark:| | +|LightweightM2M-1.1-int-8 - Bootstrap Read | |Test cannot be implemented from client side.| +|LightweightM2M-1.1-int-9 - Bootstrap and Configuration Consistency | |testcase not implemented | |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-103 - Deregistration |:white_check_mark:| | |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:| | @@ -160,21 +168,21 @@ Tests are written from test spec; |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-235 - Read-Composite Operation on root path|:white_check_mark:| | |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-261 - Write-Attribute Operation on a multiple resource|:white_check_mark:| | |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-303 - Cancel observations using Observe with Cancel parameter|:white_check_mark:|| |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-305 - Cancel Observation-Composite Operation|:white_check_mark:| | |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)| diff --git a/tests/net/lib/lwm2m/interop/prj.conf b/tests/net/lib/lwm2m/interop/prj.conf index 07bd9a0535d..6115e6f40e3 100644 --- a/tests/net/lib/lwm2m/interop/prj.conf +++ b/tests/net/lib/lwm2m/interop/prj.conf @@ -18,6 +18,9 @@ CONFIG_LWM2M=y CONFIG_LWM2M_IPSO_SUPPORT=y CONFIG_LWM2M_SHELL=y +CONFIG_LWM2M_TICKLESS=y +CONFIG_NET_SOCKETPAIR=y + #Enable Portfolio object CONFIG_LWM2M_PORTFOLIO_OBJ_SUPPORT=y @@ -44,6 +47,11 @@ CONFIG_LWM2M_RW_OMA_TLV_SUPPORT=y CONFIG_COAP_EXTENDED_OPTIONS_LEN=y CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=40 +# Speed up testing, we are running in non-lossy network +CONFIG_COAP_INIT_ACK_TIMEOUT_MS=1000 +CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT=n +CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES=2 + # Use QUEUE mode by default CONFIG_LWM2M_QUEUE_MODE_ENABLED=y CONFIG_LWM2M_QUEUE_MODE_UPTIME=20 diff --git a/tests/net/lib/lwm2m/interop/pytest/conftest.py b/tests/net/lib/lwm2m/interop/pytest/conftest.py index 9ca971b85c7..7d3ea4e7f80 100644 --- a/tests/net/lib/lwm2m/interop/pytest/conftest.py +++ b/tests/net/lib/lwm2m/interop/pytest/conftest.py @@ -27,6 +27,25 @@ logger = logging.getLogger(__name__) +class Endpoint: + def __init__(self, name: str, shell: Shell, registered: bool = False, bootstrap: bool = False): + self.name = name + self.registered = registered + self.bootstrap = bootstrap + self.shell = shell + self.last_update = 0.0 + + def check_update(self): + if not self.registered: + return + if self.last_update < time.time() - 5: + self.shell.exec_command('lwm2m update') + self.last_update = time.time() + + def __str__(self): + return self.name + + @pytest.fixture(scope='session') def leshan() -> Leshan: """ @@ -89,9 +108,8 @@ def endpoint_nosec(shell: Shell, dut: DeviceAdapter, leshan: Leshan) -> str: 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 + yield Endpoint(ep, shell) # All done shell.exec_command('lwm2m stop') @@ -125,7 +143,7 @@ def endpoint_bootstrap(shell: Shell, dut: DeviceAdapter, leshan: Leshan, leshan_ shell.exec_command(f'lwm2m write 0/0/5 -s {bs_passwd}') shell.exec_command(f'lwm2m start {ep} -b 1') - yield ep + yield Endpoint(ep, shell) shell.exec_command('lwm2m stop') dut.readlines_until(regex=r'.*Deregistration success', timeout=10.0) @@ -137,12 +155,16 @@ def endpoint_bootstrap(shell: Shell, dut: DeviceAdapter, leshan: Leshan, leshan_ leshan_bootstrap.delete_bs_device(ep) @pytest.fixture(scope='module') -def endpoint_registered(endpoint_bootstrap, shell: Shell, dut: DeviceAdapter) -> str: +def endpoint_registered(endpoint_bootstrap, dut: DeviceAdapter) -> str: """Fixture that returns an endpoint that is registered.""" - dut.readlines_until(regex='.*Registration Done', timeout=5.0) + if not endpoint_bootstrap.registered: + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + endpoint_bootstrap.bootstrap = True + endpoint_bootstrap.registered = True return endpoint_bootstrap -@pytest.fixture(scope='module') +@pytest.fixture(scope='function') def endpoint(endpoint_registered) -> str: """Fixture that returns an endpoint that is registered.""" + endpoint_registered.check_update() return endpoint_registered diff --git a/tests/net/lib/lwm2m/interop/pytest/leshan.py b/tests/net/lib/lwm2m/interop/pytest/leshan.py index 7240aae2baf..181f15ebf61 100644 --- a/tests/net/lib/lwm2m/interop/pytest/leshan.py +++ b/tests/net/lib/lwm2m/interop/pytest/leshan.py @@ -62,9 +62,9 @@ def get(self, path: str): 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): + def put_raw(self, path: str, data: str | dict | None = None, headers: dict | None = None, params: 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) + resp = self._s.put(f'{self.api_url}{path}', data=data, headers=headers, params=params, timeout=self.timeout) return Leshan.handle_response(resp) def put(self, path: str, data: str | dict, uri_options: str = ''): @@ -108,6 +108,21 @@ def write(self, endpoint: str, path: str, value: bool | int | str): rid = path.split('/')[-1] return self.put(f'/clients/{endpoint}/{path}', self._define_resource(rid, value, kind)) + def write_attributes(self, endpoint: str, path: str, attributes: dict): + """Send LwM2M Write-Attributes to given path + example: + leshan.write_attributes(endpoint, '1/2/3, {'pmin': 10, 'pmax': 40}) + """ + return self.put_raw(f'/clients/{endpoint}/{path}/attributes', params=attributes) + + def remove_attributes(self, endpoint: str, path: str, attributes: list): + """Send LwM2M Write-Attributes to given path + example: + leshan.remove_attributes(endpoint, '1/2/3, ['pmin', 'pmax']) + """ + attrs = '&'.join(attributes) + return self.put_raw(f'/clients/{endpoint}/{path}/attributes?'+ attrs) + def update_obj_instance(self, endpoint: str, path: str, resources: dict): """Update object instance""" data = self._define_obj_inst(path, resources) @@ -256,6 +271,10 @@ def parse_composite(cls, payload: dict): raise RuntimeError(f'No content received') payload = payload['content'] for path, content in payload.items(): + if path == "/": + for obj in content['objects']: + data.update(cls._decode_obj(obj)) + continue keys = [int(key) for key in path.lstrip("/").split('/')] if len(keys) == 1: data.update(cls._decode_obj(content)) @@ -370,6 +389,9 @@ 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?active') + + def passive_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]): @@ -379,6 +401,10 @@ def composite_observe(self, endpoint: str, paths: list[str]): 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) + '&active') + + def passive_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)) diff --git a/tests/net/lib/lwm2m/interop/pytest/pytest.ini b/tests/net/lib/lwm2m/interop/pytest/pytest.ini new file mode 100644 index 00000000000..761785364d8 --- /dev/null +++ b/tests/net/lib/lwm2m/interop/pytest/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +markers = + slow: marks tests as slow (deselect with '-m "not slow"') diff --git a/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py index 65561db0676..2a45669d912 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_bootstrap.py @@ -15,9 +15,11 @@ """ import logging +import pytest from leshan import Leshan from twister_harness import Shell from twister_harness import DeviceAdapter +from conftest import Endpoint logger = logging.getLogger(__name__) @@ -29,24 +31,69 @@ # Bootstrap Interface: [0-99] # -def verify_LightweightM2M_1_1_int_0(shell: Shell, dut: DeviceAdapter): +def verify_LightweightM2M_1_1_int_0(dut: DeviceAdapter, endpoint_bootstrap: Endpoint): """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) + dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0) + endpoint_bootstrap.bootstrap = True -def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: str): +def test_LightweightM2M_1_1_int_1(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint_bootstrap: Endpoint): """LightweightM2M-1.1-int-1 - Client Initiated Bootstrap Full (PSK)""" - verify_LightweightM2M_1_1_int_0(shell, dut) + verify_LightweightM2M_1_1_int_0(dut, endpoint_bootstrap) 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): +def test_LightweightM2M_1_1_int_4(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): + """LightweightM2M-1.1-int-4 - Bootstrap Delete""" + shell.exec_command('lwm2m create 1/2') + shell.exec_command('lwm2m read 1/2/0') + retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0]) + assert retval == 0 + leshan.execute(endpoint, '1/0/9') + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + shell.exec_command('lwm2m read 1/2/0') + retval = int(shell.get_filtered_output(shell.exec_command('retval'))[0]) + assert retval < 0 + logger.info('retval: %s', retval) + +def test_LightweightM2M_1_1_int_5(dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): + """LightweightM2M-1.1-int-5 - Server Initiated Bootstrap""" + leshan.execute(endpoint, '1/0/9') + dut.readlines_until(regex='.*Server Initiated Bootstrap', timeout=1) + dut.readlines_until(regex='.*Bootstrap transfer complete', timeout=5.0) + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + +def test_LightweightM2M_1_1_int_6(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint): + """LightweightM2M-1.1-int-6 - Bootstrap Sequence""" + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert not any("Bootstrap" in line for line in lines) + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command("lwm2m delete 1/0") + shell.exec_command("lwm2m delete 0/1") + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=5.0) + assert any("Bootstrap" in line for line in lines) + +@pytest.mark.slow +def test_LightweightM2M_1_1_int_7(shell: Shell, dut: DeviceAdapter, endpoint: Endpoint): + """LightweightM2M-1.1-int-7 - Fallback to bootstrap""" + shell.exec_command('lwm2m stop') + dut.readlines_until(regex=r'.*Deregistration success', timeout=5) + shell.exec_command('lwm2m write 0/1/0 -s coaps://10.10.10.10:5684') + shell.exec_command(f'lwm2m start {endpoint}') + lines = dut.readlines_until(regex='.*Registration Done', timeout=600.0) + assert any("Bootstrap" in line for line in lines) + +def verify_LightweightM2M_1_1_int_101(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: Endpoint): """LightweightM2M-1.1-int-101 - Initial Registration""" dut.readlines_until(regex='.*Registration Done', timeout=5.0) assert leshan.get(f'/clients/{endpoint}') + endpoint.registered = True -def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: str): +def verify_LightweightM2M_1_1_int_401(shell: Shell, leshan: Leshan, endpoint: Endpoint): """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] diff --git a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py index 8f3acd69c7e..4e0ae207e8d 100644 --- a/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py +++ b/tests/net/lib/lwm2m/interop/pytest/test_lwm2m.py @@ -44,6 +44,17 @@ def test_LightweightM2M_1_1_int_102(shell: Shell, dut: DeviceAdapter, leshan: Le assert latest["lifetime"] == lifetime shell.exec_command('lwm2m write 1/0/1 -u32 86400') +def test_LightweightM2M_1_1_int_103(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-103 - Deregistration""" + leshan.execute(endpoint, '1/0/4') + dut.readlines_until(regex='LwM2M server disabled', timeout=5.0) + dut.readlines_until(regex='Deregistration success', timeout=5.0) + # Reset timers by restarting the client + shell.exec_command('lwm2m stop') + time.sleep(1) + shell.exec_command(f'lwm2m start {endpoint}') + dut.readlines_until(regex='.*Registration Done', timeout=5.0) + 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') @@ -51,6 +62,7 @@ def test_LightweightM2M_1_1_int_104(shell: Shell, dut: DeviceAdapter, leshan: Le leshan.execute(endpoint, '1/0/8') dut.readlines_until(regex='.*net_lwm2m_rd_client: Update Done', timeout=5.0) +@pytest.mark.slow 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) @@ -66,6 +78,7 @@ 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"] +@pytest.mark.slow 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') @@ -169,6 +182,7 @@ def verify_setting_basic_in_format(shell, leshan, endpoint, format): verify_server_object(server_obj) # Remove Read-Only resources, so we don't end up writing those del server_obj[0][0] + del server_obj[0][13] data = { 2: 101, 3: 1010, @@ -200,13 +214,13 @@ 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)' + assert leshan.write_attributes(endpoint, '0', {'pmin':10})['status'] == 'UNAUTHORIZED(401)' 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 + assert len(resp[1][0]) == 11 resp = leshan.read(endpoint, '3') assert len(resp) == 1 assert len(resp[3]) == 1 @@ -216,7 +230,7 @@ def test_LightweightM2M_1_1_int_222(shell: Shell, leshan: Leshan, endpoint: str) 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 + assert len(resp[0]) == 11 resp = leshan.read(endpoint, '3/0') assert len(resp[0]) == 15 assert resp[0][0] == 'Zephyr' @@ -280,7 +294,7 @@ def test_LightweightM2M_1_1_int_229(shell: Shell, leshan: Leshan, endpoint: str) 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 + assert len(resp[1][0]) == 11 resp = leshan.composite_read(endpoint, ['1/0/1', '/3/0/11/0']) logger.debug(resp) @@ -365,9 +379,12 @@ 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') -@pytest.mark.skip("Leshan does not allow reading root path") -def test_LightweightM2M_1_1_int_235(): +def test_LightweightM2M_1_1_int_235(leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-235 - Read-Composite Operation on root path""" + resp = leshan.composite_read(endpoint, ['/']) + expected_keys = [1, 3, 5] + missing_keys = [key for key in expected_keys if key not in resp.keys()] + assert len(missing_keys) == 0 def test_LightweightM2M_1_1_int_236(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-236 - Read-Composite - Partial Presence""" @@ -427,15 +444,12 @@ def test_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str) 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)' + assert leshan.write_attributes(endpoint, '3', {'pmin': 10, '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)' + assert leshan.write_attributes(endpoint, '3/0/7', {'lt': 1, 'gt': 6, '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()] @@ -449,8 +463,9 @@ def test_LightweightM2M_1_1_int_260(shell: Shell, leshan: Leshan, endpoint: str) 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) + # restore + leshan.remove_attributes(endpoint, '3', ['pmin', 'pmax']) -@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') @@ -460,19 +475,20 @@ def test_LightweightM2M_1_1_int_261(shell: Shell, leshan: Leshan, endpoint: str) 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)' + assert leshan.write_attributes(endpoint, '3', {'pmin':10, 'pmax':200})['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0', {'pmax':320})['status'] == 'CHANGED(204)' + assert leshan.write_attributes(endpoint, '3/0/11/0', {'pmax':100, 'epmin':1, '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 + # Note: Zephyr does not support epmin&epmax. + # Restore + leshan.remove_attributes(endpoint, '3', ['pmin', 'pmax']) + leshan.remove_attributes(endpoint, '3/0', ['pmax']) + leshan.remove_attributes(endpoint, '3/0/11/0', ['pmax']) + def test_LightweightM2M_1_1_int_280(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-280 - Successful Read-Composite Operation""" @@ -500,14 +516,14 @@ def test_LightweightM2M_1_1_int_281(shell: Shell, leshan: Leshan, endpoint: str) # Information Reporting Interface [300-399] # +@pytest.mark.slow 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)' + assert leshan.write_attributes(endpoint, '3/0/7', {'pmin': 5, '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') @@ -526,6 +542,7 @@ def test_LightweightM2M_1_1_int_301(shell: Shell, leshan: Leshan, endpoint: str) 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') + leshan.remove_attributes(endpoint, '3/0/7', ['pmin', 'pmax']) 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""" @@ -535,21 +552,41 @@ def test_LightweightM2M_1_1_int_302(shell: Shell, dut: DeviceAdapter, leshan: Le 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') + leshan.passive_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') + leshan.passive_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_303(shell: Shell, dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-303 - Cancel observations using Observe with Cancel parameter""" + 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') + 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') + dut.readlines_until(regex=r'.*Observer removed for 3/0/8') + +@pytest.mark.slow 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)' + # 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') + assert leshan.write_attributes(endpoint, '1/0/1', {'pmin': 30, '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 @@ -570,6 +607,18 @@ def test_LightweightM2M_1_1_int_304(shell: Shell, leshan: Leshan, endpoint: str) 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']) + # Restore configuration C.3 + shell.exec_command('lwm2m write 1/0/2 -u32 1') + shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '1/0/1', ['pmin', 'pmax']) + +def test_LightweightM2M_1_1_int_305(dut: DeviceAdapter, leshan: Leshan, endpoint: str): + """LightweightM2M-1.1-int-305 - Cancel Observation-Composite Operation""" + leshan.composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + leshan.cancel_composite_observe(endpoint, ['/1/0/1', '/3/0/11/0', '/3/0/16']) + dut.readlines_until(regex=r'.*Observer removed for 1/0/1') + dut.readlines_until(regex=r'.*Observer removed for 3/0/11/0') + dut.readlines_until(regex=r'.*Observer removed for 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""" @@ -590,6 +639,8 @@ def test_LightweightM2M_1_1_int_307(shell: Shell, dut: DeviceAdapter, leshan: Le shell.exec_command('lwm2m send /3/0') dut.readlines_until(regex=r'.*SEND status: 0', timeout=5.0) + +@pytest.mark.slow 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') @@ -613,8 +664,7 @@ def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Le 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)' + assert leshan.write_attributes(endpoint, '16/0', {'pmin': 30, '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: @@ -630,7 +680,9 @@ def test_LightweightM2M_1_1_int_308(shell: Shell, dut: DeviceAdapter, leshan: Le # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '16/0', ['pmin','pmax']) +@pytest.mark.slow 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') @@ -655,8 +707,7 @@ def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Le 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)' + assert leshan.write_attributes(endpoint, '16/0', {'pmin': 30, '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: @@ -672,17 +723,17 @@ def test_LightweightM2M_1_1_int_309(shell: Shell, dut: DeviceAdapter, leshan: Le # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '16/0', ['pmin', 'pmax']) +@pytest.mark.slow 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)' + assert leshan.write_attributes(endpoint, '3', {'pmax': 5})['status'] == 'CHANGED(204)' start = time.time() data = events.next_event('NOTIFICATION') assert data[3][0][0] == 'Zephyr' @@ -695,6 +746,7 @@ def test_LightweightM2M_1_1_int_310(shell: Shell, leshan: Leshan, endpoint: str) # Restore configuration C.3 shell.exec_command('lwm2m write 1/0/2 -u32 1') shell.exec_command('lwm2m write 1/0/3 -u32 10') + leshan.remove_attributes(endpoint, '3', ['pmax']) def test_LightweightM2M_1_1_int_311(shell: Shell, leshan: Leshan, endpoint: str): """LightweightM2M-1.1-int-311 - Send command""" diff --git a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c index 706091659a5..a150f1b41cb 100644 --- a/tests/net/lib/lwm2m/interop/src/lwm2m-client.c +++ b/tests/net/lib/lwm2m/interop/src/lwm2m-client.c @@ -73,6 +73,17 @@ int set_socketoptions(struct lwm2m_ctx *ctx) ret = -errno; LOG_ERR("Failed to enable TLS_DTLS_CID: %d", ret); } + + /* Allow DTLS handshake to timeout much faster. + * these tests run on TUN/TAP network, so there should be no network latency. + */ + uint32_t min = 100; + uint32_t max = 500; + + zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_HANDSHAKE_TIMEOUT_MIN, &min, + sizeof(min)); + zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_DTLS_HANDSHAKE_TIMEOUT_MAX, &max, + sizeof(max)); } return lwm2m_set_default_sockopt(ctx); } @@ -119,6 +130,10 @@ static void rd_client_event(struct lwm2m_ctx *client, /* do nothing */ break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_DBG("LwM2M server disabled"); + break; + case LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE: LOG_DBG("Bootstrap registration failure!"); break; diff --git a/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf b/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf new file mode 100644 index 00000000000..c735e1a8a2d --- /dev/null +++ b/tests/net/lib/lwm2m/lwm2m_engine/boards/qemu_x86.conf @@ -0,0 +1 @@ +CONFIG_TEST_EXTRA_STACK_SIZE=1024 diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c index ed26380eccd..7078fbebe6d 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c @@ -13,10 +13,11 @@ #include "lwm2m_rd_client.h" #include "stubs.h" -#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) +#if defined(CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME) #include "timer_model.h" #endif +#define LOG_LEVEL LOG_LEVEL_DBG LOG_MODULE_REGISTER(lwm2m_engine_test); DEFINE_FFF_GLOBALS; @@ -67,7 +68,7 @@ static void test_service(struct k_work *work) static void setup(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 */ @@ -259,11 +260,13 @@ ZTEST(lwm2m_engine, test_push_queued_buffers) int ret; struct lwm2m_ctx ctx; struct lwm2m_message msg; + struct coap_pending pending; (void)memset(&ctx, 0x0, sizeof(ctx)); sys_slist_init(&ctx.queued_messages); msg.ctx = &ctx; + msg.pending = &pending; sys_slist_append(&ctx.queued_messages, &msg.node); ret = lwm2m_push_queued_buffers(&ctx); zassert_equal(ret, 0); @@ -390,6 +393,7 @@ ZTEST(lwm2m_engine, test_socket_send) int ret; struct lwm2m_ctx ctx; struct lwm2m_message msg; + struct coap_pending pending; (void)memset(&ctx, 0x0, sizeof(ctx)); @@ -397,6 +401,7 @@ ZTEST(lwm2m_engine, test_socket_send) ctx.sock_fd = -1; sys_slist_init(&ctx.queued_messages); msg.ctx = &ctx; + msg.pending = &pending; msg.type = COAP_TYPE_CON; sys_slist_append(&ctx.queued_messages, &msg.node); @@ -467,3 +472,70 @@ ZTEST(lwm2m_engine, test_security) zassert_equal(tls_credential_add_fake.arg1_history[2], TLS_CREDENTIAL_CA_CERTIFICATE); zassert_equal(lwm2m_engine_stop(&ctx), 0); } + +static enum lwm2m_socket_states last_state; + +static void socket_state(int fd, enum lwm2m_socket_states state) +{ + (void) fd; + last_state = state; +} + +ZTEST(lwm2m_engine, test_socket_state) +{ + int ret; + struct lwm2m_ctx ctx = { + .remote_addr.sa_family = AF_INET, + .sock_fd = -1, + .set_socket_state = socket_state, + }; + struct lwm2m_message msg1 = { + .ctx = &ctx, + .type = COAP_TYPE_CON, + }; + struct lwm2m_message msg2 = msg1; + struct lwm2m_message ack = { + .ctx = &ctx, + .type = COAP_TYPE_ACK, + }; + + sys_slist_init(&ctx.pending_sends); + ret = lwm2m_engine_start(&ctx); + zassert_equal(ret, 0); + + /* One confimable in queue, should cause ONE_RESPONSE status */ + coap_pendings_count_fake.return_val = 1; + sys_slist_append(&ctx.pending_sends, &msg1.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONE_RESPONSE); + + /* More than one messages in queue, not empty, should cause ONGOING */ + coap_pendings_count_fake.return_val = 2; + sys_slist_append(&ctx.pending_sends, &msg1.node); + sys_slist_append(&ctx.pending_sends, &msg2.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING); + + /* Last out, while waiting for ACK to both, should still cause ONGOING */ + coap_pendings_count_fake.return_val = 2; + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_ONGOING); + + /* Only one Ack transmiting, nothing expected back -> LAST */ + coap_pendings_count_fake.return_val = 0; + sys_slist_append(&ctx.pending_sends, &ack.node); + set_socket_events(ZSOCK_POLLOUT); + k_sleep(K_MSEC(100)); + zassert_equal(last_state, LWM2M_SOCKET_STATE_LAST); + + /* Socket suspended (as in QUEUE_RX_OFF), should cause NO_DATA */ + ret = lwm2m_socket_suspend(&ctx); + zassert_equal(ret, 0); + zassert_equal(last_state, LWM2M_SOCKET_STATE_NO_DATA); + + ret = lwm2m_engine_stop(&ctx); + zassert_equal(ret, 0); +} diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 5db155f1e29..0958d75a54a 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -19,6 +19,7 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *); DEFINE_FAKE_VOID_FUNC(lwm2m_registry_lock); DEFINE_FAKE_VOID_FUNC(lwm2m_registry_unlock); DEFINE_FAKE_VALUE_FUNC(bool, coap_pending_cycle, struct coap_pending *); +DEFINE_FAKE_VALUE_FUNC(size_t, coap_pendings_count, struct coap_pending *, size_t); DEFINE_FAKE_VALUE_FUNC(int, generate_notify_message, struct lwm2m_ctx *, struct observe_node *, void *); DEFINE_FAKE_VALUE_FUNC(int64_t, engine_observe_shedule_next_event, struct observe_node *, uint16_t, @@ -41,6 +42,7 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t); DEFINE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t); +DEFINE_FAKE_VOID_FUNC(engine_update_tx_time); static sys_slist_t obs_obj_path_list = SYS_SLIST_STATIC_INIT(&obs_obj_path_list); sys_slist_t *lwm2m_obs_obj_path_list(void) diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h index 7b8ca481f85..67c4cde883d 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h @@ -28,6 +28,7 @@ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_rd_client_resume); DECLARE_FAKE_VALUE_FUNC(struct lwm2m_message *, find_msg, struct coap_pending *, struct coap_reply *); DECLARE_FAKE_VOID_FUNC(coap_pending_clear, struct coap_pending *); +DECLARE_FAKE_VALUE_FUNC(size_t, coap_pendings_count, struct coap_pending *, size_t); DECLARE_FAKE_VOID_FUNC(lwm2m_reset_message, struct lwm2m_message *, bool); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_send_message_async, struct lwm2m_message *); DECLARE_FAKE_VOID_FUNC(lwm2m_registry_lock); @@ -56,6 +57,7 @@ DECLARE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, socklen_t); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void *, socklen_t); +DECLARE_FAKE_VOID_FUNC(engine_update_tx_time); #define DO_FOREACH_FAKE(FUNC) \ do { \ @@ -63,6 +65,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void FUNC(lwm2m_rd_client_resume) \ FUNC(find_msg) \ FUNC(coap_pending_clear) \ + FUNC(coap_pendings_count) \ FUNC(lwm2m_reset_message) \ FUNC(lwm2m_send_message_async) \ FUNC(lwm2m_registry_lock) \ @@ -85,6 +88,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_setsockopt, int, int, int, const void FUNC(z_impl_zsock_connect) \ FUNC(lwm2m_security_mode) \ FUNC(z_impl_zsock_setsockopt) \ + FUNC(engine_update_tx_time) \ } while (0) #endif /* STUBS_H */ 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 931f6f15904..1d6a4e584fa 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -21,7 +21,7 @@ DEFINE_FFF_GLOBALS; /* Maximum number of iterations within the state machine of RD Client * service that is waited for until a possible event occurs */ -static const uint8_t RD_CLIENT_MAX_LOOKUP_ITERATIONS = 100; +#define RD_CLIENT_MAX_LOOKUP_ITERATIONS 500 FAKE_VOID_FUNC(show_lwm2m_event, enum lwm2m_rd_client_event); FAKE_VOID_FUNC(show_lwm2m_observe, enum lwm2m_observe_event); @@ -97,6 +97,9 @@ static void lwm2m_event_cb(struct lwm2m_ctx *client, enum lwm2m_rd_client_event case LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF"); break; + case LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED: + LOG_INF("*** LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED"); + break; case LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED: LOG_INF("*** LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED"); break; @@ -165,6 +168,7 @@ static void my_suite_before(void *data) lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; coap_packet_append_option_fake.custom_fake = NULL; + stub_lwm2m_server_disable(false); } static void my_suite_after(void *data) @@ -198,8 +202,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -207,6 +209,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -228,8 +231,6 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -237,6 +238,7 @@ ZTEST(lwm2m_rd_client, test_register_update_too_small_lifetime_to_default) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -249,14 +251,13 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert(lwm2m_rd_client_ctx() == &ctx, ""); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -273,16 +274,17 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_timeout_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); - zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR), NULL); } ZTEST(lwm2m_rd_client, test_start_registration_fail) @@ -291,8 +293,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -302,8 +302,15 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), + NULL); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE), + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR), + NULL); } ZTEST(lwm2m_rd_client, test_start_registration_update) @@ -312,8 +319,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -321,6 +326,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -335,8 +341,6 @@ ZTEST(lwm2m_rd_client, test_rx_off) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -344,6 +348,7 @@ ZTEST(lwm2m_rd_client, test_rx_off) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -359,8 +364,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -368,6 +371,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -384,8 +388,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -393,6 +395,7 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); test_prepare_pending_message_cb(&message_reply_timeout_cb_default); @@ -415,8 +418,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -424,6 +425,7 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -439,8 +441,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -449,6 +449,8 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) coap_packet_append_option_fake.custom_fake = NULL; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -482,8 +484,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -491,6 +491,7 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); zassert_true(!lwm2m_rd_client_is_suspended(&ctx), NULL); @@ -517,8 +518,6 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -527,6 +526,7 @@ ZTEST(lwm2m_rd_client, test_suspend_stop_resume) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); zassert_true(lwm2m_rd_client_pause() == 0, NULL); @@ -544,8 +544,6 @@ ZTEST(lwm2m_rd_client, test_socket_error) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -554,6 +552,7 @@ ZTEST(lwm2m_rd_client, test_socket_error) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -569,8 +568,6 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -579,6 +576,7 @@ ZTEST(lwm2m_rd_client, test_socket_error_on_stop) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); @@ -608,8 +606,6 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -617,6 +613,7 @@ ZTEST(lwm2m_rd_client, test_engine_trigger_bootstrap) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; @@ -638,8 +635,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_timeout_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -651,6 +646,7 @@ ZTEST(lwm2m_rd_client, test_bootstrap_timeout) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), NULL); } @@ -661,8 +657,6 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail) (void)memset(&ctx, 0x0, sizeof(ctx)); - test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -674,27 +668,224 @@ ZTEST(lwm2m_rd_client, test_bootstrap_fail) coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), NULL); } -ZTEST(lwm2m_rd_client, test_bootstrap_no_srv_fallback_to_register) +ZTEST(lwm2m_rd_client, test_bootstrap_no_srv) { struct lwm2m_ctx ctx; (void)memset(&ctx, 0x0, sizeof(ctx)); + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; - zassert_true(lwm2m_rd_client_start(&ctx, "Test", 1, lwm2m_event_cb, lwm2m_observe_cb) == 0, + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server_stop) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), + NULL); + wait_for_service(1); + zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT), NULL); +} + +ZTEST(lwm2m_rd_client, test_disable_server_connect) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + stub_lwm2m_server_disable(true); + lwm2m_rd_client_server_disabled(0); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED), + NULL); + + wait_for_service(500); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + stub_lwm2m_server_disable(false); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_fallback_to_bootstrap) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_timeout_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT), NULL); + + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_no_srv_fallback_to_bootstrap) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_changed; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_true; + stub_lwm2m_server_disable(true); + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + test_prepare_pending_message_cb(&message_reply_cb_default); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE), + NULL); + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + stub_lwm2m_server_disable(false); + engine_bootstrap_finish(); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); +} + +ZTEST(lwm2m_rd_client, test_start_stop_ignore_engine_fault) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + test_prepare_pending_message_cb(&message_reply_cb_default); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_engine_context_init_fake.custom_fake = lwm2m_engine_context_init_fake1; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default; + lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default; + lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + + 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_DISCONNECT), NULL); + + int c = show_lwm2m_event_fake.call_count; + + test_throw_network_error_from_engine(EIO); + wait_for_service(10); + zassert_equal(show_lwm2m_event_fake.call_count, c, + "Should not enter any other state and throw an event"); +} + +ZTEST(lwm2m_rd_client, test_start_suspend_ignore_engine_fault) +{ + struct lwm2m_ctx ctx; + + (void)memset(&ctx, 0x0, sizeof(ctx)); + + test_prepare_pending_message_cb(&message_reply_cb_default); + + lwm2m_rd_client_init(); + test_lwm2m_engine_start_service(); + wait_for_service(1); + + lwm2m_engine_context_init_fake.custom_fake = lwm2m_engine_context_init_fake1; + lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default; + lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default; + lwm2m_init_message_fake.custom_fake = lwm2m_init_message_fake_default; + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_created; + coap_find_options_fake.custom_fake = coap_find_options_do_registration_reply_cb_ok; + zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, + NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE), + NULL); + + coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; + zassert_true(lwm2m_rd_client_pause() == 0, NULL); + zassert_true(expect_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED), NULL); + + int c = show_lwm2m_event_fake.call_count; + + test_throw_network_error_from_engine(EIO); + wait_for_service(10); + zassert_equal(show_lwm2m_event_fake.call_count, c, + "Should not enter any other state and throw an event"); } 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..621057f8496 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -86,6 +86,10 @@ int lwm2m_get_u32_val(const struct lwm2m_obj_path *path, uint32_t *val) /* subsys/net/lib/lwm2m/lwm2m_engine.h */ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); +int lwm2m_socket_start_fake_fail(struct lwm2m_ctx *client_ctx) +{ + return -1; +} DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); @@ -93,6 +97,16 @@ DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_init, struct lwm2m_ctx *); +struct lwm2m_ctx *client_ctx_fake; +void lwm2m_engine_context_init_fake1(struct lwm2m_ctx *client_ctx) +{ + client_ctx_fake = client_ctx; +} +void test_throw_network_error_from_engine(int err) +{ + client_ctx_fake->fault_cb(err); +} + DEFINE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *); char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr) @@ -102,6 +116,24 @@ char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr) DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t); +DEFINE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t); +DEFINE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps); + +static bool srv_disabled; +bool lwm2m_server_select(uint16_t *obj_inst_id) +{ + if (obj_inst_id) { + *obj_inst_id = 0; + } + return !srv_disabled; +} + +void stub_lwm2m_server_disable(bool disable) +{ + srv_disabled = disable; +} k_work_handler_t service; int64_t next; @@ -163,9 +195,13 @@ void test_lwm2m_engine_start_service(void) void test_lwm2m_engine_stop_service(void) { + struct k_work_sync sync; + pending_message_cb = NULL; + pending_message = NULL; running = false; k_work_cancel(&service_work); + k_work_flush(&service_work, &sync); } /* subsys/net/lib/lwm2m/lwm2m_message_handling.h */ diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h index 620e4d8fc12..0a3ce31d9e8 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h @@ -54,21 +54,31 @@ int lwm2m_get_u32_val(const struct lwm2m_obj_path *path, uint32_t *val); /* subsys/net/lib/lwm2m/lwm2m_engine.h */ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); +int lwm2m_socket_start_fake_fail(struct lwm2m_ctx *client_ctx); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_short_id_to_inst, uint16_t); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_init, struct lwm2m_ctx *); +void lwm2m_engine_context_init_fake1(struct lwm2m_ctx *client_ctx); +void test_throw_network_error_from_engine(int err); DECLARE_FAKE_VOID_FUNC(lwm2m_engine_context_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *); char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); -DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_disable, uint16_t, k_timeout_t); +DECLARE_FAKE_VALUE_FUNC(uint8_t, lwm2m_server_get_prio, uint16_t); +DECLARE_FAKE_VOID_FUNC(lwm2m_server_reset_timestamps); + + void wait_for_service(uint16_t cycles); void test_lwm2m_engine_start_service(void); void test_lwm2m_engine_stop_service(void); +void stub_lwm2m_server_disable(bool disable); /* subsys/net/lib/lwm2m/lwm2m_message_handling.h */ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_init_message, struct lwm2m_message *); 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 d4c0a7757a6..8e99f666b7f 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -203,16 +203,6 @@ ZTEST(lwm2m_registry, test_get_set) zassert_equal(strlen(buf), 0); } -ZTEST(lwm2m_registry, test_missing_u64) -{ - /* This data type is missing, so use S64 resource instead */ - uint64_t u64 = 123; - - zassert_equal(lwm2m_set_u64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), u64), 0); - zassert_equal(lwm2m_get_u64(&LWM2M_OBJ(32768, 0, LWM2M_RES_TYPE_S64), &u64), 0); - zassert_equal(u64, 123); -} - ZTEST(lwm2m_registry, test_temp_sensor) { int ret; diff --git a/tests/subsys/jwt/src/tls_config/user-tls-conf.h b/tests/subsys/jwt/src/tls_config/user-tls-conf.h index 035f2b062ec..0d95ee80ac0 100644 --- a/tests/subsys/jwt/src/tls_config/user-tls-conf.h +++ b/tests/subsys/jwt/src/tls_config/user-tls-conf.h @@ -3,3 +3,4 @@ #define MBEDTLS_HAVE_TIME #define MBEDTLS_HAVE_TIME_DATE #define MBEDTLS_PLATFORM_TIME_ALT +#define MBEDTLS_PLATFORM_MS_TIME_ALT 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..557697f576c 100644 --- a/tests/subsys/llext/src/test_llext_simple.c +++ b/tests/subsys/llext/src/test_llext_simple.c @@ -9,8 +9,11 @@ #include #include -#ifdef CONFIG_ARM /* ARMV7 */ -const static uint8_t hello_world_elf[] __aligned(4) = { +#if defined(CONFIG_ARM) /* ARMV7 */ || defined(CONFIG_XTENSA) +#ifndef CONFIG_LLEXT_STORAGE_WRITABLE +const +#endif +static uint8_t hello_world_elf[] __aligned(4) = { #include "hello_world.inc" }; #endif @@ -24,7 +27,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..2747edf8d0c 100644 --- a/tests/subsys/llext/testcase.yaml +++ b/tests/subsys/llext/testcase.yaml @@ -9,3 +9,10 @@ tests: # Broken platforms platform_exclude: - 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 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 diff --git a/tests/subsys/mgmt/mcumgr/cb_notifications/src/smp_test_util.c b/tests/subsys/mgmt/mcumgr/cb_notifications/src/smp_test_util.c index a20f948f30b..270f232af77 100644 --- a/tests/subsys/mgmt/mcumgr/cb_notifications/src/smp_test_util.c +++ b/tests/subsys/mgmt/mcumgr/cb_notifications/src/smp_test_util.c @@ -29,7 +29,7 @@ bool create_mcumgr_format_packet(zcbor_state_t *zse, uint8_t *buffer, uint8_t *o ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "d") && - zcbor_tstr_put_term(zse, "some test data") && + zcbor_tstr_put_lit(zse, "some test data") && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); diff --git a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/src/main.c b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/src/main.c index a5cafef589d..30575172a84 100644 --- a/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/src/main.c +++ b/tests/subsys/mgmt/mcumgr/fs_mgmt_hash_supported/src/main.c @@ -97,7 +97,7 @@ ZTEST(fs_mgmt_hash_supported, test_supported) /* Search expected type array for this type and update details */ zcbor_new_decode_state(state, 10, &nb->data[sizeof(struct smp_hdr)], - (nb->len - sizeof(struct smp_hdr)), 1); + (nb->len - sizeof(struct smp_hdr)), 1, NULL, 0); ok = zcbor_map_start_decode(state); 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..9b12fd7b2b0 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 @@ -120,9 +120,10 @@ void img_read_response(int count) zcbor_tstr_put_lit(zse, "slot") && zcbor_uint32_put(zse, image_dummy_info[i].slot_num) && zcbor_tstr_put_lit(zse, "version") && - zcbor_tstr_put_term(zse, image_dummy_info[i].version) && + zcbor_tstr_put_term(zse, image_dummy_info[i].version, + sizeof(image_dummy_info[i].version)) && - zcbor_tstr_put_term(zse, "hash") && + zcbor_tstr_put_lit(zse, "hash") && 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) && @@ -180,7 +181,8 @@ void img_state_write_verify(struct net_buf *nb) ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash) }; - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1, + NULL, 0); decoded = 0; /* Init buffer values */ @@ -231,7 +233,8 @@ void img_upload_init_verify(struct net_buf *nb) ZCBOR_MAP_DECODE_KEY_DECODER("sha", zcbor_bstr_decode, &sha) }; - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1, + NULL, 0); decoded = 0; /* Init buffer values */ diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c index bf70f178fe7..c724c72c2cc 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c @@ -225,12 +225,12 @@ ZTEST(mcumgr_client, test_os_echo) smp_stub_set_rx_data_verify(NULL); smp_client_send_status_stub(MGMT_ERR_EOK); /* Test timeout */ - rc = os_mgmt_client_echo(&os_client, os_echo_test); + rc = os_mgmt_client_echo(&os_client, os_echo_test, sizeof(os_echo_test)); zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", MGMT_ERR_ETIMEOUT, rc); /* Test successfully operation */ smp_stub_set_rx_data_verify(os_echo_verify); - rc = os_mgmt_client_echo(&os_client, os_echo_test); + rc = os_mgmt_client_echo(&os_client, os_echo_test, sizeof(os_echo_test)); zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); } diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c index 888f00dba38..c7196874556 100644 --- a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c @@ -81,7 +81,8 @@ void os_echo_verify(struct net_buf *nb) ZCBOR_MAP_DECODE_KEY_DECODER("d", zcbor_tstr_decode, &echo_data) }; - zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1, + NULL, 0); echo_data.len = 0; rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c index c387c3b4812..05adb1d6de4 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_datetime/src/main.c @@ -191,7 +191,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_get_not_set_v1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -253,7 +253,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_get_not_set_v2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -318,7 +318,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -365,7 +365,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -428,7 +428,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -475,7 +475,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -538,7 +538,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_3) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -585,7 +585,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v1_3) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -648,7 +648,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -695,7 +695,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -760,7 +760,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -807,7 +807,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -872,7 +872,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_3) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -919,7 +919,7 @@ ZTEST(os_mgmt_datetime_not_set, test_datetime_set_invalid_v2_3) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -984,7 +984,7 @@ ZTEST(os_mgmt_datetime_set, test_datetime_set_v1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1030,7 +1030,7 @@ ZTEST(os_mgmt_datetime_set, test_datetime_set_v1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1098,7 +1098,7 @@ ZTEST(os_mgmt_datetime_set, test_datetime_set_v2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1144,7 +1144,7 @@ ZTEST(os_mgmt_datetime_set, test_datetime_set_v2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1225,7 +1225,7 @@ ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1287,7 +1287,7 @@ ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v1) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1357,7 +1357,7 @@ ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -1418,7 +1418,7 @@ ZTEST(os_mgmt_datetime_hook, test_datetime_set_valid_hook_v2) /* 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); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); 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 index 927089c3ee3..d2b969999cd 100644 --- 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 @@ -49,9 +49,9 @@ bool create_mcumgr_datetime_set_packet_str(zcbor_state_t *zse, bool version2, co 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) && + bool ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "datetime") && + zcbor_tstr_put_term(zse, data, CONFIG_ZCBOR_MAX_STR_LEN) && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/build_date.c b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/build_date.c index 4af977895c3..5674e338dfa 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/build_date.c +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/build_date.c @@ -121,7 +121,7 @@ ZTEST(os_mgmt_info_build_date, test_info_build_date_1_build_date) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -197,7 +197,7 @@ ZTEST(os_mgmt_info_build_date, test_info_build_date_2_all) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/limited.c b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/limited.c index f8899734351..613402e1624 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/limited.c +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/limited.c @@ -81,7 +81,7 @@ ZTEST(os_mgmt_info_limited, test_info_1_kernel_name) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -147,7 +147,7 @@ ZTEST(os_mgmt_info_limited, test_info_2_all) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); /* Ensure only an error is received */ ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -155,7 +155,7 @@ ZTEST(os_mgmt_info_limited, test_info_2_all) zassert_true(ok, "Expected decode to be successful\n"); zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n"); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/main.c b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/main.c index 8ffc2a354b8..6e8cc61098d 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/main.c +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/main.c @@ -338,7 +338,7 @@ ZTEST(os_mgmt_info, test_info_2_kernel_name) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -399,7 +399,7 @@ ZTEST(os_mgmt_info, test_info_3_node_name) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -461,7 +461,7 @@ ZTEST(os_mgmt_info, test_info_4_kernel_release) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -523,7 +523,7 @@ ZTEST(os_mgmt_info, test_info_5_kernel_version) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -584,7 +584,7 @@ ZTEST(os_mgmt_info, test_info_6_machine) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -645,7 +645,7 @@ ZTEST(os_mgmt_info, test_info_7_processor) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -706,7 +706,7 @@ ZTEST(os_mgmt_info, test_info_8_platform) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -778,7 +778,7 @@ ZTEST(os_mgmt_info, test_info_9_os) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -839,7 +839,7 @@ ZTEST(os_mgmt_info, test_info_10_all) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -914,7 +914,7 @@ ZTEST(os_mgmt_info, test_info_11_multi_1) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -979,7 +979,7 @@ ZTEST(os_mgmt_info, test_info_12_multi_2) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1051,7 +1051,7 @@ ZTEST(os_mgmt_info, test_info_13_invalid_1) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); /* Ensure only an error is received */ ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1059,7 +1059,7 @@ ZTEST(os_mgmt_info, test_info_13_invalid_1) zassert_true(ok, "Expected decode to be successful\n"); zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n"); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); @@ -1122,7 +1122,7 @@ ZTEST(os_mgmt_info, test_info_14_invalid_2) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); /* Ensure only an error is received */ ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1130,7 +1130,7 @@ ZTEST(os_mgmt_info, test_info_14_invalid_2) zassert_true(ok, "Expected decode to be successful\n"); zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n"); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); @@ -1199,7 +1199,7 @@ ZTEST(os_mgmt_info_custom_os, test_info_os_custom) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1260,7 +1260,7 @@ ZTEST(os_mgmt_info_custom_os_disabled, test_info_os_custom_disabled) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1333,7 +1333,7 @@ ZTEST(os_mgmt_info_custom_cmd, test_info_cmd_custom) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; @@ -1399,14 +1399,14 @@ ZTEST(os_mgmt_info_custom_cmd_disabled, test_info_cmd_custom_disabled) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n"); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); @@ -1468,14 +1468,14 @@ ZTEST(os_mgmt_info_custom_cmd_disabled_verify, test_info_cmd_custom_disabled) /* Process received data by removing header */ (void)net_buf_pull(nb, sizeof(struct smp_hdr)); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); zassert_equal(decoded, 0, "Expected to receive 0 decoded zcbor element\n"); - zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 3, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, error_decode, ARRAY_SIZE(error_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful\n"); diff --git a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/smp_test_util.c b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/smp_test_util.c index c1dcded0ff6..b76ac1ad623 100644 --- a/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/smp_test_util.c +++ b/tests/subsys/mgmt/mcumgr/os_mgmt_info/src/smp_test_util.c @@ -31,7 +31,7 @@ bool create_mcumgr_format_packet(zcbor_state_t *zse, const uint8_t *format, uint ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "format") && - zcbor_tstr_put_term(zse, format) && + zcbor_tstr_put_term(zse, format, CONFIG_ZCBOR_MAX_STR_LEN) && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); diff --git a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c index 745fa333790..869a4f750d9 100644 --- a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c +++ b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/main.c @@ -487,7 +487,7 @@ ZTEST(settings_mgmt, test_set_read) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -590,7 +590,7 @@ ZTEST(settings_mgmt, test_read_max_size) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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, 2, "Expected to receive 2 decoded zcbor elements"); @@ -745,7 +745,7 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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"); @@ -875,7 +875,7 @@ ZTEST(settings_mgmt, test_set_disallowed) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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"); @@ -1147,7 +1147,7 @@ ZTEST(settings_mgmt, test_delete) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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"); @@ -1274,7 +1274,7 @@ ZTEST(settings_mgmt, test_delete) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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"); @@ -1519,7 +1519,7 @@ ZTEST(settings_mgmt, test_delete) zassert_equal(smp_header->nh_version, 1, "SMP header version mismatch"); /* Get the response value to compare */ - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); 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"); diff --git a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/smp_test_util.c b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/smp_test_util.c index 63b91151797..dcabd0d08c3 100644 --- a/tests/subsys/mgmt/mcumgr/settings_mgmt/src/smp_test_util.c +++ b/tests/subsys/mgmt/mcumgr/settings_mgmt/src/smp_test_util.c @@ -31,7 +31,7 @@ bool create_settings_mgmt_read_packet(zcbor_state_t *zse, uint8_t *buffer, uint8 ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "name") && - zcbor_tstr_put_term(zse, name) && + zcbor_tstr_put_term(zse, name, CONFIG_ZCBOR_MAX_STR_LEN) && (max_size == 0 || (zcbor_tstr_put_lit(zse, "max_size") && zcbor_uint32_put(zse, max_size))) && zcbor_map_end_encode(zse, 2); @@ -51,11 +51,11 @@ bool create_settings_mgmt_write_packet(zcbor_state_t *zse, uint8_t *buffer, uint { bool ok; - ok = zcbor_map_start_encode(zse, 2) && - zcbor_tstr_put_lit(zse, "name") && - zcbor_tstr_put_term(zse, name) && - zcbor_tstr_put_lit(zse, "val") && - zcbor_bstr_encode_ptr(zse, val, val_size) && + ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "name") && + zcbor_tstr_put_term(zse, name, CONFIG_ZCBOR_MAX_STR_LEN) && + zcbor_tstr_put_lit(zse, "val") && + zcbor_bstr_encode_ptr(zse, val, val_size) && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); @@ -72,9 +72,9 @@ bool create_settings_mgmt_delete_packet(zcbor_state_t *zse, uint8_t *buffer, { bool ok; - ok = zcbor_map_start_encode(zse, 2) && - zcbor_tstr_put_lit(zse, "name") && - zcbor_tstr_put_term(zse, name) && + ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "name") && + zcbor_tstr_put_term(zse, name, CONFIG_ZCBOR_MAX_STR_LEN) && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); diff --git a/tests/subsys/mgmt/mcumgr/smp_version/src/main.c b/tests/subsys/mgmt/mcumgr/smp_version/src/main.c index 8676678336e..ed596ae964e 100644 --- a/tests/subsys/mgmt/mcumgr/smp_version/src/main.c +++ b/tests/subsys/mgmt/mcumgr/smp_version/src/main.c @@ -155,7 +155,7 @@ ZTEST(smp_version, test_legacy_command) zassert_equal(smp_header->nh_version, LEGACY_VERSION, "Expected response header version mismatch"); - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -242,7 +242,7 @@ ZTEST(smp_version, test_current_command) zassert_equal(smp_header->nh_version, CURRENT_VERSION, "Expected response header version mismatch"); - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); @@ -328,7 +328,7 @@ ZTEST(smp_version, test_new_command) zassert_equal(smp_header->nh_version, CURRENT_VERSION, "Expected response header version mismatch"); - zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1); + zcbor_new_decode_state(zsd, 4, nb->data, nb->len, 1, NULL, 0); ok = zcbor_map_decode_bulk(zsd, output_decode, ARRAY_SIZE(output_decode), &decoded) == 0; zassert_true(ok, "Expected decode to be successful"); diff --git a/tests/subsys/mgmt/mcumgr/smp_version/src/smp_test_util.c b/tests/subsys/mgmt/mcumgr/smp_version/src/smp_test_util.c index e93ad69ff2a..96d97a6b6fa 100644 --- a/tests/subsys/mgmt/mcumgr/smp_version/src/smp_test_util.c +++ b/tests/subsys/mgmt/mcumgr/smp_version/src/smp_test_util.c @@ -32,7 +32,7 @@ bool create_mcumgr_format_packet(zcbor_state_t *zse, const uint8_t *format, uint ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "format") && - zcbor_tstr_put_term(zse, format) && + zcbor_tstr_put_term(zse, format, CONFIG_ZCBOR_MAX_STR_LEN) && zcbor_map_end_encode(zse, 2); *buffer_size = (zse->payload_mut - buffer); diff --git a/tests/subsys/mgmt/mcumgr/zcbor_bulk/src/main.c b/tests/subsys/mgmt/mcumgr/zcbor_bulk/src/main.c index e50dc8fe51f..b1d3d79b30a 100644 --- a/tests/subsys/mgmt/mcumgr/zcbor_bulk/src/main.c +++ b/tests/subsys/mgmt/mcumgr/zcbor_bulk/src/main.c @@ -60,7 +60,7 @@ ZTEST(zcbor_bulk, test_correct) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -101,7 +101,7 @@ ZTEST(zcbor_bulk, test_correct_out_of_order) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -140,7 +140,7 @@ ZTEST(zcbor_bulk, test_not_map) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -175,7 +175,7 @@ ZTEST(zcbor_bulk, test_bad_type) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -211,7 +211,7 @@ ZTEST(zcbor_bulk, test_bad_type_2) zcbor_tstr_put_lit(zsd, "bool val") && zcbor_true_put(zsd) && zcbor_map_end_encode(zsd, 10); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -252,7 +252,7 @@ ZTEST(zcbor_bulk, test_bad_type_encoded) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -287,7 +287,7 @@ ZTEST(zcbor_bulk, test_duplicate) zcbor_tstr_put_lit(zsd, "hello") && zcbor_tstr_put_lit(zsd, "world") && zcbor_map_end_encode(zsd, 10); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -366,7 +366,7 @@ ZTEST(zcbor_bulk, test_map_in_map_correct) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -445,7 +445,7 @@ ZTEST(zcbor_bulk, test_map_in_map_bad) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -486,7 +486,7 @@ ZTEST(zcbor_bulk, test_key_found) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); @@ -528,7 +528,7 @@ ZTEST(zcbor_bulk, test_reset) zassert_true(ok, "Expected to be successful in encoding test pattern"); - zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1); + zcbor_new_decode_state(zsd, 4, buffer, ARRAY_SIZE(buffer), 1, NULL, 0); int rc = zcbor_map_decode_bulk(zsd, dm, ARRAY_SIZE(dm), &decoded); diff --git a/tests/subsys/modem/backends/tty/CMakeLists.txt b/tests/subsys/modem/backends/tty/CMakeLists.txt index e692be0de90..44597d8ae95 100644 --- a/tests/subsys/modem/backends/tty/CMakeLists.txt +++ b/tests/subsys/modem/backends/tty/CMakeLists.txt @@ -6,3 +6,4 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(modem_backend_tty_test) target_sources(app PRIVATE src/main.c) +target_compile_definitions(app PRIVATE _XOPEN_SOURCE=600) diff --git a/tests/subsys/modem/backends/tty/src/main.c b/tests/subsys/modem/backends/tty/src/main.c index 49a1841486a..96ebdb2763d 100644 --- a/tests/subsys/modem/backends/tty/src/main.c +++ b/tests/subsys/modem/backends/tty/src/main.c @@ -22,7 +22,8 @@ #define TEST_MODEM_BACKEND_TTY_PIPE_EVENT_OPENED_BIT (0) #define TEST_MODEM_BACKEND_TTY_PIPE_EVENT_RRDY_BIT (1) -#define TEST_MODEM_BACKEND_TTY_PIPE_EVENT_CLOSED_BIT (2) +#define TEST_MODEM_BACKEND_TTY_PIPE_EVENT_TIDLE_BIT (2) +#define TEST_MODEM_BACKEND_TTY_PIPE_EVENT_CLOSED_BIT (3) #define TEST_MODEM_BACKEND_TTY_OP_DELAY (K_MSEC(1000)) @@ -72,6 +73,10 @@ static void modem_pipe_callback_handler(struct modem_pipe *pipe, enum modem_pipe atomic_set_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_RRDY_BIT); break; + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + atomic_set_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_TIDLE_BIT); + break; + case MODEM_PIPE_EVENT_CLOSED: atomic_set_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_CLOSED_BIT); break; @@ -122,9 +127,13 @@ static void test_modem_backend_tty_teardown(void *f) /*************************************************************************************************/ ZTEST(modem_backend_tty_suite, test_close_open) { + bool result; + 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"); + result = atomic_test_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_TIDLE_BIT); + zassert_true(result, "Transmit idle event should be set"); zassert_ok(modem_pipe_open(tty_pipe), "Pipe should already be open"); } @@ -172,12 +181,19 @@ ZTEST(modem_backend_tty_suite, test_transmit) { int ret; char msg[] = "Test me buddy 2"; + bool result; + + result = atomic_test_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_TIDLE_BIT); + zassert_false(result, "Transmit idle event should not be set"); ret = modem_pipe_transmit(tty_pipe, msg, sizeof(msg)); zassert_true(ret == sizeof(msg), "Failed to transmit using pipe"); k_sleep(TEST_MODEM_BACKEND_TTY_OP_DELAY); + result = atomic_test_bit(&tty_pipe_events, TEST_MODEM_BACKEND_TTY_PIPE_EVENT_TIDLE_BIT); + zassert_true(result, "Transmit idle event should be set"); + ret = read(primary_fd, buffer1, sizeof(buffer1)); zassert_true(ret == sizeof(msg), "Read incorrect number of bytes"); ret = memcmp(msg, buffer1, sizeof(msg)); diff --git a/tests/subsys/modem/backends/tty/testcase.yaml b/tests/subsys/modem/backends/tty/testcase.yaml index 11f78b1d641..28d3c3d4aa2 100644 --- a/tests/subsys/modem/backends/tty/testcase.yaml +++ b/tests/subsys/modem/backends/tty/testcase.yaml @@ -5,4 +5,8 @@ tests: modem.backends.tty: tags: modem_backend_tty harness: ztest - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim 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 diff --git a/tests/subsys/modem/mock/modem_backend_mock.c b/tests/subsys/modem/mock/modem_backend_mock.c index 55c5679f35f..5b7b47c0eb4 100644 --- a/tests/subsys/modem/mock/modem_backend_mock.c +++ b/tests/subsys/modem/mock/modem_backend_mock.c @@ -42,6 +42,16 @@ static int modem_backend_mock_transmit(void *data, const uint8_t *buf, size_t si int ret; size = (mock->limit < size) ? mock->limit : size; + + if (mock->bridge) { + struct modem_backend_mock *t_mock = mock->bridge; + + ret = ring_buf_put(&t_mock->rx_rb, buf, size); + k_work_submit(&t_mock->receive_ready_work); + k_work_submit(&mock->transmit_idle_work); + return ret; + } + ret = ring_buf_put(&mock->tx_rb, buf, size); if (modem_backend_mock_update(mock, buf, size)) { modem_backend_mock_put(mock, mock->transaction->put, @@ -50,6 +60,7 @@ static int modem_backend_mock_transmit(void *data, const uint8_t *buf, size_t si mock->transaction = NULL; } + k_work_submit(&mock->transmit_idle_work); return ret; } @@ -76,14 +87,22 @@ struct modem_pipe_api modem_backend_mock_api = { .close = modem_backend_mock_close, }; -static void modem_backend_mock_received_handler(struct k_work *item) +static void modem_backend_mock_receive_ready_handler(struct k_work *item) { - struct modem_backend_mock_work *mock_work_item = (struct modem_backend_mock_work *)item; - struct modem_backend_mock *mock = mock_work_item->mock; + struct modem_backend_mock *mock = + CONTAINER_OF(item, struct modem_backend_mock, receive_ready_work); modem_pipe_notify_receive_ready(&mock->pipe); } +static void modem_backend_mock_transmit_idle_handler(struct k_work *item) +{ + struct modem_backend_mock *mock = + CONTAINER_OF(item, struct modem_backend_mock, transmit_idle_work); + + modem_pipe_notify_transmit_idle(&mock->pipe); +} + struct modem_pipe *modem_backend_mock_init(struct modem_backend_mock *mock, const struct modem_backend_mock_config *config) { @@ -91,8 +110,8 @@ struct modem_pipe *modem_backend_mock_init(struct modem_backend_mock *mock, ring_buf_init(&mock->rx_rb, config->rx_buf_size, config->rx_buf); ring_buf_init(&mock->tx_rb, config->tx_buf_size, config->tx_buf); - mock->received_work_item.mock = mock; - k_work_init(&mock->received_work_item.work, modem_backend_mock_received_handler); + k_work_init(&mock->receive_ready_work, modem_backend_mock_receive_ready_handler); + k_work_init(&mock->transmit_idle_work, modem_backend_mock_transmit_idle_handler); mock->limit = config->limit; modem_pipe_init(&mock->pipe, mock, &modem_backend_mock_api); return &mock->pipe; @@ -121,7 +140,7 @@ void modem_backend_mock_put(struct modem_backend_mock *mock, const uint8_t *buf, __ASSERT(ring_buf_put(&mock->rx_rb, buf, size) == size, "Mock buffer capacity exceeded"); - k_work_submit(&mock->received_work_item.work); + k_work_submit(&mock->receive_ready_work); } void modem_backend_mock_prime(struct modem_backend_mock *mock, @@ -130,3 +149,9 @@ void modem_backend_mock_prime(struct modem_backend_mock *mock, mock->transaction = transaction; mock->transaction_match_cnt = 0; } + +void modem_backend_mock_bridge(struct modem_backend_mock *mock_a, struct modem_backend_mock *mock_b) +{ + mock_a->bridge = mock_b; + mock_b->bridge = mock_a; +} diff --git a/tests/subsys/modem/mock/modem_backend_mock.h b/tests/subsys/modem/mock/modem_backend_mock.h index 1c221963aa8..56a5b585cb1 100644 --- a/tests/subsys/modem/mock/modem_backend_mock.h +++ b/tests/subsys/modem/mock/modem_backend_mock.h @@ -11,13 +11,6 @@ #ifndef ZEPHYR_DRIVERS_MODEM_MODEM_PIPE_MOCK #define ZEPHYR_DRIVERS_MODEM_MODEM_PIPE_MOCK -struct modem_backend_mock; - -struct modem_backend_mock_work { - struct k_work work; - struct modem_backend_mock *mock; -}; - struct modem_backend_mock_transaction { /* Get data which will trigger put */ const uint8_t *get; @@ -34,13 +27,16 @@ struct modem_backend_mock { struct ring_buf rx_rb; struct ring_buf tx_rb; - struct modem_backend_mock_work received_work_item; + struct k_work receive_ready_work; + struct k_work transmit_idle_work; const struct modem_backend_mock_transaction *transaction; size_t transaction_match_cnt; /* Max allowed read/write size */ size_t limit; + /* Mock Brige pair */ + struct modem_backend_mock *bridge; }; struct modem_backend_mock_config { @@ -63,4 +59,7 @@ void modem_backend_mock_put(struct modem_backend_mock *mock, const uint8_t *buf, void modem_backend_mock_prime(struct modem_backend_mock *mock, const struct modem_backend_mock_transaction *transaction); +void modem_backend_mock_bridge(struct modem_backend_mock *mock_a, + struct modem_backend_mock *mock_b); + #endif /* ZEPHYR_DRIVERS_MODEM_MODEM_PIPE_MOCK */ diff --git a/tests/subsys/modem/modem_chat/src/main.c b/tests/subsys/modem/modem_chat/src/main.c index 3f1ef57754d..f9a37ecc6cc 100644 --- a/tests/subsys/modem/modem_chat/src/main.c +++ b/tests/subsys/modem/modem_chat/src/main.c @@ -254,7 +254,6 @@ static void *test_modem_chat_setup(void) .argv_size = ARRAY_SIZE(cmd_argv), .unsol_matches = unsol_matches, .unsol_matches_size = ARRAY_SIZE(unsol_matches), - .process_timeout = K_MSEC(2), }; zassert(modem_chat_init(&cmd, &cmd_config) == 0, "Failed to init modem CMD"); diff --git a/tests/subsys/modem/modem_chat/testcase.yaml b/tests/subsys/modem/modem_chat/testcase.yaml index 8716d7f0d17..2b8723428ea 100644 --- a/tests/subsys/modem/modem_chat/testcase.yaml +++ b/tests/subsys/modem/modem_chat/testcase.yaml @@ -5,4 +5,8 @@ tests: modem.modem_chat: tags: modem_chat harness: ztest - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim diff --git a/tests/subsys/modem/modem_cmux/src/main.c b/tests/subsys/modem/modem_cmux/src/main.c index 9df6837efc5..b08cf26b5af 100644 --- a/tests/subsys/modem/modem_cmux/src/main.c +++ b/tests/subsys/modem/modem_cmux/src/main.c @@ -17,12 +17,16 @@ /*************************************************************************************************/ /* Definitions */ /*************************************************************************************************/ -#define EVENT_CMUX_CONNECTED BIT(0) -#define EVENT_CMUX_DLCI1_OPEN BIT(1) -#define EVENT_CMUX_DLCI2_OPEN BIT(2) -#define EVENT_CMUX_DLCI1_CLOSED BIT(3) -#define EVENT_CMUX_DLCI2_CLOSED BIT(4) -#define EVENT_CMUX_DISCONNECTED BIT(5) +#define EVENT_CMUX_CONNECTED BIT(0) +#define EVENT_CMUX_DLCI1_OPEN BIT(1) +#define EVENT_CMUX_DLCI2_OPEN BIT(2) +#define EVENT_CMUX_DLCI1_RECEIVE_READY BIT(3) +#define EVENT_CMUX_DLCI1_TRANSMIT_IDLE BIT(4) +#define EVENT_CMUX_DLCI2_RECEIVE_READY BIT(5) +#define EVENT_CMUX_DLCI2_TRANSMIT_IDLE BIT(6) +#define EVENT_CMUX_DLCI1_CLOSED BIT(7) +#define EVENT_CMUX_DLCI2_CLOSED BIT(8) +#define EVENT_CMUX_DISCONNECTED BIT(9) /*************************************************************************************************/ /* Instances */ @@ -59,6 +63,14 @@ static void test_modem_dlci1_pipe_callback(struct modem_pipe *pipe, enum modem_p k_event_post(&cmux_event, EVENT_CMUX_DLCI1_OPEN); break; + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event, EVENT_CMUX_DLCI1_RECEIVE_READY); + break; + + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + k_event_post(&cmux_event, EVENT_CMUX_DLCI1_TRANSMIT_IDLE); + break; + case MODEM_PIPE_EVENT_CLOSED: k_event_post(&cmux_event, EVENT_CMUX_DLCI1_CLOSED); break; @@ -76,6 +88,14 @@ static void test_modem_dlci2_pipe_callback(struct modem_pipe *pipe, enum modem_p k_event_post(&cmux_event, EVENT_CMUX_DLCI2_OPEN); break; + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); + break; + + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + k_event_post(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE); + break; + case MODEM_PIPE_EVENT_CLOSED: k_event_post(&cmux_event, EVENT_CMUX_DLCI2_CLOSED); break; @@ -144,8 +164,6 @@ static uint8_t cmux_frame_data_dlci1_at_newline[] = {0x0D, 0x0A}; /*************************************************************************************************/ static uint8_t cmux_frame_dlci1_at_at_desync[] = {0x41, 0x54, 0x30, 0xF9}; -static uint8_t cmux_frame_resync[] = {0xF9, 0xF9, 0xF9}; - /*************************************************************************************************/ /* DLCI2 PPP CMUX frames */ /*************************************************************************************************/ @@ -302,6 +320,7 @@ static void test_modem_cmux_before(void *f) ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at) { int ret; + uint32_t events; modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont, sizeof(cmux_frame_dlci2_at_cgdcont)); @@ -311,6 +330,10 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at) k_msleep(100); + events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); + zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY, + "Receive ready event not received for DLCI2 pipe"); + ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2)); zassert_true(ret == (sizeof(cmux_frame_data_dlci2_at_cgdcont) + sizeof(cmux_frame_data_dlci2_at_newline)), @@ -329,6 +352,7 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_at) ZTEST(modem_cmux, test_modem_cmux_receive_dlci1_at) { int ret; + uint32_t events; modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at, sizeof(cmux_frame_dlci1_at_at)); modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline, @@ -336,6 +360,10 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci1_at) k_msleep(100); + events = k_event_test(&cmux_event, EVENT_CMUX_DLCI1_RECEIVE_READY); + zassert_equal(events, EVENT_CMUX_DLCI1_RECEIVE_READY, + "Receive ready event not received for DLCI1 pipe"); + ret = modem_pipe_receive(dlci1_pipe, buffer1, sizeof(buffer1)); zassert_true(ret == (sizeof(cmux_frame_data_dlci1_at_at) + sizeof(cmux_frame_data_dlci1_at_newline)), @@ -354,12 +382,17 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci1_at) ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_ppp) { int ret; + uint32_t events; modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_52, sizeof(cmux_frame_dlci2_ppp_52)); modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_ppp_18, sizeof(cmux_frame_dlci2_ppp_18)); k_msleep(100); + events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY); + zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY, + "Receive ready event not received for DLCI2 pipe"); + ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2)); zassert_true(ret == (sizeof(cmux_frame_data_dlci2_ppp_52) + sizeof(cmux_frame_data_dlci2_ppp_18)), @@ -378,17 +411,25 @@ ZTEST(modem_cmux, test_modem_cmux_receive_dlci2_ppp) ZTEST(modem_cmux, test_modem_cmux_transmit_dlci2_ppp) { int ret; + uint32_t events; ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_52, sizeof(cmux_frame_data_dlci2_ppp_52)); - zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_52), "Failed to send DLCI2 PPP 52"); + + events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200)); + zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, + "Transmit idle event not received for DLCI2 pipe"); + + k_event_clear(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE); + ret = modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_18, sizeof(cmux_frame_data_dlci2_ppp_18)); - zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_18), "Failed to send DLCI2 PPP 18"); - k_msleep(100); + events = k_event_wait(&cmux_event, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, false, K_MSEC(200)); + zassert_equal(events, EVENT_CMUX_DLCI2_TRANSMIT_IDLE, + "Transmit idle event not received for DLCI2 pipe"); ret = modem_backend_mock_get(&bus_mock, buffer2, sizeof(buffer2)); zassert_true(ret == (sizeof(cmux_frame_dlci2_ppp_52) + sizeof(cmux_frame_dlci2_ppp_18)), @@ -401,15 +442,6 @@ ZTEST(modem_cmux, test_modem_cmux_resync) modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at_desync, sizeof(cmux_frame_dlci1_at_at_desync)); - - k_msleep(100); - - ret = modem_backend_mock_get(&bus_mock, buffer1, sizeof(buffer1)); - zassert_true(ret == sizeof(cmux_frame_resync), "Expected resync flags to be sent to bus"); - zassert_true(memcmp(buffer1, cmux_frame_resync, sizeof(cmux_frame_resync)) == 0, - "Expected resync flags to be sent to bus"); - - modem_backend_mock_put(&bus_mock, cmux_frame_resync, sizeof(cmux_frame_resync)); modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_at, sizeof(cmux_frame_dlci1_at_at)); modem_backend_mock_put(&bus_mock, cmux_frame_dlci1_at_newline, sizeof(cmux_frame_dlci1_at_newline)); diff --git a/tests/subsys/modem/modem_cmux/testcase.yaml b/tests/subsys/modem/modem_cmux/testcase.yaml index c7d1f53a085..fd89a3f5656 100644 --- a/tests/subsys/modem/modem_cmux/testcase.yaml +++ b/tests/subsys/modem/modem_cmux/testcase.yaml @@ -5,4 +5,8 @@ tests: modem.modem_cmux: tags: modem_cmux harness: ztest - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim diff --git a/tests/subsys/modem/modem_cmux_pair/CMakeLists.txt b/tests/subsys/modem/modem_cmux_pair/CMakeLists.txt new file mode 100644 index 00000000000..00efcc5695b --- /dev/null +++ b/tests/subsys/modem/modem_cmux_pair/CMakeLists.txt @@ -0,0 +1,9 @@ +# 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(modem_cmux_pair_test) + +target_sources(app PRIVATE src/main.c ../mock/modem_backend_mock.c) +target_include_directories(app PRIVATE ../mock) diff --git a/tests/subsys/modem/modem_cmux_pair/prj.conf b/tests/subsys/modem/modem_cmux_pair/prj.conf new file mode 100644 index 00000000000..bf21fcb42ac --- /dev/null +++ b/tests/subsys/modem/modem_cmux_pair/prj.conf @@ -0,0 +1,9 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_NO_OPTIMIZATIONS=y + +CONFIG_MODEM_MODULES=y +CONFIG_MODEM_CMUX=y + +CONFIG_ZTEST=y diff --git a/tests/subsys/modem/modem_cmux_pair/src/main.c b/tests/subsys/modem/modem_cmux_pair/src/main.c new file mode 100644 index 00000000000..6c38fd7e98b --- /dev/null +++ b/tests/subsys/modem/modem_cmux_pair/src/main.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include + +/* CMUX state flags */ +#define EVENT_CMUX_CONNECTED BIT(0) +#define EVENT_CMUX_DLCI1_OPEN BIT(1) +#define EVENT_CMUX_DLCI2_OPEN BIT(2) +#define EVENT_CMUX_DLCI1_CLOSED BIT(3) +#define EVENT_CMUX_DLCI2_CLOSED BIT(4) +#define EVENT_CMUX_DISCONNECTED BIT(5) +#define EVENT_CMUX_DLCI1_RX_DATA BIT(6) +#define EVENT_CMUX_DLCI2_RX_DATA BIT(7) + +/* CMUX DTE variables */ +static struct modem_cmux cmux_dte; +static uint8_t cmux_receive_buf[127]; +static uint8_t cmux_transmit_buf[149]; +static struct modem_cmux_dlci dlci1; +static struct modem_cmux_dlci dlci2; +static struct modem_pipe *dlci1_pipe; +static struct modem_pipe *dlci2_pipe; + +/* CMUX DCE variables */ +static struct modem_cmux cmux_dce; +static uint8_t cmux_receive_buf_dce[127]; +static uint8_t cmux_transmit_buf_dce[149]; +static struct modem_cmux_dlci dlci1_dce; +static struct modem_cmux_dlci dlci2_dce; +static struct modem_pipe *dlci1_pipe_dce; +static struct modem_pipe *dlci2_pipe_dce; + +/* DTE & DCE Event */ +static struct k_event cmux_event_dte; +static struct k_event cmux_event_dce; + +/* Backend MOCK */ +static struct modem_backend_mock bus_mock_dte; +static struct modem_backend_mock bus_mock_dce; +static uint8_t bus_mock_rx_buf[2048]; +static uint8_t bus_mock_tx_buf[2048]; +static uint8_t bus_mock_rx_buf_dce[2048]; +static uint8_t bus_mock_tx_buf_dce[2048]; +static struct modem_pipe *bus_mock_pipe; +static struct modem_pipe *bus_mock_pipe_dce; + +static uint8_t dlci1_receive_buf[127]; +static uint8_t dlci2_receive_buf[127]; +static uint8_t dlci1_receive_buf_dce[127]; +static uint8_t dlci2_receive_buf_dce[127]; + +static uint8_t buffer1[2048]; +static uint8_t buffer2[2048]; + +static void test_dlci1_pipe_cb(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI1_OPEN); + break; + + case MODEM_PIPE_EVENT_CLOSED: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI1_CLOSED); + break; + + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI1_RX_DATA); + break; + + default: + break; + } +} + +static void test_dlci2_pipe_cb(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI2_OPEN); + break; + + case MODEM_PIPE_EVENT_CLOSED: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI2_CLOSED); + break; + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event_dte, EVENT_CMUX_DLCI2_RX_DATA); + break; + + default: + break; + } +} + +static void test_dlci1_pipe_cb_dce(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI1_OPEN); + break; + + case MODEM_PIPE_EVENT_CLOSED: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI1_CLOSED); + break; + + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI1_RX_DATA); + break; + + default: + break; + } +} + +static void test_dlci2_pipe_cb_dce(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI2_OPEN); + break; + + case MODEM_PIPE_EVENT_CLOSED: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI2_CLOSED); + break; + case MODEM_PIPE_EVENT_RECEIVE_READY: + k_event_post(&cmux_event_dce, EVENT_CMUX_DLCI2_RX_DATA); + break; + + default: + break; + } +} + +/*************************************************************************************************/ +/* DLCI2 AT CMUX frames */ +/*************************************************************************************************/ +static uint8_t cmux_frame_data_dlci2_at_cgdcont[] = { + 0x41, 0x54, 0x2B, 0x43, 0x47, 0x44, 0x43, 0x4F, 0x4E, 0x54, 0x3D, + 0x31, 0x2C, 0x22, 0x49, 0x50, 0x22, 0x2C, 0x22, 0x74, 0x72, 0x61, + 0x63, 0x6B, 0x75, 0x6E, 0x69, 0x74, 0x2E, 0x6D, 0x32, 0x6D, 0x22}; + +static uint8_t cmux_frame_data_dlci2_at_newline[] = {0x0D, 0x0A}; + +/*************************************************************************************************/ +/* DLCI1 AT CMUX frames */ +/*************************************************************************************************/ +static uint8_t cmux_frame_data_dlci1_at_at[] = {0x41, 0x54}; + +static uint8_t cmux_frame_data_dlci1_at_newline[] = {0x0D, 0x0A}; + +/*************************************************************************************************/ +/* DLCI2 PPP CMUX frames */ +/*************************************************************************************************/ +static uint8_t cmux_frame_data_dlci2_ppp_52[] = { + 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}; + +static uint8_t cmux_frame_data_dlci2_ppp_18[] = {0x7E, 0xFF, 0x7D, 0x23, 0xC0, 0x21, + 0x7D, 0x22, 0x7D, 0x21, 0x7D, 0x20, + 0x7D, 0x24, 0x7D, 0x3C, 0x90, 0x7E}; + +static void test_cmux_ctrl_cb(struct modem_cmux *cmux, enum modem_cmux_event event, void *user_data) +{ + if (event == MODEM_CMUX_EVENT_CONNECTED) { + k_event_post(&cmux_event_dte, EVENT_CMUX_CONNECTED); + return; + } + + if (event == MODEM_CMUX_EVENT_DISCONNECTED) { + k_event_post(&cmux_event_dte, EVENT_CMUX_DISCONNECTED); + return; + } +} + +static void test_cmux_ctrl_cb_dce(struct modem_cmux *cmux, enum modem_cmux_event event, + void *user_data) +{ + if (event == MODEM_CMUX_EVENT_CONNECTED) { + k_event_post(&cmux_event_dce, EVENT_CMUX_CONNECTED); + return; + } + + if (event == MODEM_CMUX_EVENT_DISCONNECTED) { + k_event_post(&cmux_event_dce, EVENT_CMUX_DISCONNECTED); + return; + } +} + +static void cmux_dte_init(void) +{ + struct modem_cmux_dlci_config dlci1_config = { + .dlci_address = 1, + .receive_buf = dlci1_receive_buf, + .receive_buf_size = sizeof(dlci1_receive_buf), + }; + + struct modem_cmux_dlci_config dlci2_config = { + .dlci_address = 2, + .receive_buf = dlci2_receive_buf, + .receive_buf_size = sizeof(dlci2_receive_buf), + }; + + struct modem_cmux_config cmux_config = { + .callback = test_cmux_ctrl_cb, + .user_data = NULL, + .receive_buf = cmux_receive_buf, + .receive_buf_size = sizeof(cmux_receive_buf), + .transmit_buf = cmux_transmit_buf, + .transmit_buf_size = ARRAY_SIZE(cmux_transmit_buf), + }; + + const struct modem_backend_mock_config bus_mock_config = { + .rx_buf = bus_mock_rx_buf, + .rx_buf_size = sizeof(bus_mock_rx_buf), + .tx_buf = bus_mock_tx_buf, + .tx_buf_size = sizeof(bus_mock_tx_buf), + .limit = 32, + }; + + modem_cmux_init(&cmux_dte, &cmux_config); + dlci1_pipe = modem_cmux_dlci_init(&cmux_dte, &dlci1, &dlci1_config); + dlci2_pipe = modem_cmux_dlci_init(&cmux_dte, &dlci2, &dlci2_config); + /* Init Backend DTE */ + bus_mock_pipe = modem_backend_mock_init(&bus_mock_dte, &bus_mock_config); + __ASSERT_NO_MSG(modem_pipe_open(bus_mock_pipe) == 0); + __ASSERT_NO_MSG(modem_cmux_attach(&cmux_dte, bus_mock_pipe) == 0); + modem_pipe_attach(dlci1_pipe, test_dlci1_pipe_cb, NULL); + modem_pipe_attach(dlci2_pipe, test_dlci2_pipe_cb, NULL); +} + +static void cmux_dce_init(void) +{ + struct modem_cmux_dlci_config dlci1_config = { + .dlci_address = 1, + .receive_buf = dlci1_receive_buf_dce, + .receive_buf_size = sizeof(dlci1_receive_buf_dce), + }; + + struct modem_cmux_dlci_config dlci2_config = { + .dlci_address = 2, + .receive_buf = dlci2_receive_buf_dce, + .receive_buf_size = sizeof(dlci2_receive_buf_dce), + }; + + struct modem_cmux_config cmux_config_dce = { + .callback = test_cmux_ctrl_cb_dce, + .user_data = NULL, + .receive_buf = cmux_receive_buf_dce, + .receive_buf_size = sizeof(cmux_receive_buf_dce), + .transmit_buf = cmux_transmit_buf_dce, + .transmit_buf_size = ARRAY_SIZE(cmux_transmit_buf_dce), + }; + + const struct modem_backend_mock_config bus_mock_config = { + .rx_buf = bus_mock_rx_buf_dce, + .rx_buf_size = sizeof(bus_mock_rx_buf_dce), + .tx_buf = bus_mock_tx_buf_dce, + .tx_buf_size = sizeof(bus_mock_tx_buf_dce), + .limit = 32, + }; + + modem_cmux_init(&cmux_dce, &cmux_config_dce); + dlci1_pipe_dce = modem_cmux_dlci_init(&cmux_dce, &dlci1_dce, &dlci1_config); + dlci2_pipe_dce = modem_cmux_dlci_init(&cmux_dce, &dlci2_dce, &dlci2_config); + /* Init Backend DCE */ + bus_mock_pipe_dce = modem_backend_mock_init(&bus_mock_dce, &bus_mock_config); + __ASSERT_NO_MSG(modem_pipe_open(bus_mock_pipe_dce) == 0); + __ASSERT_NO_MSG(modem_cmux_attach(&cmux_dce, bus_mock_pipe_dce) == 0); + modem_pipe_attach(dlci1_pipe_dce, test_dlci1_pipe_cb_dce, NULL); + modem_pipe_attach(dlci2_pipe_dce, test_dlci2_pipe_cb_dce, NULL); +} + +static void *test_setup(void) +{ + uint32_t events; + + /* Init Event mask's */ + k_event_init(&cmux_event_dte); + k_event_init(&cmux_event_dce); + + /* Init CMUX, Pipe and Backend instances */ + cmux_dte_init(); + cmux_dce_init(); + + /* Create MOCK bridge */ + modem_backend_mock_bridge(&bus_mock_dte, &bus_mock_dce); + + /* Connect CMUX by DTE */ + __ASSERT_NO_MSG(modem_cmux_connect_async(&cmux_dte) == 0); + events = k_event_wait(&cmux_event_dte, EVENT_CMUX_CONNECTED, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_CONNECTED)); + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_CONNECTED, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_CONNECTED)); + + /* Open DLCI channels init by DTE */ + __ASSERT_NO_MSG(modem_pipe_open_async(dlci1_pipe) == 0); + events = k_event_wait(&cmux_event_dte, EVENT_CMUX_DLCI1_OPEN, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI1_OPEN)); + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_DLCI1_OPEN, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI1_OPEN)); + + __ASSERT_NO_MSG(modem_pipe_open_async(dlci2_pipe) == 0); + events = k_event_wait(&cmux_event_dte, EVENT_CMUX_DLCI2_OPEN, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI2_OPEN)); + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_DLCI2_OPEN, false, K_MSEC(100)); + __ASSERT_NO_MSG((events & EVENT_CMUX_DLCI2_OPEN)); + + return NULL; +} + +static void test_before(void *f) +{ + /* Reset events */ + k_event_clear(&cmux_event_dte, UINT32_MAX); + k_event_clear(&cmux_event_dce, UINT32_MAX); + + /* Reset mock pipes */ + modem_backend_mock_reset(&bus_mock_dte); + modem_backend_mock_reset(&bus_mock_dce); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dce_receive_dlci2_at) +{ + int ret; + uint32_t events; + + modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_at_cgdcont, + sizeof(cmux_frame_data_dlci2_at_cgdcont)); + + modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_at_newline, + sizeof(cmux_frame_data_dlci2_at_newline)); + + k_msleep(100); + + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_DLCI2_RX_DATA, false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI2_RX_DATA), "DLCI2 dce not rx data"); + + ret = modem_pipe_receive(dlci2_pipe_dce, buffer2, sizeof(buffer2)); + zassert_true(ret == (sizeof(cmux_frame_data_dlci2_at_cgdcont) + + sizeof(cmux_frame_data_dlci2_at_newline)), + "Incorrect number of bytes received"); + + zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_at_cgdcont, + sizeof(cmux_frame_data_dlci2_at_cgdcont)) == 0, + "Incorrect data received"); + + zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_at_cgdcont)], + cmux_frame_data_dlci2_at_newline, + sizeof(cmux_frame_data_dlci2_at_newline)) == 0, + "Incorrect data received"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dce_receive_dlci1_at) +{ + int ret; + uint32_t events; + + modem_pipe_transmit(dlci1_pipe, cmux_frame_data_dlci1_at_at, + sizeof(cmux_frame_data_dlci1_at_at)); + modem_pipe_transmit(dlci1_pipe, cmux_frame_data_dlci1_at_newline, + sizeof(cmux_frame_data_dlci1_at_newline)); + + k_msleep(100); + + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_DLCI1_RX_DATA, false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI1_RX_DATA), "DLCI1 dce not rx data"); + + ret = modem_pipe_receive(dlci1_pipe_dce, buffer1, sizeof(buffer1)); + zassert_true(ret == (sizeof(cmux_frame_data_dlci1_at_at) + + sizeof(cmux_frame_data_dlci1_at_newline)), + "Incorrect number of bytes received"); + + zassert_true(memcmp(buffer1, cmux_frame_data_dlci1_at_at, + sizeof(cmux_frame_data_dlci1_at_at)) == 0, + "Incorrect data received"); + + zassert_true(memcmp(&buffer1[sizeof(cmux_frame_data_dlci1_at_at)], + cmux_frame_data_dlci1_at_newline, + sizeof(cmux_frame_data_dlci1_at_newline)) == 0, + "Incorrect data received"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dce_receive_dlci2_ppp) +{ + int ret; + + uint32_t events; + + modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_52, + sizeof(cmux_frame_data_dlci2_ppp_52)); + modem_pipe_transmit(dlci2_pipe, cmux_frame_data_dlci2_ppp_18, + sizeof(cmux_frame_data_dlci2_ppp_18)); + + k_msleep(100); + + events = k_event_wait(&cmux_event_dce, EVENT_CMUX_DLCI2_RX_DATA, false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI2_RX_DATA), "DLCI2 dce not rx data"); + + ret = modem_pipe_receive(dlci2_pipe_dce, buffer2, sizeof(buffer2)); + zassert_true(ret == (sizeof(cmux_frame_data_dlci2_ppp_52) + + sizeof(cmux_frame_data_dlci2_ppp_18)), + "Incorrect number of bytes received"); + + zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_ppp_52, + sizeof(cmux_frame_data_dlci2_ppp_52)) == 0, + "Incorrect data received"); + + zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_ppp_52)], + cmux_frame_data_dlci2_ppp_18, + sizeof(cmux_frame_data_dlci2_ppp_18)) == 0, + "Incorrect data received"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dce_transmit_dlci2_ppp) +{ + int ret; + uint32_t events; + + ret = modem_pipe_transmit(dlci2_pipe_dce, cmux_frame_data_dlci2_ppp_52, + sizeof(cmux_frame_data_dlci2_ppp_52)); + + zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_52), "Failed to send DLCI2 PPP 52 %d", + ret); + ret = modem_pipe_transmit(dlci2_pipe_dce, cmux_frame_data_dlci2_ppp_18, + sizeof(cmux_frame_data_dlci2_ppp_18)); + + zassert_true(ret == sizeof(cmux_frame_data_dlci2_ppp_18), "Failed to send DLCI2 PPP 18"); + + k_msleep(100); + + events = k_event_wait(&cmux_event_dte, EVENT_CMUX_DLCI2_RX_DATA, false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI2_RX_DATA), "DLCI2 dce not rx data"); + + ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2)); + zassert_true(ret == (sizeof(cmux_frame_data_dlci2_ppp_52) + + sizeof(cmux_frame_data_dlci2_ppp_18)), + "Incorrect number of bytes received"); + + zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_ppp_52, + sizeof(cmux_frame_data_dlci2_ppp_52)) == 0, + "Incorrect data received"); + + zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_ppp_52)], + cmux_frame_data_dlci2_ppp_18, + sizeof(cmux_frame_data_dlci2_ppp_18)) == 0, + "Incorrect data received"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dlci1_close_open) +{ + uint32_t events; + + /* Close DLCI1 */ + zassert_true(modem_pipe_close_async(dlci1_pipe) == 0, "Failed to close DLCI1 pipe"); + k_msleep(100); + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_DLCI1_CLOSED), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "DLCI1 not closed as expected"); + events = k_event_wait_all(&cmux_event_dce, (EVENT_CMUX_DLCI1_CLOSED), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "DLCI1 not closed as expected"); + + /* Open DLCI1 */ + zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); + + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_DLCI1_OPEN), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_OPEN), "DLCI1 not opened as expected"); + events = k_event_wait_all(&cmux_event_dce, (EVENT_CMUX_DLCI1_OPEN), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_OPEN), "DLCI1 not opened as expected"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_disconnect_connect) +{ + uint32_t events; + + /* Disconnect CMUX */ + zassert_true(modem_pipe_close_async(dlci1_pipe) == 0, "Failed to close DLCI1"); + zassert_true(modem_pipe_close_async(dlci2_pipe) == 0, "Failed to close DLCI2"); + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, + (EVENT_CMUX_DLCI1_CLOSED | EVENT_CMUX_DLCI2_CLOSED), false, + K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "Failed to close DLCI1"); + zassert_true((events & EVENT_CMUX_DLCI2_CLOSED), "Failed to close DLCI2"); + + /* Discard CMUX DLCI DISC commands */ + modem_backend_mock_reset(&bus_mock_dte); + zassert_true(modem_cmux_disconnect_async(&cmux_dte) == 0, "Failed to disconnect CMUX"); + + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_DISCONNECTED), false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DISCONNECTED), "Failed to disconnect CMUX"); + + /* Reconnect CMUX */ + zassert_true(modem_cmux_connect_async(&cmux_dte) == 0, "Failed to connect CMUX"); + + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_CONNECTED), false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_CONNECTED), "Failed to connect CMUX"); + + /* Open DLCI1 */ + zassert_true(modem_pipe_open_async(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); + + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_DLCI1_OPEN), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI1_OPEN), "DLCI1 not opened as expected"); + + /* Open DLCI2 */ + zassert_true(modem_pipe_open_async(dlci2_pipe) == 0, "Failed to open DLCI2 pipe"); + + k_msleep(100); + + events = k_event_wait_all(&cmux_event_dte, (EVENT_CMUX_DLCI2_OPEN), false, K_MSEC(100)); + + zassert_true((events & EVENT_CMUX_DLCI2_OPEN), "DLCI1 not opened as expected"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_disconnect_connect_sync) +{ + uint32_t events; + + zassert_true(modem_pipe_close(dlci1_pipe) == 0, "Failed to close DLCI1"); + zassert_true(modem_pipe_close(dlci2_pipe) == 0, "Failed to close DLCI2"); + events = k_event_wait_all(&cmux_event_dce, + (EVENT_CMUX_DLCI1_CLOSED | EVENT_CMUX_DLCI2_CLOSED), false, + K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "DCE DLCI1 not closed as expected"); + zassert_true((events & EVENT_CMUX_DLCI2_CLOSED), "DCE DLCI2 not closed as expected"); + + zassert_true(modem_cmux_disconnect(&cmux_dte) == 0, "Failed to disconnect CMUX"); + zassert_true(modem_cmux_disconnect(&cmux_dte) == -EALREADY, + "Should already be disconnected"); + zassert_true(modem_cmux_disconnect(&cmux_dce) == -EALREADY, + "Should already be disconnected"); + + k_msleep(100); + + zassert_true(modem_cmux_connect(&cmux_dte) == 0, "Failed to connect CMUX"); + zassert_true(modem_cmux_connect(&cmux_dte) == -EALREADY, "Should already be connected"); + zassert_true(modem_cmux_connect(&cmux_dce) == -EALREADY, "Should already be connected"); + + zassert_true(modem_pipe_open(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); + zassert_true(modem_pipe_open(dlci2_pipe) == 0, "Failed to open DLCI2 pipe"); + events = k_event_wait_all(&cmux_event_dce, (EVENT_CMUX_DLCI1_OPEN | EVENT_CMUX_DLCI2_OPEN), + false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI1_OPEN), "DCE DLCI1 not open as expected"); + zassert_true((events & EVENT_CMUX_DLCI2_OPEN), "DCE DLCI2 not open as expected"); +} + +ZTEST(modem_cmux_pair, test_modem_cmux_dlci_close_open_sync) +{ + uint32_t events; + + zassert_true(modem_pipe_close(dlci1_pipe) == 0, "Failed to close DLCI1"); + zassert_true(modem_pipe_close(dlci2_pipe) == 0, "Failed to close DLCI2"); + + events = k_event_wait_all(&cmux_event_dce, + (EVENT_CMUX_DLCI1_CLOSED | EVENT_CMUX_DLCI2_CLOSED), false, + K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI1_CLOSED), "DCE DLCI1 not closed as expected"); + zassert_true((events & EVENT_CMUX_DLCI2_CLOSED), "DCE DLCI2 not closed as expected"); + + zassert_true(modem_pipe_open(dlci1_pipe) == 0, "Failed to open DLCI1 pipe"); + zassert_true(modem_pipe_open(dlci2_pipe) == 0, "Failed to open DLCI2 pipe"); + /* Verify DCE side channels are open also */ + events = k_event_wait_all(&cmux_event_dce, (EVENT_CMUX_DLCI1_OPEN | EVENT_CMUX_DLCI2_OPEN), + false, K_MSEC(100)); + zassert_true((events & EVENT_CMUX_DLCI1_OPEN), "DCE DLCI1 not open as expected"); + zassert_true((events & EVENT_CMUX_DLCI2_OPEN), "DCE DLCI2 not open as expected"); +} + +ZTEST_SUITE(modem_cmux_pair, NULL, test_setup, test_before, NULL, NULL); diff --git a/tests/subsys/modem/modem_cmux_pair/testcase.yaml b/tests/subsys/modem/modem_cmux_pair/testcase.yaml new file mode 100644 index 00000000000..9d0cdf33420 --- /dev/null +++ b/tests/subsys/modem/modem_cmux_pair/testcase.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +tests: + modem.modem_cmux_pair: + tags: modem_cmux + harness: ztest + platform_allow: native_sim diff --git a/tests/subsys/modem/modem_pipe/CMakeLists.txt b/tests/subsys/modem/modem_pipe/CMakeLists.txt new file mode 100644 index 00000000000..9d160a67720 --- /dev/null +++ b/tests/subsys/modem/modem_pipe/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_pipe_test) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/subsys/modem/modem_pipe/prj.conf b/tests/subsys/modem/modem_pipe/prj.conf new file mode 100644 index 00000000000..ab3228738b9 --- /dev/null +++ b/tests/subsys/modem/modem_pipe/prj.conf @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_NO_OPTIMIZATIONS=y +CONFIG_MODEM_MODULES=y +CONFIG_MODEM_PIPE=y +CONFIG_EVENTS=y +CONFIG_ZTEST=y diff --git a/tests/subsys/modem/modem_pipe/src/main.c b/tests/subsys/modem/modem_pipe/src/main.c new file mode 100644 index 00000000000..07cc93decfe --- /dev/null +++ b/tests/subsys/modem/modem_pipe/src/main.c @@ -0,0 +1,401 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/*************************************************************************************************/ +/* Dependencies */ +/*************************************************************************************************/ +#include +#include +#include +#include +#include + +#define TEST_MODEM_PIPE_EVENT_OPENED_BIT 0 +#define TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT 1 +#define TEST_MODEM_PIPE_EVENT_RECEIVE_READY_BIT 2 +#define TEST_MODEM_PIPE_EVENT_CLOSED_BIT 3 +#define TEST_MODEM_PIPE_NOTIFY_TIMEOUT K_MSEC(10) +#define TEST_MODEM_PIPE_WAIT_TIMEOUT K_MSEC(20) + +/*************************************************************************************************/ +/* Fake modem_pipe backend */ +/*************************************************************************************************/ +struct modem_backend_fake { + struct modem_pipe pipe; + + struct k_work_delayable opened_dwork; + struct k_work_delayable transmit_idle_dwork; + struct k_work_delayable closed_dwork; + + const uint8_t *transmit_buffer; + size_t transmit_buffer_size; + + uint8_t *receive_buffer; + size_t receive_buffer_size; + + uint8_t synchronous : 1; + uint8_t open_called : 1; + uint8_t transmit_called : 1; + uint8_t receive_called : 1; + uint8_t close_called : 1; +}; + +static void modem_backend_fake_opened_handler(struct k_work *item) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(item); + struct modem_backend_fake *backend = + CONTAINER_OF(dwork, struct modem_backend_fake, opened_dwork); + + modem_pipe_notify_opened(&backend->pipe); +} + +static int modem_backend_fake_open(void *data) +{ + struct modem_backend_fake *backend = data; + + backend->open_called = true; + + if (backend->synchronous) { + modem_pipe_notify_opened(&backend->pipe); + } else { + k_work_schedule(&backend->opened_dwork, TEST_MODEM_PIPE_NOTIFY_TIMEOUT); + } + + return 0; +} + +static void modem_backend_fake_transmit_idle_handler(struct k_work *item) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(item); + struct modem_backend_fake *backend = + CONTAINER_OF(dwork, struct modem_backend_fake, transmit_idle_dwork); + + modem_pipe_notify_transmit_idle(&backend->pipe); +} + +static int modem_backend_fake_transmit(void *data, const uint8_t *buf, size_t size) +{ + struct modem_backend_fake *backend = data; + + backend->transmit_called = true; + backend->transmit_buffer = buf; + backend->transmit_buffer_size = size; + + if (backend->synchronous) { + modem_pipe_notify_transmit_idle(&backend->pipe); + } else { + k_work_schedule(&backend->transmit_idle_dwork, TEST_MODEM_PIPE_NOTIFY_TIMEOUT); + } + + return size; +} + +static int modem_backend_fake_receive(void *data, uint8_t *buf, size_t size) +{ + struct modem_backend_fake *backend = data; + + backend->receive_called = true; + backend->receive_buffer = buf; + backend->receive_buffer_size = size; + return size; +} + +static void modem_backend_fake_closed_handler(struct k_work *item) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(item); + struct modem_backend_fake *backend = + CONTAINER_OF(dwork, struct modem_backend_fake, closed_dwork); + + modem_pipe_notify_closed(&backend->pipe); +} + +static int modem_backend_fake_close(void *data) +{ + struct modem_backend_fake *backend = data; + + backend->close_called = true; + + if (backend->synchronous) { + modem_pipe_notify_closed(&backend->pipe); + } else { + k_work_schedule(&backend->closed_dwork, TEST_MODEM_PIPE_NOTIFY_TIMEOUT); + } + + return 0; +} + +static struct modem_pipe_api modem_backend_fake_api = { + .open = modem_backend_fake_open, + .transmit = modem_backend_fake_transmit, + .receive = modem_backend_fake_receive, + .close = modem_backend_fake_close, +}; + +static struct modem_pipe *modem_backend_fake_init(struct modem_backend_fake *backend) +{ + k_work_init_delayable(&backend->opened_dwork, + modem_backend_fake_opened_handler); + k_work_init_delayable(&backend->transmit_idle_dwork, + modem_backend_fake_transmit_idle_handler); + k_work_init_delayable(&backend->closed_dwork, + modem_backend_fake_closed_handler); + + modem_pipe_init(&backend->pipe, backend, &modem_backend_fake_api); + return &backend->pipe; +} + +static void modem_backend_fake_reset(struct modem_backend_fake *backend) +{ + backend->transmit_buffer = NULL; + backend->transmit_buffer_size = 0; + backend->receive_buffer = NULL; + backend->transmit_buffer_size = 0; + backend->open_called = false; + backend->transmit_called = false; + backend->receive_called = false; + backend->close_called = false; +} + +static void modem_backend_fake_set_sync(struct modem_backend_fake *backend, bool sync) +{ + backend->synchronous = sync; +} + +/*************************************************************************************************/ +/* Instances */ +/*************************************************************************************************/ +static struct modem_backend_fake test_backend; +static struct modem_pipe *test_pipe; +static uint32_t test_user_data; +static atomic_t test_state; +static uint8_t test_buffer[4]; +static size_t test_buffer_size = sizeof(test_buffer); + +/*************************************************************************************************/ +/* Callbacks */ +/*************************************************************************************************/ +static void modem_pipe_fake_handler(struct modem_pipe *pipe, enum modem_pipe_event event, + void *user_data) +{ + __ASSERT(pipe == test_pipe, "Incorrect pipe provided with callback"); + __ASSERT(user_data == (void *)&test_user_data, "Incorrect user data ptr"); + + switch (event) { + case MODEM_PIPE_EVENT_OPENED: + atomic_set_bit(&test_state, TEST_MODEM_PIPE_EVENT_OPENED_BIT); + break; + + case MODEM_PIPE_EVENT_RECEIVE_READY: + atomic_set_bit(&test_state, TEST_MODEM_PIPE_EVENT_RECEIVE_READY_BIT); + break; + + case MODEM_PIPE_EVENT_TRANSMIT_IDLE: + atomic_set_bit(&test_state, TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT); + break; + + case MODEM_PIPE_EVENT_CLOSED: + atomic_set_bit(&test_state, TEST_MODEM_PIPE_EVENT_CLOSED_BIT); + break; + } +} + +static void test_reset(void) +{ + modem_backend_fake_reset(&test_backend); + atomic_set(&test_state, 0); +} + +static void *modem_backend_fake_setup(void) +{ + test_pipe = modem_backend_fake_init(&test_backend); + return NULL; +} + +static void modem_backend_fake_before(void *f) +{ + modem_backend_fake_set_sync(&test_backend, false); + modem_pipe_attach(test_pipe, modem_pipe_fake_handler, &test_user_data); + test_reset(); +} + +static void modem_backend_fake_after(void *f) +{ + __ASSERT(modem_pipe_close(test_pipe) == 0, "Failed to close pipe"); + modem_pipe_release(test_pipe); +} + +/* Opening pipe shall raise events OPENED and TRANSMIT_IDLE */ +static void test_pipe_open(void) +{ + zassert_ok(modem_pipe_open(test_pipe), "Failed to open pipe"); + zassert_true(test_backend.open_called, "open was not called"); + zassert_equal(atomic_get(&test_state), + BIT(TEST_MODEM_PIPE_EVENT_OPENED_BIT) | + BIT(TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +/* Re-opening pipe shall have no effect */ +static void test_pipe_reopen(void) +{ + zassert_ok(modem_pipe_open(test_pipe), "Failed to re-open pipe"); + zassert_false(test_backend.open_called, "open was called"); + zassert_equal(atomic_get(&test_state), 0, + "Unexpected state %u", atomic_get(&test_state)); +} + +/* Closing pipe shall raise event CLOSED */ +static void test_pipe_close(void) +{ + zassert_ok(modem_pipe_close(test_pipe), "Failed to close pipe"); + zassert_true(test_backend.close_called, "close was not called"); + zassert_equal(atomic_get(&test_state), BIT(TEST_MODEM_PIPE_EVENT_CLOSED_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +/* Re-closing pipe shall have no effect */ +static void test_pipe_reclose(void) +{ + zassert_ok(modem_pipe_close(test_pipe), "Failed to re-close pipe"); + zassert_false(test_backend.close_called, "close was called"); + zassert_equal(atomic_get(&test_state), 0, + "Unexpected state %u", atomic_get(&test_state)); +} + +static void test_pipe_async_transmit(void) +{ + zassert_equal(modem_pipe_transmit(test_pipe, test_buffer, test_buffer_size), + test_buffer_size, "Failed to transmit"); + zassert_true(test_backend.transmit_called, "transmit was not called"); + zassert_equal(test_backend.transmit_buffer, test_buffer, "Incorrect buffer"); + zassert_equal(test_backend.transmit_buffer_size, test_buffer_size, + "Incorrect buffer size"); + zassert_equal(atomic_get(&test_state), 0, "Unexpected state %u", + atomic_get(&test_state)); + k_sleep(TEST_MODEM_PIPE_WAIT_TIMEOUT); + zassert_equal(atomic_get(&test_state), BIT(TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +static void test_pipe_sync_transmit(void) +{ + zassert_equal(modem_pipe_transmit(test_pipe, test_buffer, test_buffer_size), + test_buffer_size, "Failed to transmit"); + zassert_true(test_backend.transmit_called, "transmit was not called"); + zassert_equal(test_backend.transmit_buffer, test_buffer, "Incorrect buffer"); + zassert_equal(test_backend.transmit_buffer_size, test_buffer_size, + "Incorrect buffer size"); + zassert_equal(atomic_get(&test_state), BIT(TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +static void test_pipe_attach_receive_not_ready_transmit_idle(void) +{ + modem_pipe_attach(test_pipe, modem_pipe_fake_handler, &test_user_data); + zassert_equal(atomic_get(&test_state), BIT(TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +static void test_pipe_attach_receive_ready_transmit_idle(void) +{ + modem_pipe_attach(test_pipe, modem_pipe_fake_handler, &test_user_data); + zassert_equal(atomic_get(&test_state), + BIT(TEST_MODEM_PIPE_EVENT_TRANSMIT_IDLE_BIT) | + BIT(TEST_MODEM_PIPE_EVENT_RECEIVE_READY_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +static void test_pipe_receive(void) +{ + zassert_equal(modem_pipe_receive(test_pipe, test_buffer, test_buffer_size), + test_buffer_size, "Failed to receive"); + zassert_true(test_backend.receive_called, "receive was not called"); + zassert_equal(test_backend.receive_buffer, test_buffer, "Incorrect buffer"); + zassert_equal(test_backend.receive_buffer_size, test_buffer_size, + "Incorrect buffer size"); + zassert_equal(atomic_get(&test_state), 0, "Unexpected state %u", + atomic_get(&test_state)); +} + +static void test_pipe_notify_receive_ready(void) +{ + modem_pipe_notify_receive_ready(test_pipe); + zassert_equal(atomic_get(&test_state), BIT(TEST_MODEM_PIPE_EVENT_RECEIVE_READY_BIT), + "Unexpected state %u", atomic_get(&test_state)); +} + +ZTEST(modem_pipe, test_async_open_close) +{ + test_pipe_open(); + test_reset(); + test_pipe_reopen(); + test_reset(); + test_pipe_close(); + test_reset(); + test_pipe_reclose(); +} + +ZTEST(modem_pipe, test_sync_open_close) +{ + modem_backend_fake_set_sync(&test_backend, true); + test_pipe_open(); + test_reset(); + test_pipe_reopen(); + test_reset(); + test_pipe_close(); + test_reset(); + test_pipe_reclose(); +} + +ZTEST(modem_pipe, test_async_transmit) +{ + test_pipe_open(); + test_reset(); + test_pipe_async_transmit(); +} + +ZTEST(modem_pipe, test_sync_transmit) +{ + modem_backend_fake_set_sync(&test_backend, true); + test_pipe_open(); + test_reset(); + test_pipe_sync_transmit(); +} + +ZTEST(modem_pipe, test_attach) +{ + test_pipe_open(); + + /* + * Attaching pipe shall reinvoke TRANSMIT IDLE, but not RECEIVE READY as + * receive is not ready. + */ + test_reset(); + test_pipe_attach_receive_not_ready_transmit_idle(); + + /* + * Notify receive ready and expect receive ready to be re-invoked every + * time the pipe is attached to. + */ + test_reset(); + test_pipe_notify_receive_ready(); + test_reset(); + test_pipe_attach_receive_ready_transmit_idle(); + test_reset(); + test_pipe_attach_receive_ready_transmit_idle(); + + /* + * Receiving data from the pipe shall clear the receive ready state, stopping + * the invocation of receive ready on attach. + */ + test_reset(); + test_pipe_receive(); + test_reset(); + test_pipe_attach_receive_not_ready_transmit_idle(); +} + +ZTEST_SUITE(modem_pipe, NULL, modem_backend_fake_setup, modem_backend_fake_before, + modem_backend_fake_after, NULL); diff --git a/tests/subsys/modem/modem_pipe/testcase.yaml b/tests/subsys/modem/modem_pipe/testcase.yaml new file mode 100644 index 00000000000..39a8c8e6c2c --- /dev/null +++ b/tests/subsys/modem/modem_pipe/testcase.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Trackunit Corporation +# SPDX-License-Identifier: Apache-2.0 + +tests: + modem.modem_pipe: + tags: modem_pipe + harness: ztest + platform_allow: native_sim diff --git a/tests/subsys/modem/modem_ppp/testcase.yaml b/tests/subsys/modem/modem_ppp/testcase.yaml index 0b3fef701f3..7e0937ea144 100644 --- a/tests/subsys/modem/modem_ppp/testcase.yaml +++ b/tests/subsys/modem/modem_ppp/testcase.yaml @@ -5,4 +5,8 @@ tests: modem.modem_ppp: tags: modem_ppp harness: ztest - platform_allow: native_posix + platform_allow: + - native_posix + - native_sim + integration_platforms: + - native_sim diff --git a/version.h.in b/version.h.in index c60fb721804..bfb2eb3edb7 100644 --- a/version.h.in +++ b/version.h.in @@ -9,12 +9,15 @@ #cmakedefine ZEPHYR_VERSION_CODE @ZEPHYR_VERSION_CODE@ #cmakedefine ZEPHYR_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) -#define @VERSION_TYPE@VERSION @@VERSION_TYPE@VERSION@ -#define @VERSION_TYPE@_VERSION_NUMBER @@VERSION_TYPE@_VERSION_NUMBER@ -#define @VERSION_TYPE@_VERSION_MAJOR @@VERSION_TYPE@_VERSION_MAJOR@ -#define @VERSION_TYPE@_VERSION_MINOR @@VERSION_TYPE@_VERSION_MINOR@ -#define @VERSION_TYPE@_PATCHLEVEL @@VERSION_TYPE@_PATCHLEVEL@ -#define @VERSION_TYPE@_VERSION_STRING "@@VERSION_TYPE@_VERSION_STRING@" +#define @VERSION_TYPE@VERSION @@VERSION_TYPE@VERSION@ +#define @VERSION_TYPE@_VERSION_NUMBER @@VERSION_TYPE@_VERSION_NUMBER@ +#define @VERSION_TYPE@_VERSION_MAJOR @@VERSION_TYPE@_VERSION_MAJOR@ +#define @VERSION_TYPE@_VERSION_MINOR @@VERSION_TYPE@_VERSION_MINOR@ +#define @VERSION_TYPE@_PATCHLEVEL @@VERSION_TYPE@_PATCHLEVEL@ +#define @VERSION_TYPE@_TWEAK @@VERSION_TYPE@_VERSION_TWEAK@ +#define @VERSION_TYPE@_VERSION_STRING "@@VERSION_TYPE@_VERSION_STRING@" +#define @VERSION_TYPE@_VERSION_EXTENDED_STRING "@@VERSION_TYPE@_VERSION_EXTENDED_STRING@" +#define @VERSION_TYPE@_VERSION_TWEAK_STRING "@@VERSION_TYPE@_VERSION_TWEAK_STRING@" #define @BUILD_VERSION_NAME@ @@BUILD_VERSION_NAME@@ @@VERSION_TYPE@_VERSION_CUSTOMIZATION@ diff --git a/west.yml b/west.yml index 14847109194..46e2085d756 100644 --- a/west.yml +++ b/west.yml @@ -40,77 +40,77 @@ manifest: - babblesim - name: babblesim_base remote: babblesim - repo-path: base.git + repo-path: base path: tools/bsim/components revision: 19d62424c0802c6c9fc15528febe666e40f372a1 groups: - babblesim - name: babblesim_ext_2G4_libPhyComv1 remote: babblesim - repo-path: ext_2G4_libPhyComv1.git + repo-path: ext_2G4_libPhyComv1 path: tools/bsim/components/ext_2G4_libPhyComv1 revision: 9018113a362fa6c9e8f4b9cab9e5a8f12cc46b94 groups: - babblesim - name: babblesim_ext_2G4_phy_v1 remote: babblesim - repo-path: ext_2G4_phy_v1.git + repo-path: ext_2G4_phy_v1 path: tools/bsim/components/ext_2G4_phy_v1 revision: d47c6dd90035b41b14f6921785ccb7b8484868e2 groups: - babblesim - name: babblesim_ext_2G4_channel_NtNcable remote: babblesim - repo-path: ext_2G4_channel_NtNcable.git + repo-path: ext_2G4_channel_NtNcable path: tools/bsim/components/ext_2G4_channel_NtNcable revision: 20a38c997f507b0aa53817aab3d73a462fff7af1 groups: - babblesim - name: babblesim_ext_2G4_channel_multiatt remote: babblesim - repo-path: ext_2G4_channel_multiatt.git + repo-path: ext_2G4_channel_multiatt path: tools/bsim/components/ext_2G4_channel_multiatt revision: bde72a57384dde7a4310bcf3843469401be93074 groups: - babblesim - name: babblesim_ext_2G4_modem_magic remote: babblesim - repo-path: ext_2G4_modem_magic.git + repo-path: ext_2G4_modem_magic path: tools/bsim/components/ext_2G4_modem_magic revision: cb70771794f0bf6f262aa474848611c68ae8f1ed groups: - babblesim - name: babblesim_ext_2G4_modem_BLE_simple remote: babblesim - repo-path: ext_2G4_modem_BLE_simple.git + repo-path: ext_2G4_modem_BLE_simple path: tools/bsim/components/ext_2G4_modem_BLE_simple revision: 809ab073159c9ab6686c2fea5749b0702e0909f7 groups: - babblesim - name: babblesim_ext_2G4_device_burst_interferer remote: babblesim - repo-path: ext_2G4_device_burst_interferer.git + repo-path: ext_2G4_device_burst_interferer path: tools/bsim/components/ext_2G4_device_burst_interferer revision: 5b5339351d6e6a2368c686c734dc8b2fc65698fc groups: - babblesim - name: babblesim_ext_2G4_device_WLAN_actmod remote: babblesim - repo-path: ext_2G4_device_WLAN_actmod.git + repo-path: ext_2G4_device_WLAN_actmod path: tools/bsim/components/ext_2G4_device_WLAN_actmod revision: 9cb6d8e72695f6b785e57443f0629a18069d6ce4 groups: - babblesim - name: babblesim_ext_2G4_device_playback remote: babblesim - repo-path: ext_2G4_device_playback.git + repo-path: ext_2G4_device_playback path: tools/bsim/components/ext_2G4_device_playback revision: 85c645929cf1ce995d8537107d9dcbd12ed64036 groups: - babblesim - name: babblesim_ext_libCryptov1 remote: babblesim - repo-path: ext_libCryptov1.git + repo-path: ext_libCryptov1 path: tools/bsim/components/ext_libCryptov1 revision: eed6d7038e839153e340bd333bc43541cb90ba64 groups: @@ -183,7 +183,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 56e0b052dff311c2f8eb08c6804e60fc79feb56f + revision: dce8519f7da37b0a745237679fd3f88250b495ff path: modules/hal/nordic groups: - hal @@ -193,7 +193,7 @@ manifest: groups: - hal - name: hal_nxp - revision: 69046233b7a7fac3138ae4dd5bcf6158e82529bb + revision: 0463d6aa0de62761fb9ae56e3521c61b0e490374 path: modules/hal/nxp groups: - hal @@ -277,12 +277,12 @@ manifest: revision: 7c61a4cec26402d20c845c95dcad0e39dcd319f8 path: modules/lib/gui/lvgl - name: mbedtls - revision: 7053083b0cff8462464e3cbb826e87852fc03da6 + revision: 66ed2279d6222056af172c188eaf4dcfed481032 path: modules/crypto/mbedtls groups: - crypto - name: mcuboot - revision: 0c0470e294dcfb52aab92299356a5f3caa0aa52b + revision: f09e205b1e4a8d2bc3f50dffa7960d6ccd14df59 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t @@ -295,13 +295,13 @@ manifest: groups: - tools - name: nrf_hw_models - revision: a715dcc179f1a71f51c574165958b72fe932ae3f + revision: 52d0b4b7b7431d8da6222cc3b17a8afdcb099baf path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: 214f9fc1539f8e5937c0474cb6ee29b6dcb2d4b8 path: modules/lib/open-amp - name: openthread - revision: 193e77e40ec2387d458eaebd1e03902d86f484a5 + revision: 7761b81d23b10b3d5ee21b8504c67535cde10896 path: modules/lib/openthread - name: percepio path: modules/debug/percepio @@ -322,7 +322,7 @@ manifest: groups: - crypto - name: trusted-firmware-m - revision: 33c0f47bcb19721a5c33e6fe1eee9225d00bb5bc + revision: 58d0b5367f0fada9dbaddad1e08e302aeb044863 path: modules/tee/tf-m/trusted-firmware-m groups: - tee @@ -332,10 +332,10 @@ manifest: groups: - tee - name: uoscore-uedhoc - revision: 5fe2cb613bd7e4590bd1b00c2adf181ac0229379 + revision: 150f4eb2955eaf36ac0f9519d4f4f58d5ade5740 path: modules/lib/uoscore-uedhoc - name: zcbor - revision: 67fd8bb88d3136738661fa8bb5f9989103f4599e + revision: d3093b5684f62268c7f27f8a5079f166772619de path: modules/lib/zcbor self: