I am trying to pass a message from one task to another and when I call os_mbx_send I am getting a HardFault_Handler error. The call stack has a lot of HAL_CM3 calls. Any ideas? Seems pretty straight forward. Also, I followed instructions on setting up a mailbox.
#define MBOX_SIZE 60
typedef struct { void *pMsg; } Object_Message;
os_mbx_declare(MBox, MBOX_SIZE); /* Declare an RTX mailbox */ _declare_box (MBox_Pool, sizeof(Object_Message), MBOX_SIZE);/* Dynamic memory pool */
__task void init_task (void) { // Init mail box(s) _init_box(MBox_Pool, sizeof(MBox_Pool), sizeof(Object_Message)); /* the membox dynamic allocation */ os_mbx_init(MBox, sizeof(MBox));
//... start tasks
Comm_Mgr_Task_ID = os_tsk_create(comm_manager_task, 4); os_tsk_delete_self (); /* STOP init task (no longer needed)*/ }
/********************************************************************* comm_manager_task *********************************************************************/ __task void comm_manager_task(void) { Object_Message *pNewMsg;
while(1) { pNewMsg = (Object_Message *)_alloc_box(MBox_Pool); /* Allocate a memory for the message */ pNewMsg->pMsg = new uint8[256]; sprintf((char *)pNewMsg->pMsg, "blah"); os_mbx_send(pNewMsg, MBox, TASK_WAIT_FOREVER); <== HardFault_Handler here os_dly_wait(SYS_MSEC_TO_TICKS(1000)); } }
/********************************************************************* main *********************************************************************/ int main(void) { SystemInit(); ADC_init(); /* ADC Initialization */
// Do display intialization Comm_Manager.pTrain_Display->APP_DISP_init();
os_sys_init(init_task); /* init and start with task 'INIT' */ }
D'Oh, parameter order is incorrect on os_mbx_send. Hmmm, compiler was not warning.
Ben
And why would it?
The compiler knows nothing about the meaning of the parameters - all it knows is whether the types are "compatible" within the rules of the 'C' programming language...!
Depends on the implementation of the compiler, some are more strict than others as to what types are automatically promoted/cast/demoted. Some have configurable rules.
The function prototype is:
OS_RESULT os_mbx_send( OS_ID mailbox, void* message_ptr, U16 timeout );
http://www.keil.com/support/man/docs/rlarm/rlarm_os_mbx_send.htm
So the only checks that the compiler can do are: 1. The first actual parameter has a type compatible with the type OS_ID; 2. The second actual parameter has a type compatible with the type void*; 3. The third actual parameter has a type compatible with the type U16.
Unfortunatly Object_Message is not of type OS_ID, but OS_ID is typedef void *, so I can see why that is happening.
The whole point of void* is that it's compatible with anything!
Close, but not quite worthy of a cigar.
void * is compatible with any data pointer. You should still get a warning if you mix it with integers and function pointers, and an error if you mix it with floats or structs.
Just as well that I don't smoke, then...!