简介
Duo 的 CPU 采用双核设计,大核上跑的是 Linux 系统,小核上跑的是实时系统,当前是 FreeRTOS。
如何使用小核
核间通信样例
Duo 大核与小核间通信是通过 mailbox 机制实现的,最新的镜像已经在大核的 Linux 内核中添加了 mailbox 驱动,小核 FreeRTOS 代码中也实现了相关功能,请使用 V1.0.9 或者 更新的镜像 测试。
通过大核控制小核点亮 LED
该样例是运行在大核上的一个 Linux 应用程序,通过大核 Linux 内核中的 mailbox 驱动,来通知小核 FreeRTOS 控制 Duo 上的蓝色 LED 先点亮,3秒后再灭掉。
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
enum SYSTEM_CMD_TYPE {
CMDQU_SEND = 1,
CMDQU_SEND_WAIT,
CMDQU_SEND_WAKEUP,
};
#define RTOS_CMDQU_DEV_NAME "/dev/cvi-rtos-cmdqu"
#define RTOS_CMDQU_SEND _IOW('r', CMDQU_SEND, unsigned long)
#define RTOS_CMDQU_SEND_WAIT _IOW('r', CMDQU_SEND_WAIT, unsigned long)
#define RTOS_CMDQU_SEND_WAKEUP _IOW('r', CMDQU_SEND_WAKEUP, unsigned long)
enum SYS_CMD_ID {
CMD_TEST_A = 0x10,
CMD_TEST_B,
CMD_TEST_C,
CMD_DUO_LED,
SYS_CMD_INFO_LIMIT,
};
enum DUO_LED_STATUS {
DUO_LED_ON = 0x02,
DUO_LED_OFF,
DUO_LED_DONE,
};
struct valid_t {
unsigned char linux_valid;
unsigned char rtos_valid;
} __attribute__((packed));
typedef union resv_t {
struct valid_t valid;
unsigned short mstime; // 0 : noblock, -1 : block infinite
} resv_t;
typedef struct cmdqu_t cmdqu_t;
/* cmdqu size should be 8 bytes because of mailbox buffer size */
struct cmdqu_t {
unsigned char ip_id;
unsigned char cmd_id : 7;
unsigned char block : 1;
union resv_t resv;
unsigned int param_ptr;
} __attribute__((packed)) __attribute__((aligned(0x8)));
int main()
{
int ret = 0;
int fd = open(RTOS_CMDQU_DEV_NAME, O_RDWR);
if(fd <= 0)
{
printf("open failed! fd = %d\n", fd);
return 0;
}
struct cmdqu_t cmd = {0};
cmd.ip_id = 0;
cmd.cmd_id = CMD_DUO_LED;
cmd.resv.mstime = 100;
cmd.param_ptr = DUO_LED_ON;
ret = ioctl(fd , RTOS_CMDQU_SEND_WAIT, &cmd);
if(ret < 0)
{
printf("ioctl error!\n");
close(fd);
}
sleep(1);
printf("C906B: cmd.param_ptr = 0x%x\n", cmd.param_ptr);
sleep(3);
cmd.cmd_id = CMD_DUO_LED;
cmd.param_ptr = DUO_LED_OFF;
ret = ioctl(fd , RTOS_CMDQU_SEND, &cmd);
if(ret < 0)
{
printf("ioctl error!\n");
close(fd);
}
sleep(1);
printf("C906B: cmd.param_ptr = 0x%x\n", cmd.param_ptr);
close(fd);
return 0;
}
该测试程序已经放到了 duo-examples 仓库中,如果你是第一次使用该仓库,可以参考 README 来配置环境完成编译:
- 推荐的编译环境是
Ubuntu 22.04 LTS
- 安装依赖的工具:
sudo apt-get install wget git make
- 获取 duo-examples 仓库源码:
git clone https://github.com/milkv-duo/duo-examples.git --depth=1
- 加载编译环境:
cd duo-examples
source envsetup.sh - 进入
mailbox-test
目录编译cd mailbox-test
make
编译成功后将生成的 mailbox_test
测试程序通过网口或者 USB网络(RNDIS) 等方式传送到 Duo 设备中,比如 USB 网络方式,Duo 的 IP 为 192.168.42.1
,用户名是 root
,密码是 milkv
$ scp mailbox_test [email protected]:/root/
在 Duo 上为 mailbox_test
程序添加可执行权限:
chmod +x mailbox_test
Duo 的默认固件大核 Linux 系统会控制 LED 闪烁,这个是通过开机脚本实现的,在测试该程序的时候,需要将 LED 闪烁的脚本禁用,在 Duo 的终端中执行:
mv /mnt/system/blink.sh /mnt/system/blink.sh_backup && sync