RISCV_mailbox使用参考
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 1.0 | Initial release | 08/18/2025 |
1. 概述¶
这个模块可以称为mailbox,但是mailbox也是一组片上的多个核心都可以访问到的寄存器,通过结合这些寄存器与共享内存,可用实现核间通信。在这里,用于uboot和FreeRTOS的通信。
2. 关键字说明¶
-
mailbox/mbx
mbx是mailbox的缩写,狭义上特指芯片上一组多个核心都可以访问到的寄存器,广义上也指这个功能模块。
-
uboot
linux的引导程序,运行在linux启动之前。
3. 功能描述¶
本模块用于uboot与FreeRTOS的简单通信。由于发送和接收都没有竞争保护,不能在多个并行任务中同时进行发送或接收。这个功能是单工的,接收和发送无法同时进行,一端在发送时,另一端无法发送。由于没有信道的竞争保护,通信的双方只能有一个主动端,即只有一端可以主动发送,另一端只能被动地在收到消息后回复。
3.1. 原理¶
在初始化时,先通过mailbox寄存器,通信双方确立一块共享内存,然后使用两个mailbox寄存器,一个用于通报arm to riscv的消息长度,当这个mailbox有非零值length时,表示共享内存里面有length长度的arm to riscv消息,另一个用于通报riscv to arm的消息长度,当这个mailbox有非零值length时,表示共享内存里面有length长度的riscv to arm消息。
由于共享内存只有一块,所以这个功能是单工的,发送和接收无法同时进行。
uboot部分的代码位于
Alkaid/boot/drivers/sstar/riscv/drv_riscv.c
FreeRTOS部分的代码位于
Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/src/mbx_msg.c
3.2. 初始化¶
初始化主要用于双方确立一块共享内存,并通过最后的握手表示双方都已经就绪。

3.3. 接收¶
以riscv为例,流程如下

3.4. 发送¶
以riscv为例,流程如下
由于是单工的,发送时要先确保接收已经完成

3.5. 信道的竞争保护¶
在单端上,由于发送和接收都没有竞争保护,所以发送和接收都不支持多任务。在双端上,由于是单工的,且双方没有对信道的竞争机制,比如riscv发送时查询完MBX_ARM_TO_RISCV,确认其为0,但有可能arm同时在发送,且正好拷贝完成,只是还没写入MBX_ARM_TO_RISCV,就会导致arm端写入的数据被覆盖。为了防止这种情况的发生,通信的双方只能有一个主动端,即只有一方可以主动发送消息,另一方只能被动地在接收到消息后进行回复。
4. Mailbox Demo¶
4.1. Demo简介¶
Demo由两部分组成,一个是uboot app,一个是FreeRTOS下的app,两个app间使用mailbox进行通信。
在这个demo里,用户在uboot端手动发送消息到FreeRTOS端,FreeRTOS端收到消息后在尾部加上": id"再发送回来,其中id是一个计数,每次通信+1。
4.2. uboot app¶
uboot上需要打开如下配置
CONFIG_SSTAR_RISCV=y
可以通过make menuconfig配置

demo代码位于
Alkaid/boot/cmd/sstar/riscv.c
4.3. FreeRTOS app¶
FreeRTOS下默认是打开的,代码位于
Alkaid/riscv/kernel/rtk/proj/sc/application/uboot_app/src/uboot_app.c
运行结果如下

