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
  • Hello, it's me again.

    Thanks for your detailed reply.

    About the "Happy Path" ;-) : In this case it is only the osEventMessage status I need, in any other case I have to do something else so that's why I've made this. I totally agree with you, that you should check for every status and react on it. (I'll use a switch to determine the problem).

    The polling retrieval: I just want to simulate there some calculations who took cpu time. To understand: in this Thread I want to poll for a message from the queue and do other things. I don't create a whole thread just to wait for messages.

    Anyway, I think I've found my main problem about the MailboxOverflow...

    Try something below with a RTX Timer Callback Queue Size of 1

    Timers defined and created

    void Thread_Debug3(void const *argument)
    {
            // Locals
            volatile uint32_t Dummy = 0;
            osStatus  Status;
    
            // reset variables
            a = 0;
            b = 0;
    
            // 1s timer
            Status = osTimerStart (tid_Timer_1_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_2_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_3_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_4_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
    
            // Start
            while(1)
            {
                    osDelay(10);
    
                    Dummy = a + b;
                    a = 0;
                    b = 0;
            }
    }
    

    Guess what happens: MailboxOverflow!

    But WHY is the big Question. Normally I would assume that the osError will be OS_ERROR_TIMER_OVF instead of OS_ERROR_MBX_OVF

    Because of 4 Timers who are all ready on the same time will fill up the timer callback queue, but there has to be a OS_ERROR_TIMER_OVF and not the MailboxOverflow! At least when reading the comment

    case OS_ERROR_TIMER_OVF:
                            /* User Timer Callback Queue overflow detected. */
    

    So, is there a RTX problem or is something wrong with my code again?

Reply
  • Hello, it's me again.

    Thanks for your detailed reply.

    About the "Happy Path" ;-) : In this case it is only the osEventMessage status I need, in any other case I have to do something else so that's why I've made this. I totally agree with you, that you should check for every status and react on it. (I'll use a switch to determine the problem).

    The polling retrieval: I just want to simulate there some calculations who took cpu time. To understand: in this Thread I want to poll for a message from the queue and do other things. I don't create a whole thread just to wait for messages.

    Anyway, I think I've found my main problem about the MailboxOverflow...

    Try something below with a RTX Timer Callback Queue Size of 1

    Timers defined and created

    void Thread_Debug3(void const *argument)
    {
            // Locals
            volatile uint32_t Dummy = 0;
            osStatus  Status;
    
            // reset variables
            a = 0;
            b = 0;
    
            // 1s timer
            Status = osTimerStart (tid_Timer_1_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_2_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_3_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
            Status = osTimerStart (tid_Timer_4_ms, 1); // 1ms periodic timer
            if (Status != osOK)
            {
                    return; // Timer could not be started
            }
    
            // Start
            while(1)
            {
                    osDelay(10);
    
                    Dummy = a + b;
                    a = 0;
                    b = 0;
            }
    }
    

    Guess what happens: MailboxOverflow!

    But WHY is the big Question. Normally I would assume that the osError will be OS_ERROR_TIMER_OVF instead of OS_ERROR_MBX_OVF

    Because of 4 Timers who are all ready on the same time will fill up the timer callback queue, but there has to be a OS_ERROR_TIMER_OVF and not the MailboxOverflow! At least when reading the comment

    case OS_ERROR_TIMER_OVF:
                            /* User Timer Callback Queue overflow detected. */
    

    So, is there a RTX problem or is something wrong with my code again?

Children
  • "I totally agree with you, that you should check for every status and react on it. (I'll use a switch to determine the problem)."

    There is seldom a need to handle every possible error code you may get from a function call. It's enough to handle all "ok" status codes and any "error" status codes that you have work-arounds/retries/... for. Then you can have a wild-card else/default statement for any additional status code. But this code must be able to either log the problem and fully reset the device. Or log the error (time+where+status), release any allocated resources and then continue with the execution.

    The main thing is just:
    - what is happy path
    - what are expected errors that you can you recover from
    - what can you not recover from - and do you then automatically reset the device? Or intentionally lock up the device until a user performs some reset operation?
    - how to report

    And anything that isn't happy path or expected errors should be seen as unrecoverable errors without need to subdivide individual error codes further (but you want the error code logged). The only thing then is if the unexpected error should actually have been expected. Or if it happened because of corruption somewhere else.