From 89432131af6a3b3169bfcd1d4960c5a07f4df180 Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Tue, 24 Jun 2025 16:43:22 +0200 Subject: [PATCH 1/2] arch: split dynamic interrupt symbol This commit introduces the SRAM_SW_ISR_TABLE option which is selected by DYNAMIC_INTERRUPT. It allows splitting the DYNAMIC_INTERRUPT option into two parts: - One for the relocation of the ISR vector table in RAM - One for the inclusion of functions needed to install ISRs dynamically The goal is to later only select the relocation of the ISR vector table in RAM and not all the associated functions from the dynamic interrupt mechanism. Signed-off-by: Martin Hoff --- arch/Kconfig | 7 +++++++ arch/arm/core/CMakeLists.txt | 2 +- arch/arm64/core/CMakeLists.txt | 2 +- cmake/linker_script/common/common-ram.cmake | 2 +- cmake/linker_script/common/common-rom.cmake | 2 +- doc/releases/migration-guide-4.3.rst | 3 +++ doc/releases/release-notes-4.3.rst | 4 ++++ include/zephyr/linker/common-ram.ld | 2 +- .../zephyr/linker/common-rom/common-rom-kernel-devices.ld | 2 +- 9 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index d059e2a2a221..859e9a4c3b04 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -472,6 +472,7 @@ config ISR_TABLES_LOCAL_DECLARATION config DYNAMIC_INTERRUPTS bool "Installation of IRQs at runtime" + select SRAM_SW_ISR_TABLE help Enable installation of interrupts at runtime, which will move some interrupt-related data structures to RAM instead of ROM, and @@ -598,6 +599,12 @@ config SRAM_VECTOR_TABLE When XiP is enabled, this option will result in the vector table being relocated from Flash to SRAM. +config SRAM_SW_ISR_TABLE + bool "Place the software ISR table in SRAM instead of flash" + help + The option specifies that the software interrupts vector table will be + placed inside SRAM instead of the flash. + config IRQ_OFFLOAD_NESTED bool "irq_offload() supports nested IRQs" depends on IRQ_OFFLOAD diff --git a/arch/arm/core/CMakeLists.txt b/arch/arm/core/CMakeLists.txt index 922dab2ddba5..ccfa5b6c777c 100644 --- a/arch/arm/core/CMakeLists.txt +++ b/arch/arm/core/CMakeLists.txt @@ -37,7 +37,7 @@ 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) + if(CONFIG_SRAM_SW_ISR_TABLE) zephyr_linker_sources(RWDATA swi_tables.ld) else() zephyr_linker_sources(RODATA swi_tables.ld) diff --git a/arch/arm64/core/CMakeLists.txt b/arch/arm64/core/CMakeLists.txt index 9112e55f302e..1c1070416327 100644 --- a/arch/arm64/core/CMakeLists.txt +++ b/arch/arm64/core/CMakeLists.txt @@ -60,7 +60,7 @@ endif() add_subdirectory_ifdef(CONFIG_XEN xen) if(CONFIG_GEN_SW_ISR_TABLE) - if(CONFIG_DYNAMIC_INTERRUPTS) + if(CONFIG_SRAM_SW_ISR_TABLE) zephyr_linker_sources(RWDATA swi_tables.ld) else() zephyr_linker_sources(RODATA swi_tables.ld) diff --git a/cmake/linker_script/common/common-ram.cmake b/cmake/linker_script/common/common-ram.cmake index 23fae8c69484..210ab4be1af1 100644 --- a/cmake/linker_script/common/common-ram.cmake +++ b/cmake/linker_script/common/common-ram.cmake @@ -2,7 +2,7 @@ # The contents of this file is based on include/zephyr/linker/common-ram.ld # Please keep in sync -if(CONFIG_GEN_SW_ISR_TABLE AND CONFIG_DYNAMIC_INTERRUPTS) +if(CONFIG_GEN_SW_ISR_TABLE AND CONFIG_SRAM_SW_ISR_TABLE) # ld align has been changed to subalign to provide identical behavior scatter vs. ld. zephyr_linker_section(NAME sw_isr_table GROUP DATA_REGION diff --git a/cmake/linker_script/common/common-rom.cmake b/cmake/linker_script/common/common-rom.cmake index c56ccd3670be..bdd76b8e97ff 100644 --- a/cmake/linker_script/common/common-rom.cmake +++ b/cmake/linker_script/common/common-rom.cmake @@ -14,7 +14,7 @@ zephyr_linker_section_obj_level(SECTION init LEVEL SMP) zephyr_iterable_section(NAME device NUMERIC KVMA RAM_REGION GROUP RODATA_REGION) zephyr_iterable_section(NAME service NUMERIC KVMA RAM_REGION GROUP RODATA_REGION) -if(CONFIG_GEN_SW_ISR_TABLE AND NOT CONFIG_DYNAMIC_INTERRUPTS) +if(CONFIG_GEN_SW_ISR_TABLE AND NOT CONFIG_SRAM_SW_ISR_TABLE) # ld align has been changed to subalign to provide identical behavior scatter vs. ld. zephyr_linker_section(NAME sw_isr_table KVMA FLASH GROUP RODATA_REGION SUBALIGN ${CONFIG_ARCH_SW_ISR_TABLE_ALIGN} NOINPUT) zephyr_linker_section_configure( diff --git a/doc/releases/migration-guide-4.3.rst b/doc/releases/migration-guide-4.3.rst index f668d9ef6f56..34071417b65e 100644 --- a/doc/releases/migration-guide-4.3.rst +++ b/doc/releases/migration-guide-4.3.rst @@ -46,3 +46,6 @@ Modules Architectures ************* + +* The :kconfig:option:`CONFIG_DYNAMIC_INTERRUPTS` option has a new dependency on + :kconfig:option:`CONFIG_SRAM_SW_ISR_TABLE`. diff --git a/doc/releases/release-notes-4.3.rst b/doc/releases/release-notes-4.3.rst index 71aea3a12018..efd50244cf1e 100644 --- a/doc/releases/release-notes-4.3.rst +++ b/doc/releases/release-notes-4.3.rst @@ -63,6 +63,10 @@ New APIs and options like you need to add more details, add them in the API documentation code instead. +* Architectures + + * :kconfig:option:`CONFIG_SRAM_SW_ISR_TABLE` + New Boards ********** diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index 78016f9572f4..792574c9d37a 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -17,7 +17,7 @@ ITERABLE_SECTION_RAM(scmi_protocol, Z_LINK_ITERABLE_SUBALIGN) #endif /* CONFIG_ARM_SCMI */ -#if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_DYNAMIC_INTERRUPTS) +#if defined(CONFIG_GEN_SW_ISR_TABLE) && defined(CONFIG_SRAM_SW_ISR_TABLE) SECTION_DATA_PROLOGUE(sw_isr_table,,) { /* diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 2bb7d2c509ce..2cad86b76df4 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -44,7 +44,7 @@ } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) #endif -#if defined(CONFIG_GEN_SW_ISR_TABLE) && !defined(CONFIG_DYNAMIC_INTERRUPTS) +#if defined(CONFIG_GEN_SW_ISR_TABLE) && !defined(CONFIG_SRAM_SW_ISR_TABLE) SECTION_PROLOGUE(sw_isr_table,,) { /* From 2799d8f8f7f2b27239f7e42fd03e5e7bacaf0329 Mon Sep 17 00:00:00 2001 From: Martin Hoff Date: Thu, 26 Jun 2025 14:28:44 +0200 Subject: [PATCH 2/2] tests: application_development: add new test for ram-based isr This commit introduces the new test ram_context_for_isr that shows how to configure an application (prj.conf, CMakeLists.txt, etc.) in order to enable full ISR execution with a RAM context. It resolves the issue of flash latency affecting real-time constraints during ISR execution. Signed-off-by: Martin Hoff --- .../ram_context_for_isr/CMakeLists.txt | 24 +++++ .../ram_context_for_isr/README.rst | 94 +++++++++++++++++++ .../ram_context_for_isr/app.overlay | 17 ++++ .../dts/bindings/fakedriver.yml | 8 ++ .../ram_context_for_isr/include/fake_driver.h | 37 ++++++++ .../ram_context_for_isr/prj.conf | 6 ++ .../ram_context_for_isr/sections-rom.ld | 10 ++ .../ram_context_for_isr/src/fake_driver.c | 82 ++++++++++++++++ .../ram_context_for_isr/src/main.c | 82 ++++++++++++++++ .../ram_context_for_isr/testcase.yaml | 19 ++++ 10 files changed, 379 insertions(+) create mode 100644 tests/application_development/ram_context_for_isr/CMakeLists.txt create mode 100644 tests/application_development/ram_context_for_isr/README.rst create mode 100644 tests/application_development/ram_context_for_isr/app.overlay create mode 100644 tests/application_development/ram_context_for_isr/dts/bindings/fakedriver.yml create mode 100644 tests/application_development/ram_context_for_isr/include/fake_driver.h create mode 100644 tests/application_development/ram_context_for_isr/prj.conf create mode 100644 tests/application_development/ram_context_for_isr/sections-rom.ld create mode 100644 tests/application_development/ram_context_for_isr/src/fake_driver.c create mode 100644 tests/application_development/ram_context_for_isr/src/main.c create mode 100644 tests/application_development/ram_context_for_isr/testcase.yaml diff --git a/tests/application_development/ram_context_for_isr/CMakeLists.txt b/tests/application_development/ram_context_for_isr/CMakeLists.txt new file mode 100644 index 000000000000..abbe49f04513 --- /dev/null +++ b/tests/application_development/ram_context_for_isr/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (c) 2025 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(ram_context_for_isr) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) + +zephyr_include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +if(CONFIG_CPU_CORTEX_M_HAS_VTOR) + zephyr_code_relocate(FILES ${ZEPHYR_BASE}/arch/arm/core/cortex_m/isr_wrapper.c LOCATION RAM) + zephyr_code_relocate(FILES ${ZEPHYR_BASE}/arch/arm/core/cortex_m/exc_exit.c LOCATION RAM) +endif() + +zephyr_code_relocate(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c FILTER ".test_irq_callback" LOCATION RAM ) +zephyr_code_relocate(FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/fake_driver.c FILTER ".fake_driver_isr" LOCATION RAM ) + +# Only needed because the fake driver is defined in tests folder +zephyr_linker_sources(SECTIONS sections-rom.ld) diff --git a/tests/application_development/ram_context_for_isr/README.rst b/tests/application_development/ram_context_for_isr/README.rst new file mode 100644 index 000000000000..c8dc83d7d379 --- /dev/null +++ b/tests/application_development/ram_context_for_isr/README.rst @@ -0,0 +1,94 @@ +.. _vector_table_relocation: + +RAM Context for ISR +################### + +Overview +******** +A test that verifies the ISR vector table relocation and +full IRQ execution under RAM context. + + +Test Description +**************** + +This test verifies that interrupt service routines (ISRs), their callbacks, and the driver code +can be fully relocated to RAM, ensuring that all interrupt handling occurs from SRAM rather than +flash. This is important for real-time applications where minimizing interrupt latency is critical. + +The test uses a simple "fake driver" that registers an IRQ callback. The following aspects are +validated: + +- The vector table and ISR wrapper are relocated to SRAM. +- The fake driver's ISR and the registered callback are also located in SRAM. +- When the interrupt is triggered, the callback and all relevant code execute from RAM, not flash. +- The test asserts at runtime that the addresses of the callback, driver ISR, and ISR wrapper are + within the SRAM address range. + +Test Steps +********** + +1. The test registers a callback with the fake driver. +2. It triggers the interrupt (IRQ 27). +3. The callback checks (using assertions) that: + - Its own address, + - The driver's ISR address, + - The ISR wrapper address, + - And the device structure, + are all within the SRAM region. +4. The test passes if all assertions succeed and the callback is executed. + +Configuration +************* + +The test is configured with the following options in prj.conf: + +- ``CONFIG_SRAM_VECTOR_TABLE=y``: Relocate the vector table to SRAM. +- ``CONFIG_SRAM_SW_ISR_TABLE=y``: Relocate the software ISR table to SRAM. +- ``CONFIG_CODE_DATA_RELOCATION=y``: Enable code/data relocation to SRAM. +- ``CONFIG_DEVICE_MUTABLE=y``: Allow device structures to be mutable (in RAM). +- ``CONFIG_ZTEST=y``: Enable Zephyr's test framework. + +The test is only supported on ARM Cortex-M platforms with VTOR (Vector Table Offset Register) support. + +Advanced Configuration and Limitations +************************************** + +Configuration Options in testcase.yaml +====================================== + +By default, the test disables several options in testcase.yaml: + +- ``CONFIG_TRACING_ISR=n``: Disables ISR tracing. + **If enabled:** Enabling ISR tracing adds hooks to trace ISR entry/exit, which may introduce + additional code paths not relocated to RAM. This can increase interrupt latency and may cause + some tracing code to execute from flash, partially defeating the purpose of full RAM relocation. + +- ``CONFIG_STACK_SENTINEL=n``: Disables stack overflow detection sentinels. + **If enabled:** Enabling stack sentinels adds extra checks to detect stack overflows. These + checks may reside in flash and be called during interrupt handling, potentially increasing + latency and causing some code to execute from flash. + +- ``CONFIG_PM=n``: Disables power management. + **If enabled:** Enabling power management may cause the system to enter low-power states. Some + wake-up interrupts may not use the relocated vector table in RAM, and the system may revert to + using the flash-based vector table to exit idle states. This can result in some ISRs or their + wrappers executing from flash, especially during wake-up from deep sleep. + +**Summary:** +If you enable any of these options, ensure all code paths executed during interrupt handling are +also relocated to RAM to maintain the lowest possible interrupt latency. Otherwise, some code may +still execute from flash, increasing latency and partially defeating the test's purpose. + +Driver API Location and Limitations +=================================== + +**Important Note:** +While the test ensures ISR, callback, and device structures are relocated to RAM, the driver API +structure (``struct fake_driver_api``)—containing function pointers for driver methods—is not +relocated to RAM by default. This structure typically resides in flash (ROM) as device constant data. + +As long as you don't call the driver API during ISR execution, the current configuration is sufficient. +However, if you need to call driver API functions from within an ISR, you must relocate the driver API +structure to RAM. The simplest approach is to relocate the entire driver file to RAM rather than just +the ISR symbol. diff --git a/tests/application_development/ram_context_for_isr/app.overlay b/tests/application_development/ram_context_for_isr/app.overlay new file mode 100644 index 000000000000..15899c033044 --- /dev/null +++ b/tests/application_development/ram_context_for_isr/app.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + #address-cells = <1>; + #size-cells = <1>; + + fakedriver: fakedriver@E0000000 { + compatible = "fakedriver"; + reg = <0xE0000000 0x2000>; + zephyr,mutable; + status = "okay"; + }; +}; diff --git a/tests/application_development/ram_context_for_isr/dts/bindings/fakedriver.yml b/tests/application_development/ram_context_for_isr/dts/bindings/fakedriver.yml new file mode 100644 index 000000000000..80821fcbc4fa --- /dev/null +++ b/tests/application_development/ram_context_for_isr/dts/bindings/fakedriver.yml @@ -0,0 +1,8 @@ +# Copyright (c) 2025 Silicon Laboratories +# SPDX-License-Identifier: Apache-2.0 + +description: Properties for fake driver. + +compatible: "fakedriver" + +include: [base.yaml, mutable.yaml] diff --git a/tests/application_development/ram_context_for_isr/include/fake_driver.h b/tests/application_development/ram_context_for_isr/include/fake_driver.h new file mode 100644 index 000000000000..198f0123976a --- /dev/null +++ b/tests/application_development/ram_context_for_isr/include/fake_driver.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_FAKE_DRIVER_H_ +#define ZEPHYR_INCLUDE_DRIVERS_FAKE_DRIVER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*fake_driver_irq_callback_t)(const struct device *dev, void *user_data); + +struct fake_driver_config { + void (*irq_config_func)(void); + uint8_t irq_num; + uint8_t irq_priority; +}; + +struct fake_driver_data { + fake_driver_irq_callback_t irq_callback; + void *user_data; +}; + +__subsystem struct fake_driver_api { + int (*configure)(const struct device *dev, int config); + int (*register_irq_callback)(const struct device *dev, fake_driver_irq_callback_t cb, + void *user_data); +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_FAKE_DRIVER_H_ */ diff --git a/tests/application_development/ram_context_for_isr/prj.conf b/tests/application_development/ram_context_for_isr/prj.conf new file mode 100644 index 000000000000..a6e8cd2353db --- /dev/null +++ b/tests/application_development/ram_context_for_isr/prj.conf @@ -0,0 +1,6 @@ +CONFIG_COVERAGE=n +CONFIG_ZTEST=y +CONFIG_SRAM_VECTOR_TABLE=y +CONFIG_SRAM_SW_ISR_TABLE=y +CONFIG_CODE_DATA_RELOCATION=y +CONFIG_DEVICE_MUTABLE=y diff --git a/tests/application_development/ram_context_for_isr/sections-rom.ld b/tests/application_development/ram_context_for_isr/sections-rom.ld new file mode 100644 index 000000000000..eb4193b3433b --- /dev/null +++ b/tests/application_development/ram_context_for_isr/sections-rom.ld @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/* Only needed because the driver is defined in tests folder */ +ITERABLE_SECTION_ROM(fake_driver_api, Z_LINK_ITERABLE_SUBALIGN) diff --git a/tests/application_development/ram_context_for_isr/src/fake_driver.c b/tests/application_development/ram_context_for_isr/src/fake_driver.c new file mode 100644 index 000000000000..0c2ff0ce160f --- /dev/null +++ b/tests/application_development/ram_context_for_isr/src/fake_driver.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "fake_driver.h" + +#define DT_DRV_COMPAT fakedriver + +#define TEST_IRQ_NUM 27 +#define TEST_IRQ_PRIO 4 + +static void fake_driver_isr(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct fake_driver_data *data = dev->data; + + /* Store the address of fake_driver_isr in user_data because it will be optimized by the + * compiler (even with __noinline__ attribute) + */ + data->user_data = (void *)&fake_driver_isr; + + if (data->irq_callback != NULL) { + data->irq_callback(dev, data->user_data); + } +} + +static int fake_driver_configure(const struct device *dev, int config) +{ + return 0; +} + +static int fake_driver_register_irq_callback(const struct device *dev, + fake_driver_irq_callback_t cb, void *user_data) +{ + struct fake_driver_data *data = dev->data; + + data->irq_callback = cb; + data->user_data = user_data; + + return 0; +} + +DEVICE_API(fake, fake_driver_func) = { + .configure = fake_driver_configure, + .register_irq_callback = fake_driver_register_irq_callback, +}; + +static int fake_driver_init(const struct device *dev) +{ + const struct fake_driver_config *config = dev->config; + struct fake_driver_data *data = dev->data; + + data->irq_callback = NULL; + data->user_data = NULL; + + config->irq_config_func(); + + return 0; +} + +#define FAKE_INIT(inst) \ + static struct fake_driver_data fake_driver_data_##inst; \ + static void fake_driver_irq_config_func_##inst(void) \ + { \ + IRQ_CONNECT(TEST_IRQ_NUM, TEST_IRQ_PRIO, fake_driver_isr, \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(TEST_IRQ_NUM); \ + } \ + static struct fake_driver_config fake_driver_config_##inst = { \ + .irq_config_func = fake_driver_irq_config_func_##inst, \ + .irq_num = TEST_IRQ_NUM, \ + .irq_priority = TEST_IRQ_PRIO, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &fake_driver_init, NULL, &fake_driver_data_##inst, \ + &fake_driver_config_##inst, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &fake_driver_func); + +DT_INST_FOREACH_STATUS_OKAY(FAKE_INIT) diff --git a/tests/application_development/ram_context_for_isr/src/main.c b/tests/application_development/ram_context_for_isr/src/main.c new file mode 100644 index 000000000000..a38f3a39370b --- /dev/null +++ b/tests/application_development/ram_context_for_isr/src/main.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Test for driver relocation to RAM for ISRs + * + * This test demonstrates how to use the fake_driver and verify + * that the callback are properly relocated to RAM. + */ + +#if !defined(CONFIG_CPU_CORTEX_M) +#error project can only run on Cortex-M for now +#endif + +#include +#include "fake_driver.h" + +static volatile bool test_flag; + +static void test_irq_callback(const struct device *dev, void *user_data) +{ + uintptr_t func_addr = (uintptr_t)test_irq_callback; + uintptr_t driver_isr_addr, arch_isr_wrapper_addr; + + test_flag = true; + + /* Retrieve the caller address (the arch specific isr wrapper since driver isr will be + * optimized by the compiler) + */ + __asm__ volatile("mov %0, lr" : "=r"(arch_isr_wrapper_addr)); + + /* retrieve the fake_driver_isr function address that was stored in user_data */ + driver_isr_addr = (uintptr_t)user_data; + + /* Check that the function and its call stack are in RAM */ + zassert_true(func_addr >= CONFIG_SRAM_BASE_ADDRESS && + func_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024, + "%s is not in RAM! Address: 0x%x", __func__, func_addr); + + zassert_true(driver_isr_addr >= CONFIG_SRAM_BASE_ADDRESS && + driver_isr_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024, + "fake_driver_isr is not in RAM! Address: 0x%x", driver_isr_addr); + + zassert_true(arch_isr_wrapper_addr >= CONFIG_SRAM_BASE_ADDRESS && + arch_isr_wrapper_addr <= + CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024, + "arch_isr_wrapper_addr is not in RAM! Address: 0x%x", arch_isr_wrapper_addr); + + TC_PRINT("Callback function address: 0x%lx\n", func_addr); + TC_PRINT("Driver ISR address: 0x%lx\n", driver_isr_addr); + TC_PRINT("Arch ISR wrapper address: 0x%lx\n", arch_isr_wrapper_addr); +} + +ZTEST(ram_context_for_isr, test_fake_driver_in_ram) +{ + const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(fakedriver)); + const struct fake_driver_api *api = DEVICE_API_GET(fake, dev); + uintptr_t dev_addr = (uintptr_t)dev; + + zassert_true(dev_addr >= CONFIG_SRAM_BASE_ADDRESS && + dev_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024, + "fake driver device is not in RAM! Address: 0x%x", dev_addr); + + TC_PRINT("Fake driver device address: 0x%lx\n", dev_addr); + + zassert_not_null(api, "Failed to get fake driver API"); + + api->register_irq_callback(dev, test_irq_callback, NULL); + test_flag = false; + + NVIC_SetPendingIRQ(27); + + k_busy_wait(1000); + + zassert_true(test_flag, "ISR callback was not called"); +} + +ZTEST_SUITE(ram_context_for_isr, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/application_development/ram_context_for_isr/testcase.yaml b/tests/application_development/ram_context_for_isr/testcase.yaml new file mode 100644 index 000000000000..370ffbb1b781 --- /dev/null +++ b/tests/application_development/ram_context_for_isr/testcase.yaml @@ -0,0 +1,19 @@ +common: + tags: linker +tests: + application_development.ram_context_for_isr.arm: + arch_allow: arm + filter: CONFIG_CPU_CORTEX_M_HAS_VTOR + extra_configs: + - CONFIG_CODE_DATA_RELOCATION_SRAM=y + # In case you want to add this config, place all the possible called code in RAM + - CONFIG_TRACING_ISR=n + - CONFIG_STACK_SENTINEL=n + - CONFIG_PM=n + # Exclude mps3/corstone310 because it uses another mechanism to support relocation + # of the vector table (CONFIG_ROMSTART_RELOCATION_ROM). + platform_exclude: + - mps3/corstone310/an555 + - mps3/corstone310/fvp + - mps4/corstone315/fvp + - mps4/corstone320/fvp