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

osMessageGet causes HardFault when IRQ disabled

Hello All, the following code is generating a HardFault. I'm sure I've missed something stupid:

void Thread_Debug2(void const *argument)
{
        // locals
        Debug_Struct * pDbgStrct = 0;
        osStatus Status = osOK;
        uint32_t Placements2 = 0;

        // Start
        while(1)
        {
                // disable irq
                __disable_irq();

                // get message, here the hardfault occurs
                pDbgStrct = (Debug_Struct *)osMessageGet(MsgQueue_Debug1, 0).value.v;

                // enable irq
                __enable_irq();

                // free memory
                Status = osPoolFree(MemPool_Debug1, pDbgStrct);

                // check status
                if(Status == osOK)
                {
                        Placements2++;
                }
        }
}

In my opinion, the osMessageGet should be able to get a message from a message queue even when no interrupt is activated...

Parents
  • Yes, you may not make OS calls from thread level with interrupts disabled. The OS is always called through the SVC mechanism while in thread mode and if you have interrupts disabled this will always hardfault (you already know this).

    As far as being stupid, no it is not unreasonable to think that this might be possible, but if you study the OS Code, you would find out why this is not a good idea at all. Since all OS function calls are thread safe, I would hope that you would not need to disable interrupts in the way you did. IF you really need the special case you show (and yes, this is not something that people would normally try to do) you need to do something different. The main advantage to using the os functions is that you can "wait" for things to happen while not prohibiting another task to run. In the example you show, you are essentially polling for data instead of "politely" waiting for data. Polling is often an easy way to accomplish things and verifiable as correct. Of course in your example you are not only disabling interrupts and polling, there is never a time that your task ever blocks to allow other tasks to run. Also it is ALWAYS freeing a message even if it did not receive one.

    My guess is that Thread_Debug2 should not disable interrupts. It should do an osMessageGet() with an infinite timeout. When it gets a message, IF you really do need to disable interrupts to process the message, you can disable them - but so far it does not look like it is needed. Remember, until your task frees the message, no one else can use it AND both the osMessageGet() and the Free() are thread / IRQ safe.

    one difficulty to overcome working while interrupts disabled would be -

    (Task switching may need to be initiated from thread mode, which requires a switch to Handler Mode, which cannot happen if interrupts are disabled)

Reply
  • Yes, you may not make OS calls from thread level with interrupts disabled. The OS is always called through the SVC mechanism while in thread mode and if you have interrupts disabled this will always hardfault (you already know this).

    As far as being stupid, no it is not unreasonable to think that this might be possible, but if you study the OS Code, you would find out why this is not a good idea at all. Since all OS function calls are thread safe, I would hope that you would not need to disable interrupts in the way you did. IF you really need the special case you show (and yes, this is not something that people would normally try to do) you need to do something different. The main advantage to using the os functions is that you can "wait" for things to happen while not prohibiting another task to run. In the example you show, you are essentially polling for data instead of "politely" waiting for data. Polling is often an easy way to accomplish things and verifiable as correct. Of course in your example you are not only disabling interrupts and polling, there is never a time that your task ever blocks to allow other tasks to run. Also it is ALWAYS freeing a message even if it did not receive one.

    My guess is that Thread_Debug2 should not disable interrupts. It should do an osMessageGet() with an infinite timeout. When it gets a message, IF you really do need to disable interrupts to process the message, you can disable them - but so far it does not look like it is needed. Remember, until your task frees the message, no one else can use it AND both the osMessageGet() and the Free() are thread / IRQ safe.

    one difficulty to overcome working while interrupts disabled would be -

    (Task switching may need to be initiated from thread mode, which requires a switch to Handler Mode, which cannot happen if interrupts are disabled)

Children
No data