cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt curiosity (STM32G491)

HenrikGlader
Visitor

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:

  • HAL and System initiation
  • Peripheral initiation
  • Setting up interrupts

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

 

6 REPLIES 6
waclawek.jan
Super User

Try to interpret the timing we see using the disasm.

JW

HenrikGlader
Visitor

Im sorry, not to knowledged in STM matters.

Would you please explain a little bit further?

BTW, thank you = )

/Hen

waclawek.jan
Super User

If you want to discuss clock-level timing, you have to have a look at the particular instructions executed, not the source code.

JW

HenrikGlader
Visitor

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

HenrikGlader
Visitor

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

Pavel A.
Super User
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.