Mailbox Library
How to send data from one task to another? Mailbox brings one solution.
|
The mailbox is defined by two parameters:
Contrary to the Queue element that stores pointers, the Mailbox element copies and stores the messages inside. This provides a safe and clean way for sending data from one task to another. The Mailbox element runs shares the same logic and same limitation with the Event element. The Mailbox element can have multiple senders but only one receiver. |
// myMessage type for mailbox typedef struct myMessage_t { uint32_t chrono; char buffer[10]; }; // Number of messages on the mailbox #define NUMBER 4 // Mailbox post modality: either BIOS_WAIT_FOREVER or BIOS_NO_WAIT. #define MODALITY BIOS_WAIT_FOREVER // myMailbox Mailbox<myMessage_t> myMailbox; // mySemaphore Semaphore mySemaphore; |
The first sender includes a setup() function to initialise the Serial port and the mailbox myMailBox. Here, the mailbox is set to NUMBER = 4 slots.
The two senders share the same code for the loop() function. Depending on the MODALITY value,
The option BIOS_NO_WAIT allows the post() process to be non-blocking, but the returned value should be tested. Compare the two options below. |
void MailboxSender1_setup() { Serial.begin(115200); myMailbox.begin(NUMBER); // default = 16 } void MailboxSender1_loop() { messageS.chrono = millis(); strcpy(messageS.buffer, "from 1"); // Mailbox post modality: either BIOS_WAIT_FOREVER or BIOS_NO_WAIT. bool result = myMailbox.post(messageS, MODALITY); delay(300); } |
? Chrono Action Message Available Result ? .chrono .buffer 1> 6 TX 6 from 1 1 1 *< 100 RX 6 from 1 1 2> 102 TX 100 from 2 1 1 2> 304 TX 304 from 2 2 1 *< 402 RX 100 from 2 1 2> 506 TX 506 from 2 2 1 1> 508 TX 508 from 1 3 1 *< 704 RX 304 from 2 2 2> 708 TX 708 from 2 3 1 2> 910 TX 910 from 2 4 1 *< 1006 RX 506 from 2 3 1> 1010 TX 1010 from 1 4 1 *< 1308 RX 508 from 1 4 2> 1310 TX 1112 from 2 4 1 *< 1610 RX 708 from 2 4 1> 1612 TX 1512 from 1 4 1 *< 1912 RX 910 from 2 4 2> 1914 TX 1513 from 2 4 1 *< 2214 RX 1010 from 1 4 1> 2216 TX 2115 from 1 4 1 *< 2516 RX 1112 from 2 4 2> 2518 TX 211 from 2 4 1 |
? Chrono Action Message Available Result ? .chrono .buffer 1> 6 TX 6 from 1 1 1 *< 100 RX 6 from 1 1 1 2> 102 TX 100 from 2 1 1 2> 304 TX 304 from 2 2 1 *< 402 RX 100 from 2 1 1 2> 506 TX 506 from 2 2 1 1> 508 TX 508 from 1 3 1 *< 704 RX 304 from 2 2 1 2> 708 TX 708 from 2 3 1 2> 910 TX 910 from 2 4 1 *< 1006 RX 506 from 2 3 0 <= not posted 1> 1010 TX 1010 from 1 4 1 2> 1112 TX 1112 from 2 4 0 <= not posted *< 1308 RX 508 from 1 3 0 <= not posted 2> 1314 TX 1314 from 2 4 1 1> 1512 TX 1512 from 1 4 0 <= not posted 2> 1516 TX 1516 from 2 4 0 <= not posted *< 1610 RX 708 from 2 3 2> 1718 TX 1718 from 2 4 1 |
The client loop waits for a message to be available, and prints it to the Serial port.
The available() function returns the number of messages on the mailbox to be read. 0 means the mailbox is empty. |
void MailboxClient_loop() { myMailbox.waitFor(messageR);
mySemaphore.waitFor(); Serial.print("*<\t"); Serial.print(millis(), DEC); Serial.print("\tRX\t"); Serial.print(messageB.chrono, DEC); Serial.print("\t"); Serial.print(messageB.buffer); Serial.print("\t"); Serial.print(myMailbox.available()); Serial.println("\t:\t"); mySemaphore.post();
delay(300); } |