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 } }
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."
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); }