@@ -50,20 +50,17 @@ allowing both threads to know what has occurred.
5050
5151A mailbox message contains zero or more bytes of **message data **.
5252The size and format of the message data is application-defined, and can vary
53- from one message to the next. There are two forms of message data:
53+ from one message to the next.
5454
55- * A **message buffer ** is an area of memory provided by the thread
56- that sends or receives the message. An array or structure variable
57- can often be used for this purpose.
55+ A **message buffer ** is an area of memory provided by the thread that sends or
56+ receives the message data . An array or structure variable can often be used for
57+ this purpose.
5858
59- * A **message block ** is an area of memory allocated from a memory pool.
60-
61- A message may *not * have both a message buffer and a message block.
6259A message that has neither form of message data is called an **empty message **.
6360
6461.. note ::
65- A message whose message buffer or memory block exists, but contains
66- zero bytes of actual data, is *not * an empty message.
62+ A message whose message buffer exists, but contains zero bytes of actual
63+ data, is *not * an empty message.
6764
6865Message Lifecycle
6966=================
@@ -154,21 +151,15 @@ internal mailbox use only.
154151
155152*size *
156153 The message data size, in bytes. Set it to zero when sending an empty
157- message, or when sending a message buffer or message block with no
158- actual data. When receiving a message, set it to the maximum amount
159- of data desired, or to zero if the message data is not wanted.
160- The mailbox updates this field with the actual number of data bytes
161- exchanged once the message is received.
154+ message, or when sending a message buffer with no actual data. When
155+ receiving a message, set it to the maximum amount of data desired, or to
156+ zero if the message data is not wanted. The mailbox updates this field with
157+ the actual number of data bytes exchanged once the message is received.
162158
163159*tx_data *
164160 A pointer to the sending thread's message buffer. Set it to ``NULL ``
165- when sending a memory block, or when sending an empty message.
166- Leave this field uninitialized when receiving a message.
167-
168- *tx_block *
169- The descriptor for the sending thread's memory block. Set tx_block.data
170- to ``NULL `` when sending an empty message. Leave this field
171- uninitialized when sending a message buffer, or when receiving a message.
161+ when sending an empty message. Leave this field uninitialized when
162+ receiving a message.
172163
173164*tx_target_thread *
174165 The address of the desired receiving thread. Set it to :c:macro: `K_ANY `
@@ -187,9 +178,6 @@ Sending a Message
187178=================
188179
189180A thread sends a message by first creating its message data, if any.
190- A message buffer is typically used when the data volume is small,
191- and the cost of copying the data is less than the cost of allocating
192- and freeing a message block.
193181
194182Next, the sending thread creates a message descriptor that characterizes
195183the message to be sent, as described in the previous section.
@@ -312,52 +300,6 @@ the maximum size message buffer that each thread can handle.
312300 }
313301 }
314302
315- Sending Data Using a Message Block
316- ----------------------------------
317-
318- This code uses a mailbox to send asynchronous messages. A semaphore is used
319- to hold off the sending of a new message until the previous message
320- has been consumed, so that a backlog of messages doesn't build up
321- when the consuming thread is unable to keep up.
322-
323- The message data is stored in a memory block obtained from a memory pool,
324- thereby eliminating unneeded data copying when exchanging large messages.
325- The memory pool contains only two blocks: one block gets filled with
326- data while the previously sent block is being processed
327-
328- .. code-block :: c
329-
330- /* define a semaphore, indicating that no message has been sent */
331- K_SEM_DEFINE(my_sem, 1, 1);
332-
333- /* define a memory pool containing 2 blocks of 4096 bytes */
334- K_MEM_POOL_DEFINE(my_pool, 4096, 4096, 2, 4);
335-
336- void producer_thread(void)
337- {
338- struct k_mbox_msg send_msg;
339-
340- volatile char *hw_buffer;
341-
342- while (1) {
343- /* allocate a memory block to hold the message data */
344- k_mem_pool_alloc(&my_pool, &send_msg.tx_block, 4096, K_FOREVER);
345-
346- /* keep overwriting the hardware-generated data in the block */
347- /* until the previous message has been received by the consumer */
348- do {
349- memcpy(send_msg.tx_block.data, hw_buffer, 4096);
350- } while (k_sem_take(&my_sem, K_NO_WAIT) != 0);
351-
352- /* finish preparing to send message */
353- send_msg.size = 4096;
354- send_msg.tx_target_thread = K_ANY;
355-
356- /* send message containing most current data and loop around */
357- k_mbox_async_put(&my_mailbox, &send_msg, &my_sem);
358- }
359- }
360-
361303 Receiving a Message
362304===================
363305
@@ -390,10 +332,7 @@ The receiving thread controls both the quantity of data it retrieves from an
390332incoming message and where the data ends up. The thread may choose to take
391333all of the data in the message, to take only the initial part of the data,
392334or to take no data at all. Similarly, the thread may choose to have the data
393- copied into a message buffer of its choice or to have it placed in a message
394- block. A message buffer is typically used when the volume of data
395- involved is small, and the cost of copying the data is less than the cost
396- of allocating and freeing a memory pool block.
335+ copied into a message buffer of its choice.
397336
398337The following sections outline various approaches a receiving thread may use
399338when retrieving message data.
@@ -416,14 +355,6 @@ message descriptor to indicate how many data bytes were copied (if any).
416355The immediate data retrieval technique is best suited for small messages
417356where the maximum size of a message is known in advance.
418357
419- .. note ::
420- This technique can be used when the message data is actually located
421- in a memory block supplied by the sending thread. The mailbox copies
422- the data into the message buffer specified by the receiving thread, then
423- frees the message block back to its memory pool. This allows
424- a receiving thread to retrieve message data without having to know
425- whether the data was sent using a message buffer or a message block.
426-
427358The following code uses a mailbox to process variable-sized requests from any
428359producing thread, using the immediate data retrieval technique. The message
429360"info" field is used to exchange information about the maximum size
@@ -501,14 +432,6 @@ used when memory limitations make it impractical for the receiving thread to
501432always supply a message buffer capable of holding the largest possible
502433incoming message.
503434
504- .. note ::
505- This technique can be used when the message data is actually located
506- in a memory block supplied by the sending thread. The mailbox copies
507- the data into the message buffer specified by the receiving thread, then
508- frees the message block back to its memory pool. This allows
509- a receiving thread to retrieve message data without having to know
510- whether the data was sent using a message buffer or a message block.
511-
512435The following code uses a mailbox's deferred data retrieval mechanism
513436to get message data from a producing thread only if the message meets
514437certain criteria, thereby eliminating unneeded data copying. The message
@@ -543,81 +466,6 @@ certain criteria, thereby eliminating unneeded data copying. The message
543466 }
544467 }
545468
546- Retrieving Data Later Using a Message Block
547- -------------------------------------------
548-
549- A receiving thread may choose to retrieve message data into a memory block,
550- rather than a message buffer. This is done in much the same way as retrieving
551- data subsequently into a message buffer --- the receiving thread first
552- receives the message without its data, then retrieves the data by calling
553- :c:func: `k_mbox_data_block_get `. The mailbox fills in the block descriptor
554- supplied by the receiving thread, allowing the thread to access the data.
555- The mailbox also deletes the received message, since data retrieval
556- has been completed. The receiving thread is then responsible for freeing
557- the message block back to the memory pool when the data is no longer needed.
558-
559- This technique is best suited for applications where the message data has
560- been sent using a memory block.
561-
562- .. note ::
563- This technique can be used when the message data is located in a message
564- buffer supplied by the sending thread. The mailbox automatically allocates
565- a memory block and copies the message data into it. However, this is much
566- less efficient than simply retrieving the data into a message buffer
567- supplied by the receiving thread. In addition, the receiving thread
568- must be designed to handle cases where the data retrieval operation fails
569- because the mailbox cannot allocate a suitable message block from the memory
570- pool. If such cases are possible, the receiving thread must either try
571- retrieving the data at a later time or instruct the mailbox to delete
572- the message without retrieving the data.
573-
574- The following code uses a mailbox to receive messages sent using a memory block,
575- thereby eliminating unneeded data copying when processing a large message.
576- (The messages may be sent synchronously or asynchronously.)
577-
578- .. code-block :: c
579-
580- /* define a memory pool containing 1 block of 10000 bytes */
581- K_MEM_POOL_DEFINE(my_pool, 10000, 10000, 1, 4);
582-
583- void consumer_thread(void)
584- {
585- struct k_mbox_msg recv_msg;
586- struct k_mem_block recv_block;
587-
588- int total;
589- char *data_ptr;
590- int i;
591-
592- while (1) {
593- /* prepare to receive message */
594- recv_msg.size = 10000;
595- recv_msg.rx_source_thread = K_ANY;
596-
597- /* get message, but not its data */
598- k_mbox_get(&my_mailbox, &recv_msg, NULL, K_FOREVER);
599-
600- /* get message data as a memory block and discard message */
601- k_mbox_data_block_get(&recv_msg, &my_pool, &recv_block, K_FOREVER);
602-
603- /* compute sum of all message bytes in memory block */
604- total = 0;
605- data_ptr = (char *)(recv_block.data);
606- for (i = 0; i < recv_msg.size; i++) {
607- total += data_ptr++;
608- }
609-
610- /* release memory block containing data */
611- k_mem_pool_free(&recv_block);
612- }
613- }
614-
615- .. note ::
616- An incoming message that was sent using a message buffer is also processed
617- correctly by this algorithm, since the mailbox automatically allocates
618- a memory block from the memory pool and fills it with the message data.
619- However, the performance benefit of using the memory block approach is lost.
620-
621469 Suggested Uses
622470**************
623471
0 commit comments