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

RTOS osMessagePut usage problem

It takes me several days for debbuging ,but didn't work.

when the para 'timeout' of osMessagePut(id,info,timeout) is not set to 0,
then the program crashes with info 'OS_ERROR_MBX_OVF' , which means mailbox overflow.
But with timeout setting to 0,everything seems ok.

It really confuses me. Can anyone help me ? Thanks a lot!

The main frame of my program is as follows
(it is from mdk example 'CAN_Ex', basically not changed much )

osPoolDef(rlcan_mpool, 80, CAN_msg);
osMessageQDef(rlcan_msgq_tx, 20, CAN_msg);

/* Thread1, used to send can message */
while(1)
{
        ...
        /* check if  hardware is free for send */
        if (CAN_hw_tx_empty (ctrl) == CAN_OK)
        {
                CAN_hw_wr (ctrl, msg);     /* Send message */
        }
        else
        {
                ptrmsg = osPoolAlloc(rlcan_mpool);

                  /* for timeout is not 0, it crashes after ISR getting about 16 messages */
                result = osMessagePut(rlcan_msgq_tx, ptrmsg, 10);
                if (result != osOK) osPoolFree(rlcan_mpool, ptrmsg);
        }
        osDelay (500);
}


/* ISR, interrupt generates after msg sending succeeds */

void CAN0_ORed_Message_buffer_IRQHandler (void)
{
        ...
        iflag1 = CANc->IFLAG1; //iflag1 will be set if  msg sending succeeds

        while(iflag1)
        {
                iflag1 = 0;

                 /* it crashes after getting about 16 messages */
                 evt = osMessageGet(rlcan_msgq_tx[CTRL0], 0);
                if (evt.status == osEventMessage)
                {
                        CAN_hw_wr (CTRL,evt.value.p);  /* Send message */
                        osPoolFree(rlcan_mpool, evt.value.p);
                }
                iflag1 = CANc->IFLAG1; //check whether iflag1 is set again
        }
}

Parents
  • Please refer to this manual to get more details regarding osMessagePut():
    www.keil.com/.../group___c_m_s_i_s___r_t_o_s___message.html

    Especially this part might be relevant for you:
    "When the message queue is full, the system retries for a specified time with millisec. While the system retries the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

    -> when millisec is 0, the function returns instantly.
    -> when millisec is set to osWaitForever the function will wait for an infinite time until a message queue slot becomes available.
    -> all other values specify a time in millisecond for a timeout.

    Please Note:
    The parameter millisec must be 0 for using this function in an ISR."

Reply
  • Please refer to this manual to get more details regarding osMessagePut():
    www.keil.com/.../group___c_m_s_i_s___r_t_o_s___message.html

    Especially this part might be relevant for you:
    "When the message queue is full, the system retries for a specified time with millisec. While the system retries the thread that is calling this function is put into the state WAITING. The millisec timeout can have the following values:

    -> when millisec is 0, the function returns instantly.
    -> when millisec is set to osWaitForever the function will wait for an infinite time until a message queue slot becomes available.
    -> all other values specify a time in millisecond for a timeout.

    Please Note:
    The parameter millisec must be 0 for using this function in an ISR."

Children
  • thanks,Chen. I had read the details regarding osMessagePut(). The parameter millisec is indeed 0 for using osMessageGet() in ISR.

    And I can see the result of osMessagePut with 'printf', it shows that before entering ISR(where osMessageGet is called), osMessagePut has already returned,as showing below.

    I'm really confused now.

    /* Thread1, used to send can message */
    while(1)
    {
            ...
            /* check if  hardware is free for send */
            if (CAN_hw_tx_empty (ctrl) == CAN_OK)
            {
                    CAN_hw_wr (ctrl, msg);     /* Send message */
            }
            else
            {
                    ptrmsg = osPoolAlloc(rlcan_mpool);
    
                    result = osMessagePut(rlcan_msgq_tx, ptrmsg, 10);
                    if (result != osOK)
                    {
                       osPoolFree(rlcan_mpool, ptrmsg);
                       printf("after osPoolFree");
                    }
            }
            osDelay (500);
    }