RISCV Mailbox Usage Reference
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | Initial release | 08/18/2025 |
1. Overview¶
This module can be referred to as a mailbox, but a mailbox is also a set of registers accessible by multiple cores on-chip. By combining these registers with shared memory, inter-core communication can be implemented. Here, it is used for communication between U-Boot and FreeRTOS.
2. Keyword Explanation¶
-
mailbox/mbx
mbx is the abbreviation of mailbox, specifically referring to a group of registers accessible by multiple cores on the chip, and more broadly referring to this functional module.
-
uboot
The Linux bootloader, running before Linux starts.
3. Function Description¶
This module is used for simple communication between U-Boot and FreeRTOS. Since sending and receiving do not have contention protection, sending or receiving cannot occur simultaneously in multiple parallel tasks. This function is half-duplex, meaning that sending and receiving cannot occur at the same time; when one side is sending, the other cannot send. Without channel contention protection, only one side can be active, meaning that only one side can actively send, while the other side can only passively respond after receiving a message.
3.1. Principle¶
At initialization, the two communicating parties establish a block of shared memory through the mailbox registers. Then, two mailbox registers are used: one to report the message length from ARM to RISC-V; when this mailbox has a non-zero value of length, it indicates that there is a message of length length from ARM to RISC-V in the shared memory. The other mailbox reports the message length from RISC-V to ARM; when this mailbox has a non-zero value of length, it indicates that there is a message of length length from RISC-V to ARM in the shared memory.
Since there is only one block of shared memory, this function is half-duplex, meaning that sending and receiving cannot occur simultaneously.
The U-Boot part of the code is located at:
Alkaid/boot/drivers/sstar/riscv/drv_riscv.c
The FreeRTOS part of the code is located at:
Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/src/mbx_msg.c
3.2. Initialization¶
Initialization is primarily used for both parties to establish a block of shared memory and indicate that both sides are ready through a final handshake.

3.3. Reception¶
Taking RISC-V as an example, the process is as follows:

3.4. Sending¶
Taking RISC-V as an example, the process is as follows:
Since it is half-duplex, you must ensure that reception has been completed before sending.

3.5. Channel Contention Protection¶
On a single end, since there is no contention protection for sending and receiving, neither sending nor receiving supports multi-tasking. On both ends, since it is half-duplex and there is no contention mechanism for the channel, for example, if RISC-V checks MBX_ARM_TO_RISCV and confirms it is 0 while ARM is concurrently sending, and just has completed the copy but has not yet written to MBX_ARM_TO_RISCV, the data written by the ARM side may be overwritten. To prevent such situations, there can only be one active side in communication; that is, only one side can actively send messages while the other can only passively reply after receiving a message.
4. Mailbox Demo¶
4.1. Demo Overview¶
The demo consists of two parts: one is the U-Boot app and the other is the app under FreeRTOS. The two apps communicate using the mailbox.
In this demo, the user manually sends messages from the U-Boot side to the FreeRTOS side. After receiving the message, the FreeRTOS side adds ": id" to the end and sends it back, where id is a counter that increments by 1 with each communication.
4.2. U-Boot App¶
The following configuration needs to be enabled on U-Boot:
CONFIG_SSTAR_RISCV=y
This can be configured using make menuconfig.

The demo code is located at:
Alkaid/boot/cmd/sstar/riscv.c
4.3. FreeRTOS App¶
In FreeRTOS, it is enabled by default, and the code is located at:
Alkaid/riscv/kernel/rtk/proj/sc/application/uboot_app/src/uboot_app.c
The result is as follows:

