This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Race condition in IPC flag ACK



It appears that I am having a race condition in acknowledging IPC interrupt flags on the Concerto F28M35H52C1. I am using the CtoM IPC1 and IPC2 interrupts, and occasionally IPC1 will fail to acknowledge and the flag will be left set. Both interrupt handlers are already bare-minimum functions that simply acknowledge the interrupt and set a flag for later handling in the main thread.

Example code follows:

void IPCHandler1()
{
	IPCCtoMFlagAcknowledge(IPC_CTOMIPCACK_IPC1);
	IPCFlag1 = true;
}

void IPCHandler2()
{
	IPCCtoMFlagAcknowledge(IPC_CTOMIPCACK_IPC2);
	IPCFlag2 = true;
}

I believe the race condition is caused by a read-modify-write race condition on acknowledging the flags, since they both access the same register with an |= operation.

As I understand it, I have a few options:

1. Disable interrupts in the IPC handler.

2. Structure the code on the C28 so that IPC1 and IPC2 flags are set with some time separation. (This is an option for my code, but in general might not be).

3. Use bit-banding to set the acknowledge registers. This last one seems compelling as a good solution, but I can't seem to get it to work. The normal register access is given by:

void
IPCCtoMFlagAcknowledge (unsigned long ulFlags)
{
    HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= ulFlags;
}
// elsewhere
IPCCtoMFlagAcknowledge(IPC_CTOMIPCACK_IPC2);

Would the correct usage of the HWREGBITW macro to use the bit-band alias be the following?

HWREGBITW(MTOCIPC_BASE, IPC_CTOMIPCACK_IPC1) = 1;

This doesn't seem to work for me, however. Any help is appreciated on usage of the bit bands or the race condition in general.

  • Hi Michael,

    Would the correct usage of the HWREGBITW macro to use the bit-band alias be the following?

    HWREGBITW(MTOCIPC_BASE, IPC_CTOMIPCACK_IPC1) = 1;

    This doesn't seem to work for me, however. Any help is appreciated on usage of the bit bands or the race condition in general.

    HWREGBITW function is declared as HWREGBITW(x,b) where x is address of the register/RAM and b is the bit position. Please pass the argument accordingly.

    You can refer section "26.6.4 Bit-Banding" of TRM document to know how the address is calculated for bit band region. Also look at the definition of this function in "MWare\inc\hw_types.h"

    Regards,

    Vivek Singh

  • Hi Vivek,

    Thanks for responding. I've already read through the TRM section and looked at the source. My problem is that it doesn't seem to be working.

    The normal flag acknowledgement is executed with: HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= ulFlags;, which in hex is:

    0x400FB700 + 0x0 |=  0x00000001

    So that is setting the first bit at address 0x400FB700.


    If I use the corresponding bit band alias address, that should be equivalent to setting the word at address 0x43F6E000 according to the documentation. This is also given by using the HWREGBITW macro with: HWREGBITW(MTOCIPC_BASE, 0) = 1;


    I have already tried that, however, but it didn't work. The flag doesn't clear. Hence why I am posting here, to see if I am misunderstanding something.

  • After further testing, it does appear to work actually. Strangely though, when I use the bit-band method, the flag in the register remains high after the ACK register has been set, and even after the interrupt handler has exited, hence why I thought it wasn't working.
  • Hi Michael,

      Strangely though, when I use the bit-band method, the flag in the register remains high after the ACK register has been set, and even after the interrupt handler has exited.

    Do you mean bit-band method does not not work but normal write works fine ?

    Regards,

    Vivek Singh