SWINTR v. trap in RX600 GCC port

anonymous wrote on Monday, September 26, 2011:

The definition for portYIELD() for the RX600 port in V7.0.2, (FreeRTOS/Source/portable/GCC/RX600/portmacro.h) looks like this:

/* The location of the software interrupt register.  Software interrupts use
vector 27. */
#define portITU_SWINTR                  ( ( unsigned char * ) 0x000872E0 )
#define portYIELD()                             *portITU_SWINTR = 0x01; portNOP(); portNOP(); portNOP(); portNOP(); portNOP()

This raises several questions:

  • First, why not use a trap instruction (e.g:  “INT #27”) for portYIELD() (as was done for the H8S port for example)?

  • Second, what bug or (apparently undocumented) feature requires the use of no less than 5 NOPs after setting the SWINTR register?

  • Lastly, shouldn’t it be enclosed in a do{}while(0) block?  Or better yet, shouldn’t it be a static inline function?  As is, an otherwise perfectly reasonable code snipit such as

    if (foo) portYIELD(); else bar();
    

will not even compile.

thanks in advance,
brad

rtel wrote on Monday, September 26, 2011:

First, why not use a trap instruction (e.g: “INT #27”) for portYIELD() (as was done for the H8S port for example)?

The asynchronous software interrupt is a far more powerful method, and included in the core for this purpose (as it is in the Cortex-M).  I believe it was an addition that came to the architecture after the RX610 devices. 

Using a synchronous trap has two disadvantages in this case.  First, supporting interrupt nesting is much more complex and requires much more code.  Second, as a result of the first, interrupt response times are adversely effected.

Second, what bug or (apparently undocumented) feature requires the use of no less than 5 NOPs after setting the SWINTR register?

I would have to check the data sheets to answer that one.  It might be preventing execution of instructions in branch delay slots, or pipelines.  I use a *lot* of different cores and cannot recall offhand.  It might be that the NOPs are no longer needed even.

Lastly, shouldn’t it be enclosed in a do{}while(0) block?

I take the point about the hanging else.  My coding standard will not permit an if without an explicit {} block, but granted the code provided should allow for use in everybody’s applications.   The while(0) solution is a non starter for this proect.  First, it breaches nearly all formal coding standards.  Second it will cause “condition is always false” warnings from the compiler in a lot of cases (depending on the warning level - I tend to compile with very pedantic warnings).

Regards.