Hi,
I am using RL-ARM 4.01 on a STMicro Cortex-M3 (uVision V4.00a), and having some trouble with mailboxes. The key issue is that _free_box is failing (have verified this in debug), and as a result I run out of memory in the memory pool very quickly.
I have looked through the docs for gotchas about this, and double-checked that the memory pool is byte-aligned (I am using os_mbx_declare and _declare_box to set things up), and also have made sure that I am attempting to free the message from the same memory pool from which it was allocated.
But when I check the return value of _free_box, it is returning non-zero every time, indicating that it has failed. Has anyone seen this, or have an idea of what might be going on?
thanks, -David Merrill
Verify that the pointer that is being passed into _free_box is actually within the membox.
yes, I have checked to make sure that the pointer to the message is within the memory bounds of the pool.. the message format is:
typedef struct { t_command command; // is a uint8_t uint8_t address; uint8_t length; uint8_t payload[29]; } t_Message_mailbox;
Note that the struct is 32 bytes long, though I'm not sure how the byte-alignment is working out -- anyone know if this struct is actually taking up more than 32 bytes?
To initialize the mailboxes, I have the following 2 declarations at the top of my code (macros):
os_mbx_declare(Outbox_mailbox, 16); _declare_box(Outbox_mpool,sizeof(t_Message_mailbox),16);
Then these are happening before use:
_init_box(Outbox_mpool,sizeof(Outbox_mpool),sizeof(t_Message_mailbox)); os_mbx_init(Outbox_mailbox,sizeof(Outbox_mailbox));
The memory pool begins at: 0x20006BC4, and the first message allocated with _alloc_box is at address 0x20006BF0 (44 bytes in).
The message that the code is retrieving from the mailbox with the following line of code is the same one as the code stuck into the mailbox. Retrieval is with the following code (this is the call to _free_box that is failing):
rv = os_mbx_wait(Outbox_mailbox, (void **)&outboxMsgPtr, 0xffff); ProcessMessage(outboxMsgPtr); if (_free_box(Outbox_mpool,outboxMsgPtr)) { // @todo error here }
..and for completeness, the code that sticks the message into the mailbox is the following:
entries = os_mbx_check(Outbox_mailbox); if (entries > 0) { mptr = _alloc_box(Outbox_mpool); mptr->command = (t_command)this_cmd; mptr->length = 4; mptr->payload[0] = recentPacketIDX >> 24; mptr->payload[1] = recentPacketIDX >> 16; mptr->payload[2] = recentPacketIDX >> 8; mptr->payload[3] = recentPacketIDX; os_mbx_send(Outbox_mailbox,mptr,0xFFFF); } else { // @todo: error here, mailbox was full! }
So basically I'm stumped. As far as I can tell I'm declaring and initializing the mailboxes correctly, sticking messages in and getting them out correctly, and calling _free_box on the right thing. Anyone have thoughts on why _free_box would be failing?
thanks in advance.
I got it working, though I don't totally understand the solution. Turns out the way I was extern-ing the mailbox and memory pool into my various libraries was incorrect in some way. I had previously been putting the following at the top of my files:
extern OS_MBX Outbox_mailbox; extern void * Outbox_mpool;
...but when I changed this to the following, it started working properly:
extern OS_MBX Outbox_mailbox; extern u32 Outbox_mpool[];
I'm considering the case closed with respect to debugging, but I am curious why the first declaration messed things up, while the new one works.
thanks, -David
I had previously been putting the following at the top of my files:
Therein lies a considerable problem. You should only ever be adding a declaration to one file: the header file exporting the interface of the C file defining the things in question. As a rule of thumb you should never put 'extern' in a *.c file, nor 'static' in a header file.
Among the things this avoids is a conflict between the actual definition of a variable (or function) in one module and the declarations seen in the others; which has a considerable probability of causing just the kind of problem you've been discussing here. So don't do that.
View all questions in Keil forum