cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f103re EXTI interrupt response time

trisf
Associate II
Posted on December 01, 2011 at 06:29

First of all sorry for English and messy explanation.

One of EXTI channels configured as interrupt on falling edge.

EXTI ISR  toggles GPIO(set/reset) pin and resets EXTI pending bit.

I measured time between these 2 events EXTI_6 falling edge and GPIO rising edge.

And the fastest time I get with IAR toolchain (high speed optimization) is ~ 360ns.

The question is - Why does it takes so long(~26 cycles)?

Code example

&sharpinclude ''stm32f10x.h''

EXTI_InitTypeDef    EXTI_InitStructure;

NVIC_InitTypeDef    NVIC_InitStructure;

GPIO_InitTypeDef    GPIO_InitStructure;

void EXTI9_5_IRQHandler(void);

int main(void){

 

  __disable_irq();

 

  RCC_PCLK1Config(RCC_HCLK_Div1);

  RCC_PCLK2Config(RCC_HCLK_Div1);

 

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |

                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO ,  ENABLE);

 

  GPIO_InitStructure.GPIO_Pin =   GPIO_Pin_6 | GPIO_Pin_7 ;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1 ;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;

 

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

 

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB , GPIO_PinSource6 );

  EXTI_InitStructure.EXTI_Line = EXTI_Line6;

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;

  EXTI_Init(&EXTI_InitStructure);

    

  GPIOA->BSRR = GPIO_BSRR_BR1 ;

  __enable_irq();

  while (1){

  };  

};

void EXTI9_5_IRQHandler(void){

 

  GPIOA->BSRR = GPIO_BSRR_BS1; //  PA1 set

  GPIOA->BSRR = GPIO_BSRR_BR1 ; //  PA1 reset

  EXTI->PR = EXTI_Line6 ;

};

First strings of IRQ Handler in assembler I`ve got from compiler

        SECTION `.text`:CODE:NOROOT(1)

        THUMB

//  111 void EXTI9_5_IRQHandler(void){

//  112   

//  113   GPIOA->BSRR = GPIO_BSRR_BS1; //  PA1 set

EXTI9_5_IRQHandler:

        LDR.N    R0,??DataTable1_3  ;; 0x40010414

        MOVS     R1,♯+2

        STR      R1,[R0, ♯+1020]

#strm32f103re-exti
10 REPLIES 10
domen23
Associate II
Posted on December 01, 2011 at 09:33

Are you measuring this with a scope?

Enable interrupts before you trigger the pin.

What's your clock? I'd assume 72 MHz, but max pclk1 is 36 MHz, so either you have this set wrong, or your clock is lower.

Flash pre-fetching and wait cycles?
trisf
Associate II
Posted on December 01, 2011 at 14:38

1) Measurements done with digital channels of oscilloscope

2) STM32F10X_HD defined so I assume it is 72 MHz (8MHz(external crystal)*9(PLLMUL=0x7))

3) thank you for pointing to pclk1, its my mistake

4) flash pre-fetch enabled, flash 2 wait states, vect_table in flash

5) std_periph_lib_v3.5

I think that suggested code is quite clear.

Or maybe you know the better way how to show interrupt response to external event?

Where is bottleneck in this chain EXTI - NVIC - CORE(+FLASH) - GPIO  

ARM DDI 0337E figure 5-2(Exception entry timing) says that first instruction of ISR after 12 cycle latency is already in execution stage(or is it not and why?)

emalund
Associate III
Posted on December 01, 2011 at 15:34

you can read about interrupt latency (12+ cycles) here:

http://www.arm.com/files/pdf/IntroToCortex-M3.pdf

36/12 = 3Mhz = 333ns not far from your measurements

Erik

trisf
Associate II
Posted on December 02, 2011 at 08:24

Hi Erik

If core runs at 36MHz then 360ns is ok.  

MCO pin (RCC_MCO_PLLCLK_Div2) runs at 36MHz.  Core clock is 72 MHz?

If core runs at 72MHz isn`t it 72/12=6MHz=166ns?

Thats why i was so confused.

emalund
Associate III
Posted on December 02, 2011 at 16:24

Have you verified with a scope that you are, indeed, running 72MHz.  I have, on no less than two occasions found that the ST bootup software only resulted in half the supposed clock frequency.

Please do not come back with some response re you code SFR contents or whatever verify with a scope. One way is to run sysclk at /72000 and bring a flipping bit out on a pin.

Erik

From: popov.ilya

Posted: Frid
mehmet.karakaya
Associate III
Posted on December 02, 2011 at 21:32

hello ,

RCC_GetClocksFreq(&RCC_ClockFreq);

can we be sure that the above function returns the correct

system and peripheral clocks ?

Posted on December 02, 2011 at 22:06

RCC_GetClocksFreq(&RCC_ClockFreq);

 

can we be sure that the above function returns the correct  system and peripheral clocks ?

Output diagnostic data on the serial port. If your serial port baud rate works properly, you know the internal clock speed data is correct, as it's based on the same set of numbers and clock assumptions.

The most classic failure is an incorrect value of HSE_VALUE being used by the library. Often 25 MHz vs 8 MHz

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on December 02, 2011 at 22:35

If core runs at 72MHz isn`t it 72/12=6MHz=166ns?

Let's be clear here, it's going to eat at least 12 cycles before it even starts your  interrupt code, in context switching costs. The instruction being interrupted must also complete, consider multi-register push/pop scenarios. Or access to APB/AHB resources consuming multiple cycles.

At 72 MHz the FLASH is running at 3 cycles, You are going to get penalized when starting the interrupt routine, and when fetching literals. The APB buses introduce  cycles.

There is probably some latency as the EXTI pin is synchronized, and it looks for edges/transitions.

Clearing the interrupt should *not* be the last thing you do before exiting, you run into pipeline/write-buffer hazards. Failure to do this will result in the immediate spurious re-entry of the routine.

Try running your test with all your code/interrupts running out of SRAM

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
trisf
Associate II
Posted on December 05, 2011 at 12:15

Erik

I Put everything to SRAM.

SYSCLK_FREQ_72MHz defined

Scope measurements: SPI1_SCK pin (BRR configured to SPI_BaudRatePrescaler_4) ~18MHz, MCO(PLLCLK_DIV2) pin ~36 MHz.

So APB2 and PLL runs at 72MHz.

ISR response ~400 ns.

SYSCLK_FREQ_36MHz defined

Scope measurements: SPI1_SCK pin (BRR configured to SPI_BaudRatePrescaler_4) ~9MHz, MCO(PLLCLK_DIV2)  pin  ~18 MHz.

So APB2 and PLL runs at 36MHz.

ISR response ~740ns.

Clive

Your words almost persuaded  me  that measured values are quite normal.

The thing is that STM does not mention all these aspects in their documentation (or I couldn`t find it). Like how many APB cycles does it take signal to pass from pin to NVIC via EXTI or latency of other interrupts from peripheral devices?

Clive and Erik Im gratefull for your response