2025-07-16 12:41 AM
Hello friends : )
I've recently tested the NUCLEO-G491RE board for an upcoming redesign.
Current design relies on quite tough interrupt latency so here is where I begun.
As I understand, with no FPU usage (in isr) (ASPEN + LSPEN = 0) one could expect up to 12 SYSCLK latency.
In this case 75ns at 160MHz which sounds pretty decent (today it's about 73ns).
I started off by creating two very similar interrupt services I intended to toggle between.
Each would pulse a output pin and trigger the other one:
Attributes: 'interrupt' + optimize("-O2")' + 'section(".RamFunc")' + 'aligned(8)' + 'naked'
static void onTimeStampEvent(void)
{
GPIOA->BSRR = 1<<12;
NVIC->ISPR[1] = 1<<(39-1*32); // USART3
GPIOA->BRR = 1<<12;
#ifdef NAKED
__ASM volatile ("BX LR":::);
#endif
return;
}
static void onReceiveEvent(void)
{
GPIOB->BSRR = 1<<14;
NVIC->ISPR[0] = 1<<(11-0*32); // DMA1_CH1
GPIOB->BRR = 1<<14;
#ifdef NAKED
__ASM volatile ("BX LR":::);
#endif
return;
}
In main the usual suspects:
Finally, the main loop:
u = 0;
while(1)
{
NVIC->ISPR[0] = 1<<(11-0*32); // DMA1_CH1
u++;
}
This works splendidly, sort of...
<PicoScope shot 1>
The total time for a complete round trip is about 381ns or 61 SYSCLK.
Variable "u" in main never changes from "0" suggesting expected continuous interrupts.
The thing is, would not tail-chaining occur?
Now I tried diversify priority levels, yellow being less important:
<PicoScope shot 2>
Priority in action, indeed, however now a round trip takes 562ns (90 SYSCLK).
Still no tail-chaining, and worse, lots of extra time for the same amount of work.
Where have I done wrong?
Any help appreciated = )
/Hen
2025-07-16 1:45 AM
Try to interpret the timing we see using the disasm.
JW
2025-07-16 1:50 AM
Im sorry, not to knowledged in STM matters.
Would you please explain a little bit further?
BTW, thank you = )
/Hen
2025-07-16 2:12 AM
If you want to discuss clock-level timing, you have to have a look at the particular instructions executed, not the source code.
JW
2025-07-16 2:16 AM
Yes, that makes perfect sense : )
onTimeStampEvent:
20000010: mov.w r3, #1207959552 @ 0x48000000
20000014: mov.w r2, #4096 @ 0x1000
20000018: str r2, [r3, #24]
140 NVIC->ISPR[1] = 1<<(39-1*32); // USART3
2000001a: ldr r3, [pc, #20] @ (0x20000030 <onTimeStampEvent+32>)
2000001c: movs r2, #128 @ 0x80
2000001e: str.w r2, [r3, #260] @ 0x104
141 GPIOA->BRR = 1<<12;
20000022: mov.w r3, #1207959552 @ 0x48000000
20000026: mov.w r2, #4096 @ 0x1000
2000002a: str r2, [r3, #40] @ 0x28
143 __ASM volatile ("BX LR":::);
2000002c: bx lr
145 return;
onReceiveEvent:
20000038: ldr r3, [pc, #28] @ (0x20000058 <onReceiveEvent+32>)
2000003a: mov.w r2, #16384 @ 0x4000
2000003e: str r2, [r3, #24]
161 NVIC->ISPR[0] = 1<<(11-0*32); // DMA1_CH1
20000040: ldr r3, [pc, #24] @ (0x2000005c <onReceiveEvent+36>)
20000042: mov.w r2, #2048 @ 0x800
20000046: str.w r2, [r3, #256] @ 0x100
162 GPIOB->BRR = 1<<14;
2000004a: ldr r3, [pc, #12] @ (0x20000058 <onReceiveEvent+32>)
2000004c: mov.w r2, #16384 @ 0x4000
20000050: str r2, [r3, #40] @ 0x28
164 __ASM volatile ("BX LR":::);
20000052: bx lr
166 return;
Is this what you're talking about?
/Hen
2025-07-16 3:24 AM
Will be offline a couple of days, but some extras before I go.
I've set break on every handler (stopped systick) and no trap.
HAL_SuspendTick();
The debug variable is at file scope and volatile.
volatile unsigned u;
Tested different priorities with no change (except both the same).
Verified no FPU registers being stacked.
Much appreciated for any insight
/Hen
2025-07-16 3:49 AM - edited 2025-07-16 4:01 AM
NVIC->ISPR[0] = 1<<(39-1*32); // DMA1_CH1
What do you think this statement will do? (Hint: C is not python!)
This MCU has core-coupled RAM (CCM SRAM), you can put these functions there for better latency.