Hi expert,
Customer has question about how to shorten interrupt latency. According to https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1097703/lp-am243-low-latency-interrupts?tisearch=e2e-sitesearch&keymatch=GPIO%252525252520latency#
The interrupt latency can be less than 100ns.
We modify the demo code gpio_input_interrupt with nortos.
1. use GPIO1_35 as interrupt trigger source.
2. tied GPIO1_36 to GPIO1_35 and toggle from low to high to trigger interrupt every second.
3. In ISR, just toggle GPIO1_8 to indicate first line of ISR is executed.
here is the test code.
We manipulate registers directly:
static void __attribute__((section("isr_tcma"))) GPIO_bankIsrFxn(void *args)
{
*GPIO1_8_SET_ADDRESS = GPIO1_8_MASK;
*GPIO1_8_CLEAR_ADDRESS = GPIO1_8_MASK;
*GPIO1_35_INTSTAT_ADDRESS = GPIO1_35_INTSTAT_MASK;
gGpioIntrDone++;
}
ISR is set to FIQ and put to TCMA.
Since this is a simple test code, we put almost everything into TCMA and TCMB0 except .sysmem. We don't use malloc function so it should not be problem
GROUP {
.text.hwi: palign(8)
.text.cache: palign(8)
.text.mpu: palign(8)
.text.boot: palign(8)
.text:abort: palign(8) /* this helps in loading symbols when using XIP mode */
isr_tcma: palign(8)
} > R5F_TCMA
/* This is rest of code. This can be placed in DDR if DDR is available and needed */
GROUP {
.text: {} palign(8) /* This is where code resides */
.rodata: {} palign(8) /* This is where const's go */
} > R5F_TCMB0
/* This is rest of initialized data. This can be placed in DDR if DDR is available and needed */
GROUP {
.data: {} palign(8) /* This is where initialized globals and static go */
.bss: {} palign(8) /* This is where uninitialized globals go */
RUN_START(__BSS_START)
RUN_END(__BSS_END)
.stack: {} palign(8) /* This is where the main() stack goes */
} > R5F_TCMA
/* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */
GROUP {
.sysmem: {} palign(8) /* This is where the malloc heap goes */\
} > MSRAM
/* This is where the stacks for different R5F modes go */
GROUP {
.irqstack: {. = . + __IRQ_STACK_SIZE;} align(8)
RUN_START(__IRQ_STACK_START)
RUN_END(__IRQ_STACK_END)
.fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8)
RUN_START(__FIQ_STACK_START)
RUN_END(__FIQ_STACK_END)
.svcstack: {. = . + __SVC_STACK_SIZE;} align(8)
RUN_START(__SVC_STACK_START)
RUN_END(__SVC_STACK_END)
.abortstack: {. = . + __ABORT_STACK_SIZE;} align(8)
RUN_START(__ABORT_STACK_START)
RUN_END(__ABORT_STACK_END)
.undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8)
RUN_START(__UNDEFINED_STACK_START)
RUN_END(__UNDEFINED_STACK_END)
} > R5F_TCMA
/* Sections needed for C++ projects */
GROUP {
.ARM.exidx: {} palign(8) /* Needed for C++ exception handling */
.init_array: {} palign(8) /* Contains function pointers called before main */
.fini_array: {} palign(8) /* Contains function pointers called after main */
} > R5F_TCMB0
Set to release mode and optimized level to fast.
program to the device and measure the test result.
You can see the ISR is clean. It still takes 309ns.
The customer is target to toggle GPIO in 200ns. Can you please advise what more we can do?
Regards
Andre