This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

external irq called twice depending on optimization level

Controller: STM32F103
Compiler: ARM-MDK 4.14

I have a flow-meter connected to a portpin. I like to count on rising and falling slope. So I initialized this ext. irq to meet these requirements. The software works since a couple of weeks without any problem.

This week I recognized that the optimiziation level is accidentally set to 0. Ok, no problem, I set it to maximum level 3.

After this action the code shrunk significantly - nice!

But my flow-meter gave me values twice as high as usual.

I put some LED-switchings into the isr and could detect that every slope of the flow meter triggers the isr exactly twice.

This is my isr for EXTI Line 14

  void IHW_DfmImpulseIsr(void) {
    COUNT_iCount(COUNT_kDFMBRUEHWASSER);  //count on each slope
    EXTI_ClearITPendingBit(EXTI_Line14);
  } // IHW_DfmImpulseIsr()

I found an other thread, that the reason might be that the isr-pending-bit is not cleared in time. But where is the casual connetion to optimization level.

And the crucial question, HOW to clear pending-bit correctly? Unfortunately I could not find any commendation neither from KEIL/ARM nor from ST.

Parents
  • two solutions

    1. usage of __DSB()

      void IHW_DfmImpulseIsr(void) {
        COUNT_iCount(COUNT_kDFMBRUEHWASSER);  //count on each slope
        EXTI_ClearITPendingBit(EXTI_Line14);  //clear pending bit
        __DSB();                              //make shure, pending bit is cleared before return
      } // IHW_DfmImpulseIsr()
    

    2. clear pending bit as early as possible

      void IHW_DfmImpulseIsr(void) {
        EXTI_ClearITPendingBit(EXTI_Line14);  //clear pending bit
        COUNT_iCount(COUNT_kDFMBRUEHWASSER);  //count on each slope
                                              //hope, that pending bit is already cleared :)
      } // IHW_DfmImpulseIsr()
    

    Both solutions are working correctly on my system (optimization Level 3, -O3). The first one takes approximately 100ns longer (measured).

    To be shure never get traped by this one could execute __DSB() at the end of the library function EXTI_CleareITPentdingBit().

Reply
  • two solutions

    1. usage of __DSB()

      void IHW_DfmImpulseIsr(void) {
        COUNT_iCount(COUNT_kDFMBRUEHWASSER);  //count on each slope
        EXTI_ClearITPendingBit(EXTI_Line14);  //clear pending bit
        __DSB();                              //make shure, pending bit is cleared before return
      } // IHW_DfmImpulseIsr()
    

    2. clear pending bit as early as possible

      void IHW_DfmImpulseIsr(void) {
        EXTI_ClearITPendingBit(EXTI_Line14);  //clear pending bit
        COUNT_iCount(COUNT_kDFMBRUEHWASSER);  //count on each slope
                                              //hope, that pending bit is already cleared :)
      } // IHW_DfmImpulseIsr()
    

    Both solutions are working correctly on my system (optimization Level 3, -O3). The first one takes approximately 100ns longer (measured).

    To be shure never get traped by this one could execute __DSB() at the end of the library function EXTI_CleareITPentdingBit().

Children