5. API Reference¶
5.1. U-Boot API Reference¶
This section introduces the APIs and data on U-Boot.
| API Name | Function |
|---|---|
| drv_riscv_init | Module initialization. |
| drv_riscv_deinit | Module de-initialization. |
| drv_riscv_poll | Poll for pending data or readiness to send. |
| drv_riscv_send | Send data. |
| drv_riscv_recv | Receive data. |
5.1.1. drv_riscv_init¶
-
Function
Module initialization.
-
Syntax
int drv_riscv_init(void);
-
Parameters
Parameter Name Parameter Meaning Input/Output None None None -
Return Value
Return Value Description 0 Initialization successful -1 Initialization failed -
Dependencies
-
Header file: Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
Library files
-
5.1.2. drv_riscv_deinit¶
-
Function
Module de-initialization.
-
Syntax
int drv_riscv_deinit(void);
-
Parameters
Parameter Name Parameter Meaning Input/Output None None None -
Return Value
Return Value Description 0 De-initialization successful -
Dependencies
-
Header file: Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
Library files
-
5.1.3. drv_riscv_poll¶
-
Function
Poll for pending data or readiness to send.
-
Syntax
int drv_riscv_poll(int flag);
-
Parameters
Parameter Name Parameter Meaning Input/Output flag Must be either DRV_RISCV_POLLIN or DRV_RISCV_POLLOUT. DRV_RISCV_POLLIN indicates to check for pending data to receive, while DRV_RISCV_POLLOUT indicates to check if it is ready to send. Input -
Return Value
Return Value Description 0 When polling for receive, indicates there is no data to receive; when polling for send, indicates it is not ready to send. -1 Returns this value if the input parameter is neither DRV_RISCV_POLLIN nor DRV_RISCV_POLLOUT. Other values When polling for receive, indicates the length of pending data; when polling for send, indicates readiness to send. -
Dependencies
-
Header file: Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
Library files
-
-
Example
See 4.2
5.1.4. drv_riscv_send¶
-
Function
Send data.
-
Syntax
int drv_riscv_send(const char *msg, int len);
-
Parameters
Parameter Name Parameter Meaning Input/Output msg Pointer to the head of the data block to be sent. Input len Length of the data block to be sent (in bytes). Input -
Return Value
Return Value Description 0 Send successful. -1 Send failed. -
Dependencies
-
Header file: Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
Library files
-
-
Note
- Before sending, first query with drv_riscv_poll(DRV_RISCV_POLLOUT) until a non-zero return value is obtained, indicating it can be sent.
-
Example
See 4.2
5.1.5. drv_riscv_recv¶
-
Function
Receive data.
-
Syntax
int drv_riscv_recv(char *msg, int len);
-
Parameters
Parameter Name Parameter Meaning Input/Output msg Pointer to the receive buffer. Input len Length of the receive buffer (in bytes). Input -
Return Value
Return Value Description >= 0 Length of the received data. -
Dependencies
-
Header file: Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
Library files
-
-
Note
- Before receiving, first query with drv_riscv_poll(DRV_RISCV_POLLIN) until a non-zero return value indicates that data is available for receiving.
-
Related Topics
None
5.2. FreeRTOS API Reference¶
This section introduces the API on FreeRTOS.
| API Name | Function |
|---|---|
| drv_mbx_msg_init | Module initialization. |
| drv_mbx_msg_deinit | Module de-initialization. |
| drv_mbx_msg_poll | Query if it can send or if data is available to receive. |
| drv_mbx_msg_send | Send data. |
| drv_mbx_msg_recv | Receive data. |
5.2.1. drv_mbx_msg_init¶
-
Function
Module initialization.
-
Syntax
int drv_mbx_msg_init(void);
-
Parameters
Parameter Name Parameter Meaning Input/Output None None None -
Return Value
Return Value Description 0 Success -
Dependencies
-
Header file: Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
Library files
-
5.2.2. drv_mbx_msg_deinit¶
-
Function
De-initialization.
-
Syntax
int drv_mbx_msg_deinit(void);
-
Parameters
Parameter Name Parameter Meaning Input/Output None None None -
Return Value
Return Value Description 0 Success -
Dependencies
-
Header file: Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
Library files
-
5.2.3. drv_mbx_msg_poll¶
-
Function
Query if it can send or if data is available to receive.
-
Syntax
int drv_mbx_msg_poll(int flag);
-
Parameters
Parameter Name Parameter Meaning Input/Output flag Must be either DRV_MBX_MSG_POLLIN or DRV_MBX_MSG_POLLOUT. DRV_MBX_MSG_POLLIN indicates to query for pending data, while DRV_MBX_MSG_POLLOUT indicates to query if it is ready to send. Input -
Return Value
Return Value Description 0 Indicates no data is available when polling for receive, cannot send when polling for send, and returns this value if the input parameter is neither DRV_MBX_MSG_POLLIN nor DRV_MBX_MSG_POLLOUT. Other values Indicates the length of pending data when polling for receive, indicates readiness to send when polling for send. -
Dependencies
-
Header file: Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
Library files
-
5.2.4. drv_mbx_msg_send¶
-
Function
Send data.
-
Syntax
int drv_mbx_msg_send(const char *msg, int len);
-
Parameters
Parameter Name Parameter Meaning Input/Output msg Pointer to the head of the data block to be sent. Input len Length of the data block to be sent (in bytes). Input -
Return Value
Return Value Description 0 Send successful. -1 Send failed. -
Dependencies
-
Header file: Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
Library files
-
-
Note
- Before sending, use drv_mbx_msg_poll(DRV_MBX_MSG_POLLIN) to confirm there is no pending data before proceeding with drv_mbx_msg_poll(DRV_MBX_MSG_POLLOUT) confirmation for readiness to send.
5.2.5. drv_mbx_msg_recv¶
-
Function
Receive data.
-
Syntax
int drv_mbx_msg_recv(char *msg, int len);
-
Parameters
Parameter Name Parameter Meaning Input/Output msg Pointer to the receive buffer. Input len Length of the receive buffer (in bytes). Input -
Return Value
Return Value Description >= 0 Length of the received data. -
Dependencies
-
Header file: Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
Library files
-
-
Note
- Before receiving, confirm with drv_mbx_msg_poll(DRV_MBX_MSG_POLLIN) to ensure data is available for receiving.
6. FAQ¶
N/A