Skip to main content
Visitor II
May 30, 2007
Question

Temporarily locking of Interrupts on STR71x/STR73x/STR75x

  • May 30, 2007
  • 18 replies
  • 2511 views
Posted on May 30, 2007 at 17:35

Temporarily locking of Interrupts on STR71x/STR73x/STR75x

    This topic has been closed for replies.

    18 replies

    Visitor II
    April 25, 2007
    Posted on April 25, 2007 at 12:41

    One idea from absolutely another dimension - it is also possible to disable FIQ and IRQ at ARM core level by writing CPSR register. Not regarding the ARM7TDMI for STR71x and STR73x nor ARM7TDMI-S for STR75x, the procedure is always the same for all STR7xx CPU versions - read, modify and write the CPSR register. You can find more info in ARM7TDMI(-S) Technical Reference Manual available at arm's website...

    Handicap - this enables/disables all FIQ and/or IRQ interrupts (two independent locking bits), not only one specific interrupt.

    [ This message was edited by: opijozko on 25-04-2007 16:15 ]

    neunerAuthor
    Visitor II
    April 25, 2007
    Posted on April 25, 2007 at 13:09

    Mike also mentioned something in that way. But disabling the global interrupt requires this procedure:

    http://www.arm.com/support/faqip/3677.html

    So, I would prefer adding NOPs in my code, instead this stuff mentioned in that document. But of course if it is the only correct method, I might have no option and have to use it.

    BTW: Also I do not like to disable all interrupts if it is possible.

    Regards

    Andreas

    neunerAuthor
    Visitor II
    April 26, 2007
    Posted on April 26, 2007 at 06:23

    Update:

    I just tried, why my former tests (STR71 and STR73 code from me exists since some time) did not detect the problem.

    Implementation:

    The disabling of the interrupt is done in a separate function. When the function returns the access to my 'protected' variable is made. In case I move now my instruction from disabling the CAN interrupt:

    #if (TAR_CHECK_CAN_IRQ_LOCKING == 1)

    DBG_CANIRQ_CounterCpy = DBG_CANIRQ_Counter;

    #endif

    to the caller of this function. Like:

    Function_xyz()

    {

    CanIntDisable();

    #if (TAR_CHECK_CAN_IRQ_LOCKING == 1)

    DBG_CANIRQ_CounterCpy = DBG_CANIRQ_Counter;

    #endif

    ....

    }

    I do not see the problem on none of the STR7xx devices (including the STR710).

    This is either caused, because I get now a different timing or what I suppose is, that due to the jump back to the caller, the instruction pipeline of the ARM is flushed and needs to be first reloaded (this is similar to the 'NOPs' ?).

    But if it is really the jump back and not the timing, it may be anyway dangerous -- because some compilers might optimize such 'small' functions and make them in a kind of 'inline code'. In this case, there will be no function call and so also no flush of the pipeline.

    Regards

    Andreas

    Visitor II
    April 26, 2007
    Posted on April 26, 2007 at 06:23

    So... my opinion is as follows:

    There is 3-stage pipeline in ARM7TDMI core. So, if actually the instruction disabling the interrupt is loaded, yet two next instructions must be loaded while it takes effect. Therefore you need two nops, if EIC clock (I think it is APB2 clock in STR710 case) is equal to core clock. If EIC is clocked in slower rate, these two instructions must be multiplied by factor of clock ratio (e.g. by factor of 2 if EIC is clocked in half of core, therefore you need 2x2=4 nops).

    On the other hand:

    There are from 2 up to 4 clock cycles needed to catch the interrupt by EIC. EIC generates the IRQ request to ARM core by setting the nIRQ line. ARM core needs additional from 5 up to 29 (in case of single IRQ request, without FIQ intervention) clock cycles to start handle the interrupt (it depends on actual instruction executed, see ARM7TDMI TRM rev4p1 at page 2-23 for more info). So, even if you already have interrupt disabled, it seems that some oldier interrupt request (rising more than 30 clock cycles before) may be still waiting at ARM core level and executed later.

    neunerAuthor
    Visitor II
    April 26, 2007
    Posted on April 26, 2007 at 07:24

    Sounds interesting. So either I had with the 'jump/flush pipeline' so far good luck and the ARM core required only the minimum latency. Or maybe the EIC has removed the 'Last interrupt' before the ARM core has read it out (don't know if EIC does this).

    So questions over questions ??????

    I wrote today again to support of ST -- so far (since 2007-04-16) I even did not get a direct contact partner, only an automatic reply --, maybe they can finally clarify this topic.

    Thank you for your reply.

    Regards

    Andreas

    Visitor II
    May 10, 2007
    Posted on May 10, 2007 at 11:16

    Hi Andreas, your support should be managed by your local ST FAE, not by online support - it works, except MCUs :D The ST FAE has access to European MCU support directly.

    I recommend to you using SWI for your non-interruptable processing, because SWI does disable IRQs automatically. In User mode you can't access I & F bits.

    Another approach - you use SWI as a service provider, that modifies SPSR by updating I & F flags, and returns. It might update I & F bits in User mode, then.

    Tomas

    neunerAuthor
    Visitor II
    May 14, 2007
    Posted on May 14, 2007 at 09:24

    Hi Edison,

    you are right -- FAE has answered within one day. I am currently checking the proposals (proposals: Try with SWI or alternatively try to disable Interrupt Control register in EIC->ICR register).

    As soon as we find a solution I will post the result (but this may take some days/week(s)).

    BTW: What did you mean with ''service provider''. I can roughly think what you want to do, but do you think you can explain it in more detail.

    Regards

    Andreas

    Visitor II
    May 30, 2007
    Posted on May 30, 2007 at 17:35

    ''Service provider'' means to me that you have some underlaying layer of services (eg. your system routines or those handling your protected code) and the ''provider'' is a way (instruction) to enter these services. In my opinion the SWI is a way, how to access the service provider.

    Nevertheless, opijozko, I think that you don't need additional 29 NOP cycles in ARM code because the core proceeds with only one long instruction, but just 2 (IRQ entrance)+2 (pipeline ahead of eg. multiply or STMFD).