5. API参考¶
5.1. uboot API参考¶
本章介绍uboot上的api和数据。
| API名称 | 功能 |
|---|---|
| drv_riscv_init | 模块初始化。 |
| drv_riscv_deinit | 模块反初始化。 |
| drv_riscv_poll | 查询是否有待接收的数据或者是否空闲可以发送。 |
| drv_riscv_send | 发送数据。 |
| drv_riscv_recv | 接收数据。 |
5.1.1. drv_riscv_init¶
-
功能
模块初始化。
-
语法
int drv_riscv_init(void);
-
形参
参数名称 参数含义 输入/输出 无 无 无 -
返回值
返回值 描述 0 初始化成功 -1 初始化失败 -
依赖
-
头文件:Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
库文件
-
5.1.2. drv_riscv_deinit¶
-
功能
模块反初始化。
-
语法
int drv_riscv_deinit(void);
-
形参
参数名称 参数含义 输入/输出 无 无 无 -
返回值
返回值 描述 0 反初始化成功 -
依赖
-
头文件:Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
库文件
-
5.1.3. drv_riscv_poll¶
-
功能
查询是否有待接收的数据或者是否空闲可以发送。
-
语法
int drv_riscv_poll(int flag);
-
形参
参数名称 参数含义 输入/输出 flag 只能是DRV_RISCV_POLLIN或者DRV_RISCV_POLLOUT。DRV_RISCV_POLLIN表示查询是否有待接收的数据,DRV_RISCV_POLLOUT表示查询是否可以发送 输入 -
返回值
返回值 描述 0 查询接收时表示没有数据可以接收,查询发送时表示不可以发送 -1 入参既不是DRV_RISCV_POLLIN也不是DRV_RISCV_POLLOUT时返回这个值 其他值 查询接收时表示待接收的数据长度,查询发送时表示可以发送 -
依赖
-
头文件:Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
库文件
-
-
举例
见4.2
5.1.4. drv_riscv_send¶
-
功能
发送数据。
-
语法
int drv_riscv_send(const char *msg, int len);
-
形参
参数名称 参数含义 输入/输出 msg 要发送的数据块头指针。 输入 len 要发送的数据块长度(字节)。 输入 -
返回值
返回值 描述 0 发送成功 -1 发送失败 -
依赖
-
头文件:Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
库文件
-
-
注意
- 发送之前需要先用drv_riscv_poll(DRV_RISCV_POLLOUT)查询直到返回值非0,才可以发送。
-
举例
见4.2
5.1.5. drv_riscv_recv¶
-
功能
接收数据。
-
语法
int drv_riscv_recv(char *msg, int len);
-
形参
参数名称 参数含义 输入/输出 msg 接收缓冲区指针。 输入 len 接收缓冲区长度(字节)。 输入 -
返回值
返回值 描述 >= 0 接收到的数据长度 -
依赖
-
头文件:Alkaid/boot/drivers/sstar/riscv/drv_riscv.h
-
库文件
-
-
注意
- 接收之前需要先用drv_riscv_poll(DRV_RISCV_POLLIN)查询直到返回值非0,表示才有数据可以接收。
-
举例
见4.2
-
相关主题
无
5.2. FreeRTOS API参考¶
本章介绍FreeRTOS上的API
| API名 | 功能 |
|---|---|
| drv_mbx_msg_init | 模块初始化。 |
| drv_mbx_msg_deinit | 模块反初始化。 |
| drv_mbx_msg_poll | 查询是否可以发送或者是否有数据可以接收。 |
| drv_mbx_msg_send | 发送数据。 |
| drv_mbx_msg_recv | 接收数据。 |
5.2.1. drv_mbx_msg_init¶
-
功能
模块初始化。
-
语法
int drv_mbx_msg_init(void);
-
形参
参数名称 参数含义 输入/输出 无 无 无 -
返回值
返回值 描述 0 成功 -
依赖
-
头文件:Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
库文件
-
5.2.2. drv_mbx_msg_deinit¶
-
功能
反初始化。
-
语法
int drv_mbx_msg_deinit(void);
-
形参
参数名称 参数含义 输入/输出 无 无 无 -
返回值
返回值 描述 0 成功 -
依赖
-
头文件:Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
库文件
-
5.2.3. drv_mbx_msg_poll¶
-
功能
查询是否可以发送或者是否有数据可以接收。
-
语法
int drv_mbx_msg_poll(int flag);
-
形参
参数名称 参数含义 输入/输出 flag 只能是DRV_MBX_MSG_POLLIN或者DRV_MBX_MSG_POLLOUT。DRV_MBX_MSG_POLLIN表示查询是否有待接收的数据,DRV_MBX_MSG_POLLOUT表示查询是否可以发送。 输入 -
返回值
返回值 描述 0 查询接收时表示没有数据可以接收,查询发送时表示不可以发送,入参既不是DRV_RISCV_POLLIN也不是DRV_RISCV_POLLOUT时也返回这个值 其他值 查询接收时表示待接收的数据长度,查询发送时表示可以发送 -
依赖
-
头文件:Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
库文件
-
5.2.4. drv_mbx_msg_send¶
-
功能
发送数据。
-
语法
int drv_mbx_msg_send(const char *msg, int len);
-
形参
参数名称 参数含义 输入/输出 msg 要发送的数据块头指针。 输入 len 要发送的数据块长度(字节)。 输入 -
返回值
返回值 描述 0 发送成功 -1 发送失败 -
依赖
-
头文件:Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
库文件
-
-
注意
- 发送前要使用drv_mbx_msg_poll(DRV_MBX_MSG_POLLIN)确认没有数据待接收,再使用drv_mbx_msg_poll(DRV_MBX_MSG_POLLOUT)确认可以发送。
5.2.5. drv_mbx_msg_recv¶
-
功能
接收数据。
-
语法
int drv_mbx_msg_recv(char *msg, int len);
-
形参
参数名称 参数含义 输入/输出 msg 接收缓冲区指针 输入 len 接收缓冲区长度(字节)。 输入 -
返回值
返回值 描述 >= 0 接收到的数据长度 -
依赖
-
头文件:Alkaid/riscv/kernel/rtk/proj/sc/driver/sysdriver/mbx_msg/mbx_msg.h
-
库文件
-
-
注意
- 接收前要使用drv_mbx_msg_poll(DRV_MBX_MSG_POLLIN)确认有数据待接收。
6. FAQ¶
N/A