Skip to main content

大小核通信说明(以X2000为例)

本文以x2000为例展示大小核通讯时搭建软件环境的方法,包括配置串口显示小核log信息,小核的编译、加载方法、大小核通讯的代码api调用方法。

目前本文适用于x2000、x2100、x2600平台,使用方法相同。

因为小核是运行在大核内存中的大核驱动,而大小核是共用所有ddr内存的,所以在使用小核之前要先对大核中的内存进行划分,其中rtos_size段是专用于小核的。在小核配置中也要对应设置rtos_size对应段的起始地址和长度作为小核运行的起始地址和长度。

注意:如果没有对ddr进行正确划分或小核没有正确配置运行起始地址和长度,系统运行过程中大小核都可能出现一些奇奇怪怪的问题,很难查问题。

内存划分相关详细文档请参照

repo代码库\doc\开发使用说明\预留内存使用说明文档\x2600\Linux预留内存管理.pdf

repo代码库\doc\FAE文档\小核使用和开发\划分小核配置内存的方法.pdf

一 配置大核

配置大核驱动及对应的shell命令。

5

6

二 配置小核

7

8

不管使用小核的什么功能,都需要对小核的log输出uart进行配置。小核log输出的uart可以和大核是同一个,也可以不是同一个。根据硬件进行二选一的配置即可。

2.1 和大核使用同一个uart进行小核log输出

本例中,大核使用的log输出口为:uart2_pd30 到 31。本章节展示如何配置小核和大核使用同样的log输出口。

选中小核uart驱动,但是不选中具体的uart端口驱动。

9

10

配置小核的console:

11

保存小核配置:

12

2.2 和大核使用不同uart进行小核log输出

举例说明,大核当前使用的log输出口为:uart2_pd30~31,那么本章节展示配置uart3_pc25~26为小核的log输出口的方法。

13

14

注意:同一个控制器只能在大核或者小核中初始化一次,不能在大小核中都初始化。否则可能会出现当前控制器工作异常。所以本例中既然在小核中独立使用uart3,就要保证大核中没有加载uart3的设备驱动。uart的设备驱动加载在设备树中,所以本例应检查kernel对应的设备树dts文件中没有使能uart3_pc25 到 26.

15

16

上图可知,当前dts文件加载了./arch/mips/boot/dts/ingenic/x2000.dtsi,在此文件中指定了引脚定义文件x2000-pinctrl.dtsi。

17

在x2000-pinctrl.dtsi中可见上文x2000_module_base.dts中引用的uart3_pc对应的引脚定义确实是PC25 到 26,在主控端设置为FUNCTION0功能。与小核中设置的uart3引脚和功能一致,所以应在上文x2000_module_base.dts中将对应的uart3设置为disable。

18

三 编译小核配置

# 切换到工程小核libmcu的编译目录
cd libmcu/

# 配置编译器路径
export PATH=../tools/toolchains/riscv-r1.0.0/bin/:$PATH

# 编译对应的配置文件
make x2000_test_defconfig

# 编译小核(生成libmcu-bare.bin小核镜像文件)
make

# 将libmcu-bare.bin镜像文件adb到开发板的/usr/data或者tmp/可写分区
adb push libmcu-bare.bin /usr/data

四 加载小核镜像

4.1 cmd_mcu命令介绍

cmd_mcu命令介绍

# 写小核镜像
cmd_mcu write_firmware /usr/data/libmcu-bare.bin
# 加载小核镜像
cmd_mcu bootup
# 复位小核
cmd_mcu reset
# 关闭小核
cmd_mcu shutdown
# 写字符串数据
cmd_mcu write_str test123456
# 写整型数据
cmd_mcu write_data 0x01 0x02 0x03 0x04
# 往指定内存写数据
cmd_mcu write_mem 0x400 0x01 0x02 0x03
# 读取字符串数据
cmd_mcu read_str 11
# 读取整整型数据
cmd_mcu read_data 4

4.2 加载小核

# 写入小核镜像
cmd_mcu write_firmware /usr/data/libmcu-bare.bin

# 加载小核镜像
cmd_mcu bootup

# 复位小核
cmd_mcu reset

五 大小核通讯测试

应用示例路径:libmcu/vendor/vendor.c

while (1) {
while (!is_data_comming);
is_data_comming = 0;

int len = 0;
char buf[100];
int ret;
int send_len;
/* 从大核读取数据 */
while (1) {
ret = host_cpu_read(buf+len, sizeof(buf)-len);
if (!ret)
break;

len += ret;
}

printf("len: %d : ", len);
int i;
for (i = 0; i < len; i++) {
printf("%c", buf[i]);
}

printf("\n");

send_len = len;
/* 向大核写入数据 */
while (len) {
while(mcu_test_host_busy());

while (len) {
int ret = host_cpu_write(buf, len);
len -= ret;
if (!ret)
break;
}
/* 通知写入数据的长度 */
mcu_notify_host(send_len);
}
}

5.1 大核向小核写入数据

大核通过libhardware2的cmd_mcu write命令可以向小核写数据,小核通过host_cpu_read函数进行读取大核写的数据。

19

5.2 大核从小核读取数据

大核通过libhardware2的cmd_mcu read命令可以从小核读取数据,小核通过host_cpu_write函数向大核进行写数据。

20