Hello experts,
I am using SAM L11 (Core is Cortex-M23).I did a simple test of the interrupt.In the case of the handler was the secure world, it worked as I expected.The instruction sequences are as the follows. *(int*)(0xE000E380) = 0; *(int*)(0xE000E100) = 1; *(int*)(0xE000E200) = 1; for(i=0;i<1000;i++);However, when Interrupt Target Non-secure Register (0xE000E380) was set,the HardFault had occurred. As for SAM L11, would it be reasonable behavior? *(int*)(0xE000E380) = 1; *(int*)(0xE000E100) = 1; *(int*)(0xE000E200) = 1; /* HardFault */ for(i=0;i<1000;i++);Although I put the vector of the secure world to the non-secure world address, the phenomenon was not changed.From the specification aspect, how does it work?
Thank you and best regards,
Yasuhiko Koumoto.
Hi,
could you please describe the configuration of the interrupts ? Which are assigned to secure and those not?
thanks
there are no specific configurations.I use NVIC registers directly.The settings are the followings.NVIC_ISER0[0]=1 /* Interrupt Enable */NVIC_ISPR0[0]=1 /* make the interrupt pending */
Because NVIC_ITNS0[0]=1, INT0 target is the only non-secure and all the others are secure.
Thank you,Yasuhiko Koumoto.
Where does the code for the interrupt handler reside ?
Hi,here are the source codes extracted.If I use "*(int*)(0xE000E380) = 0;" the vector is .pfnSYSTEM_Handler = (void*) SYSTEM_Handler, /* 0 Main Clock */If I use "*(int*)(0xE000E380) = 1;" the vector is .pfnSYSTEM_Handler = (void*) 0x8455, /* 0 Main Clock */Here, the address 0x8455 is the SYSTEM_Handler address of the non-secure world.That's all.Thank you and best regards,Yasuhiko Koumoto.
/* Cortex-M23 core handlers */void NonMaskableInt_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void SVCall_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
/* Peripherals handlers */void SYSTEM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
__attribute__ ((section(".vectors")))const DeviceVectors exception_table = {
/* Configure Initial Stack Pointer, using linker-generated symbols */ .pvStack = (void*) (&_estack),
.pfnReset_Handler = (void*) Reset_Handler, .pfnNonMaskableInt_Handler = (void*) NonMaskableInt_Handler, .pfnHardFault_Handler = (void*) HardFault_Handler, .pvReservedC12 = (void*) (0UL), /* Reserved */ .pvReservedC11 = (void*) (0UL), /* Reserved */ .pvReservedC10 = (void*) (0UL), /* Reserved */ .pvReservedC9 = (void*) (0UL), /* Reserved */ .pvReservedC8 = (void*) (0UL), /* Reserved */ .pvReservedC7 = (void*) (0UL), /* Reserved */ .pvReservedC6 = (void*) (0UL), /* Reserved */ .pfnSVCall_Handler = (void*) SVCall_Handler, .pvReservedC4 = (void*) (0UL), /* Reserved */ .pvReservedC3 = (void*) (0UL), /* Reserved */ .pfnPendSV_Handler = (void*) PendSV_Handler, .pfnSysTick_Handler = (void*) SysTick_Handler,
/* Configurable interrupts */ .pfnSYSTEM_Handler = (void*) SYSTEM_Handler, /* 0 Main Clock */// .pfnSYSTEM_Handler = (void*) 0x8455, /* 0 Main Clock */ .pfnWDT_Handler = (void*) WDT_Handler, /* 1 Watchdog Timer */ .pfnRTC_Handler = (void*) RTC_Handler, /* 2 Real-Time Counter */ .pfnEIC_0_Handler = (void*) EIC_0_Handler, /* 3 External Interrupt Controller */ .pfnEIC_1_Handler = (void*) EIC_1_Handler, /* 4 External Interrupt Controller */ .pfnEIC_2_Handler = (void*) EIC_2_Handler, /* 5 External Interrupt Controller */ .pfnEIC_3_Handler = (void*) EIC_3_Handler, /* 6 External Interrupt Controller */ .pfnEIC_OTHER_Handler = (void*) EIC_OTHER_Handler, /* 7 External Interrupt Controller */ .pfnFREQM_Handler = (void*) FREQM_Handler, /* 8 Frequency Meter */---[snip]--- .pfnPTC_Handler = (void*) PTC_Handler, /* 42 Peripheral Touch Controller */ .pfnTRNG_Handler = (void*) TRNG_Handler, /* 43 True Random Generator */ .pfnTRAM_Handler = (void*) TRAM_Handler /* 44 TrustRAM */};
void SYSTEM_Handler(void){ //*(int*)(0xE000E280) = 1; //*(int*)(0xE000E100) = 1; printf("SYSTEM Handler in Secure Region.\n\r");}
int main(void){ volatile int i; /* Initializes MCU, drivers and middleware */ atmel_start_init();
printf("Secure application is running.\r\n");
/* Set non-secure main stack (MSP_NS) */ __TZ_set_MSP_NS(*((uint32_t *)(CONF_TZ_START_NS))); *(int*)(0xE000E380) = 0; *(int*)(0xE000E100) = 1; *(int*)(0xE002E100) = 1; *(int*)(0xE000E200) = 1; for(i=0;i<1000;i++); *(int*)(0xE000E200) = 1; for(i=0;i<1000;i++); *(int*)(0xE000E200) = 1; for(i=0;i<1000;i++); /* Get non-secure reset handler */ NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((CONF_TZ_START_NS) + 4U)));
/* Start non-secure state software application */ NonSecure_ResetHandler();
/* Replace with your application code */ while (1) { __NOP(); }}
thank you for the details
the one I was after is the configuration of the secure and non secure memory
I am looking to see where these handlers reside
if the exception handler for the non secure side resides in secure memory then you will get a security fault.
please check the settings of the security attribution unit if any and look for the part of the code that declares the non secure memory region.
HI,it seems that SAM L11 only support the non-secure handler of interrupts for EIC (External Interrupt Controller). Of which interrupt numbers are 4, 5, 6, and 7.Of course, EIC must be configured prior to use it.I double the interrupt 0 cannot be supported the non-secure handler.As for the security attributes, they are as fllows.0x00000000-0x00007bff Secure0x00007c00-0x00007fff Non-Secure Callable0x00008000-0x0000ffff Non-Secure.Best regards,Yasuhiko Koumoto.
it might be good to analyze the reason for the "hard fault" that you are getting. The controller offers registers that give you more details.
This pages might help: - http://www.keil.com/support/man/docs/uv4/uv4_cp_armv8_faults.htm - http://www.keil.com/appnotes/files/apnt209.pdf
The appnote does not specifically contain the Cortex-M23, but the concept for analysis is the same.
Hi there,
I think if you target the interrupt to the non-secure world, and you should enable the interrupt in the non-secure world but not the secure world. If you open it in secure world, there will be a fault. So you can have a try.
Best regards.
Has the problem been solved?
>Although I put the vector of the secure world to the non-secure world address,
> the phenomenon was not changed. From the specification aspect, how does it work?
This wouldn't work. Non-secure world cannot execute an interrupt handler in the Secure address space.
Non-secure world must have its own vector table (with boot code such as reset handler) and the interrupt handlers must in in Non-secure memories.
regards,
Joseph
Hi Joseph,
I think I have the same "problem" that Yasuhiko Koumoto occured. I try to describe it.
//Secure world
NVIC_SetPriority(TRNG_IRQn, 1);NVIC_SetTargetState(TRNG_IRQn);NVIC_EnableIRQ(TRNG_IRQn);
TRNG_INTENSET = TRNG_INTENSET_DATADRY; // enable intTRNG_CTRLA |= TRNG_CTRLA_ENABLE; // enable device. Hardfault will be occur after this instruction
But if i change the code into...
NVIC_SetPriority(TRNG_IRQn, 1);NVIC_SetTargetState(TRNG_IRQn);// NVIC_EnableIRQ(TRNG_IRQn);
//Non-secure world
NVIC_EnableIRQ(TRNG_IRQn);
The non-secure interrupt will occur.
And I tried put all 5 instructions into non-secure callable function as follow, it worked.
void __attribute__((cmse_nonsecure_entry)) in(){ NVIC_SetPriority(TRNG_IRQn, 1); NVIC_SetTargetState(TRNG_IRQn); NVIC_EnableIRQ(TRNG_IRQn);
TRNG_INTENSET = TRNG_INTENSET_DATADRY; // enable int TRNG_CTRLA |= TRNG_CTRLA_ENABLE; // enable device while(1);}
Best regrads,
Wenchuan
With the first code arrangement, it might be possible that your Non-secure world hasn't boot up and hence Non-secure Main stack pointer has not been initialized.