Passes variable-length messages from a kernel service into an app-provided buffer.
More...
Passes variable-length messages from a kernel service into an app-provided buffer.
Design goals:
- Data is written directly into a buffer in app space, as contiguous messages (no wrap-around) so they are easy to parse.
- A message can be written while earlier messages are still pending in the buffer.
- A partially written message can be cancelled and is then never delivered.
- No race can make the app read an incomplete message.
- The app is told how many messages were dropped for lack of space.
Non-goals: sharing a buffer between kernel services (one buffer per service tag), concurrent writers (a write fails up front while another task is writing), and preserving the order of dropped messages relative to received ones.
The kernel writes a message with app_inbox_service_begin(), any number of app_inbox_service_write() calls and app_inbox_service_end(). A callback event is then posted to the registering task, where the message and dropped handlers run.
}
bool app_inbox_service_begin(AppInboxServiceTag tag, size_t required_free_length, void *writer)
Start writing a message.
bool app_inbox_service_end(AppInboxServiceTag tag)
Finish the message being written and notify the app.
bool app_inbox_service_write(AppInboxServiceTag tag, const uint8_t *data, size_t length)
Append data to the message being written.
@ AppInboxServiceTagAppMessageReceiver
App message receiver.
Definition app_inbox_service.h:48
◆ AppInboxMessageHeader
| struct AppInboxMessageHeader |
Header preceding each message in the inbox buffer.
| Data Fields |
|
uint8_t |
data[] |
Message payload. |
|
size_t |
length |
Length of data, excluding this header. |
|
uint8_t |
padding[4] |
Reserved. The header lives in a buffer sized by the app, so it cannot grow once shipped.
|
◆ AppInboxServiceTag
Identifies an inbox and the permitted message and dropped handlers for it.
| Enumerator |
|---|
| AppInboxServiceTagInvalid | Invalid tag.
|
| AppInboxServiceTagAppMessageReceiver | App message receiver.
|
| NumAppInboxServiceTag | Number of tags.
|
◆ app_inbox_service_begin()
| bool app_inbox_service_begin |
( |
AppInboxServiceTag |
tag, |
|
|
size_t |
required_free_length, |
|
|
void * |
writer |
|
) |
| |
Start writing a message.
If this returns true, app_inbox_service_end() or app_inbox_service_cancel() must be called eventually. If it returns false, none of app_inbox_service_write(), app_inbox_service_end() and app_inbox_service_cancel() may be called; the message counts as dropped.
- Parameters
-
| tag | Inbox to write to. |
| required_free_length | Length of the message payload, excluding the header. The buffer needs this plus sizeof(AppInboxMessageHeader) bytes free. |
| writer | Non-NULL reference to the writer, for debugging. |
- Returns
- true if the inbox was claimed, false if it does not exist, is being written by another writer or has not enough space.
◆ app_inbox_service_cancel()
Abort the message being written without delivering it.
- Parameters
-
◆ app_inbox_service_end()
Finish the message being written and notify the app.
- Parameters
-
- Returns
- true if the whole message was written and delivered, false if it was dropped, in which case the dropped handler is called.
◆ app_inbox_service_init()
| void app_inbox_service_init |
( |
void |
| ) |
|
Initialize the service, once at boot.
◆ app_inbox_service_register()
| bool app_inbox_service_register |
( |
uint8_t * |
storage, |
|
|
size_t |
storage_size, |
|
|
AppInboxMessageHandler |
message_handler, |
|
|
AppInboxDroppedHandler |
dropped_handler, |
|
|
AppInboxServiceTag |
tag |
|
) |
| |
Register an inbox.
The handlers run on the calling task. Fails if an inbox already exists for tag or storage. Apps call this through app_inbox_create_and_register().
- Parameters
-
| storage | Buffer in app space that receives the messages. |
| storage_size | Size of storage in bytes. Each message also takes sizeof(AppInboxMessageHeader) bytes. |
| message_handler | Called for each received message. |
| dropped_handler | Called when one or more messages were dropped. |
| tag | Tag identifying the inbox. |
- Returns
- true on success, false on error or out of memory.
◆ app_inbox_service_unregister_all()
| void app_inbox_service_unregister_all |
( |
void |
| ) |
|
◆ app_inbox_service_unregister_by_storage()
| uint32_t app_inbox_service_unregister_by_storage |
( |
uint8_t * |
storage | ) |
|
Unregister the inbox using storage.
Apps call this through app_inbox_destroy_and_deregister().
- Parameters
-
- Returns
- Number of messages dropped or still waiting to be consumed, including one being written.
◆ app_inbox_service_write()
| bool app_inbox_service_write |
( |
AppInboxServiceTag |
tag, |
|
|
const uint8_t * |
data, |
|
|
size_t |
length |
|
) |
| |
Append data to the message being written.
After a failed write, further writes fail too and app_inbox_service_end() reports the message as dropped instead of delivering it.
- Parameters
-
| tag | Inbox being written. |
| data | Data to append. |
| length | Length of data in bytes. |
- Returns
- true if the data was written.