全志V853双核开发实战:RISC-V E907小核启动与Linux-RTOS通信详解
1. 项目概述在V853-PRO上启动RISC-V E907小核最近在折腾100ASK_V853-PRO这块开发板它搭载的全志V853芯片有个挺有意思的特性集成了Arm Cortex-A7大核和RISC-V E907小核的双CPU架构。这颗玄铁E907小核本质上是一个完全可综合的高端MCU处理器兼容RV32IMAC指令集自带单双精度浮点单元中断响应也很快。对于想在Linux大系统之外跑一些实时性要求高、功耗敏感的小任务比如传感器数据采集、电机控制、或者作为AI推理的预处理协处理器这个E907小核就非常合适了。但要把这个小核用起来光有硬件支持还不够得打通从固件编译、内核驱动配置到双核通信的整个链路。这个过程涉及到Tina Linux全志定制系统的设备树修改、内核驱动使能以及E907 RTOS基于Melis的编译环境搭建、链接脚本调整。网上资料比较零散我结合官方文档和社区大佬比如Yuzuki的成果把整个流程踩了一遍记录下关键步骤和遇到的坑希望能帮到同样想玩转V853双核的朋友。2. 环境准备与源码获取2.1 硬件与软件基础清单动手之前先理清你需要准备的东西。硬件上除了100ASK_V853-PRO开发板本体你还需要一根USB转串口模块比如CH340、CP2102这类用于连接E907小核的调试串口UART3。软件环境方面我是在Ubuntu 20.04 LTS下操作的其他Linux发行版理论上也行但工具链和依赖可能需要微调。核心的软件资源有三部分Tina Linux SDK这是全志为V853芯片定制的OpenWrt分支包含了U-Boot、Linux内核、根文件系统等。你需要从官方或合作伙伴处获取针对V853-PRO的SDK。E907 RTOS BSP包这是运行在E907小核上的实时操作系统基于Melis的源码和编译工具链。感谢社区开发者Yuzuki的整理和开源我们不必从零开始移植。全志烧写工具PhoenixSuit用于将编译好的Tina系统镜像烧录到开发板的SPI NAND Flash中。2.2 E907开发包下载与解压E907的开发包Yuzuki大佬已经整理好了。你可以直接从他的GitHub仓库获取BSP包和预编译的工具链。为了方便国内网络环境我也传了一份到百度网盘链接见后文。这里假设你把开发包放在/home/book/workspaces目录下。# 进入工作目录 cd /home/book/workspaces # 下载E907 RTOS BSP包如果从网盘下载通常是一个压缩包 # 假设压缩包名为 e907_rtos.tar.gz ls # 输出应包含e907_rtos.tar.gz # 解压源码包 tar -xzvf e907_rtos.tar.gz # 进入解压后的目录 cd e907_rtos ls解压后你会看到rtos和rtos-hal等目录。rtos/source是Melis系统的核心源码目录。编译工具链也已经包含在rtos/toolchain/目录下是riscv64-elf格式的无需额外安装这点很省心。注意工具链的路径是硬编码在Makefile里的通常位于../toolchain/riscv64-elf-x86_64-20201104/。如果你移动了e907_rtos目录可能需要检查或修改相关Makefile中的工具链路径。2.3 Tina SDK基础环境确认确保你的Tina SDK已经正确解压并且能够完成基础的编译配置。通常你需要先运行source build/envsetup.sh然后lunch选择对应的方案例如v853_100ask-tina。这部分是Tina开发的基础在此不赘述。重点是保证你的SDK能正常编译出可启动的镜像。3. E907 RTOS 固件编译详解3.1 编译环境配置与源码编译E907的固件编译过程类似于Linux内核的make menuconfig流程但更轻量。首先我们需要进入源码目录并设置环境。# 进入E907 RTOS源码目录 cd /home/book/workspaces/e907_rtos/rtos/source # 设置Melis编译环境 source melis-env.sh # 选择开发板配置 lunch执行lunch后会看到一个菜单。对于100ASK_V853-PRO开发板我们需要选择3. v853-e907-100ask。这个选项包含了针对这块开发板的预设配置比如内存布局、外设引脚复用等。选择完成后终端会打印出确认信息。接下来就可以直接编译了make编译过程会持续几十秒到一分钟。如果一切顺利你会在最后看到#### make completed successfully ####的提示。编译产物位于ekernel/目录下最重要的文件是melis30.elf这就是我们要烧录到E907小核的固件。3.2 关键配置项解析make menuconfig虽然默认的v853-e907-100ask配置已经能工作但了解核心配置项对后续自定义开发至关重要。在source目录下执行make menuconfig可以进入配置界面。这里有几个关键配置需要理解内存布局DRAM配置在Kernel Setup - Kernel Feature - Memory Layout中定义了E907可用的内存起始地址和大小。这个地址必须与Tina Linux设备树中预留的E907内存区域完全一致否则小核无法正确运行或访问内存。默认配置通常已适配好。串口驱动与输出为了让E907的打印信息能输出需要使能串口驱动。路径是Kernel Setup - Drivers Setup - SoC HAL Drivers - UART Devices。确保[*] enable uart driver被选中并且(3) cli uart port number设置为3即使用UART3。同时需要在SoC HAL Drivers - Common Option中选中[*] enable sysconfig以启用从sys_config.fex文件解析引脚配置的功能。系统配置解析器为了读取sys_config.fex中的引脚复用信息需要在Kernel Setup - Sub system support - devicetree support中选中[*] support traditional fex configuration method parser.。sys_config.fex是全志平台传统的配置文件格式用于定义引脚功能、电源管理等。3.3 链接脚本kernel.lds与内存地址的奥秘编译生成的melis30.elf文件其代码和数据在内存中的布局是由链接脚本kernel.lds决定的。这个文件位于projects/v853-e907-100ask/目录下。用文本编辑器打开它找到MEMORY部分你会看到类似这样的定义MEMORY { /*DRAM_KERNEL: 4M */ DRAM_SEG_KRN (rwx) : ORIGIN 0x48000000, LENGTH 0x00400000 }这里的ORIGIN 0x48000000就是E907固件运行时认为的“内存起始地址”。LENGTH 0x00400000表示内存大小为4MB。为什么是这个地址这需要从整个系统的内存映射说起。假设V853芯片有128MB的DDR内存Linux内核通常会占用低地址部分。为了不让两个核访问同一块物理内存导致冲突我们需要在Linux的设备树中为E907“预留”reserve出一块独立的内存区域。0x48000000这个地址意味着我们从128MB0x48000000 128MB的起始地址往后划出4MB0x00400000专供E907使用。这样A7大核就不会去使用这块区域E907小核则可以安心地在这里运行。所以链接脚本中的这个地址必须和Tina Linux设备树中reserved-memory节点为E907指定的地址一模一样。后续在配置Tina时会再次强调这一点。4. Tina Linux 侧配置与驱动使能要让A7大核运行Tina Linux认识并管理E907小核需要在Linux内核中使能相关的驱动框架。这主要涉及三个部分Remoteproc、Rpmsg和共享内存Mailbox。4.1 设备树DTS配置详解设备树是Linux内核描述硬件资源的重要文件。我们需要修改开发板对应的设备树文件通常是device/config/chips/v853/configs/100ask/board.dts。首先找到reserved-memory节点。我们需要在这里为E907预留内存并为双核通信Rpmsg预留共享内存缓冲区vring。reserved-memory { e907_dram: riscv_memreserve { reg 0x0 0x48000000 0x0 0x00400000; // 为E907预留4MB内存 no-map; // 非常重要表示Linux内核不会映射此区域仅供E907使用 }; vdev0buffer: vdev0buffer47000000 { compatible shared-dma-pool; reg 0x0 0x47000000 0x0 0x40000; // 256KB共享内存池 no-map; }; vdev0vring0: vdev0vring047040000 { reg 0x0 0x47040000 0x0 0x20000; // 128KB用于virtio vring0 no-map; }; vdev0vring1: vdev0vring147060000 { reg 0x0 0x47060000 0x0 0x20000; // 128KB用于virtio vring1 no-map; }; };地址规划解析e907_dram从0x48000000开始的4MB给E907当“主内存”。vdev0buffer从0x47000000开始的256KB作为双核通信的数据缓冲区。vdev0vring0和vdev0vring1紧挨着缓冲区各128KB是virtio通信机制中用于传递缓冲区描述符的“环”ring。这些地址需要连续且与E907侧的配置对应。接着添加E907的远程处理器Remoteproc节点e907_rproc: e907_rproc0 { compatible allwinner,sun8iw21p1-e907-rproc; clock-frequency 600000000; // E907的时钟频率 memory-region e907_dram, vdev0buffer, vdev0vring0, vdev0vring1; // 关联上面定义的内存区域 mboxes msgbox 0; // 使用硬件邮箱Mailbox通道0进行核间中断通知 mbox-names mbox-chan; iommus mmu_aw 5 1; // IOMMU设置用于地址转换 memory-mappings 0x48000000 0x00400000 0x48000000; // 内存映射表格式为 设备地址 长度 物理地址 core-name sun8iw21p1-e907; firmware-name melis-elf; // 固件名称加载时会查找 /lib/firmware/melis-elf status okay; };最后配置Rpmsg控制器和示例设备节点rpbuf_controller0: rpbuf_controller0 { compatible allwinner,rpbuf-controller; remoteproc e907_rproc; // 关联到上面的e907_rproc ctrl_id 0; // 控制器ID对应 /dev/rpmsg_ctrl0 iommus mmu_aw 5 1; status okay; }; rpbuf_sample: rpbuf_sample0 { compatible allwinner,rpbuf-sample; rpbuf rpbuf_controller0; status okay; };一个关键的硬件修改E907的调试串口UART3引脚PH0, PH1默认可能与内核中的UART3驱动冲突。为了防止Linux内核抢占并初始化这个串口我们需要在设备树中禁用Linux侧的UART3节点。找到uart3节点将其status改为disabled。uart3 { pinctrl-names default, sleep; pinctrl-0 uart3_pins_active; pinctrl-1 uart3_pins_sleep; uart-supply ®_dcdc1; status disabled; // 修改为 disabled };同时将UART3的引脚复用设置为GPIO输入模式避免引脚状态冲突uart3_pins_active: uart30 { allwinner,pins PH0, PH1; allwinner,function uart3; allwinner,muxsel 5; allwinner,drive 1; allwinner,pull 1; }; uart3_pins_sleep: uart31 { allwinner,pins PH0, PH1; allwinner,function gpio_in; // 睡眠状态设为GPIO输入 allwinner,muxsel 0; };4.2 内核驱动配置kernel_menuconfig设备树配置好后需要在内核中编译进对应的驱动模块。在Tina SDK根目录下执行make kernel_menuconfig。使能硬件支持Mailbox进入Device Drivers - Mailbox Hardware Support。选中sunxi Mailbox和sunxi rv32 standby driver。Mailbox是核间硬件中断通信的控制器。使能Rpmsg驱动进入Device Drivers - Rpmsg drivers。选中以下选项* allwinnertech rpmsg driver for v853-e907(全志V853的Rpmsg驱动)* allwinnertech rpmsg hearbeat driver(心跳包驱动用于检测小核状态)* sunxi rpmsg ctrl driver(Rpmsg控制驱动用于创建/销毁通信通道)* Virtio RPMSG bus driver(Virtio总线驱动Rpmsg基于此)使能Remoteproc驱动进入Device Drivers - Remoteproc drivers。选中* SUNXI remote processor support。这是加载和管理E907固件的核心驱动。配置完成后保存退出。回到Tina SDK根目录执行make编译内核然后执行pack打包系统镜像。最终会生成一个v853_linux_100ask_uart0.img文件将其烧录到开发板。4.3 硬件检查与UART3连接在烧录新镜像并启动前有一个硬件坑点必须检查。在100ASK_V853-PRO开发板上有一个标记为R36的电阻。这个电阻的存在会导致UART3的默认波特率异常增高使得串口无法正常通信。解决方法找到开发板上的R36电阻通常在CPU附近丝印为R36用电烙铁将其移除。移除后PH0和PH1引脚才能作为标准的UART3使用。连接UART3进行调试将USB转串口模块的RX接开发板的PH0 (UART3_TX)。将USB转串口模块的TX接开发板的PH1 (UART3_RX)。将USB转串口模块的GND接开发板的GND。 开发板背面有清晰的引脚丝印对照连接即可。在PC端使用串口工具如MobaXterm、Putty、minicom打开对应的COM口波特率设置为115200。5. 启动E907小核与双核通信实战5.1 加载并启动E907固件将编译好的melis30.elf文件拷贝到开发板文件系统的/lib/firmware/目录下。可以通过ADB、SCP或者SD卡等方式。# 假设melis30.elf已在开发板的/root目录下 cp /root/melis30.elf /lib/firmware/ ls /lib/firmware/ # 确认文件存在然后通过Remoteproc的调试接口加载并启动小核# 1. 指定固件文件 echo melis30.elf /sys/kernel/debug/remoteproc/remoteproc0/firmware # 2. 启动远程处理器E907 echo start /sys/kernel/debug/remoteproc/remoteproc0/state如果一切正常你会在**主串口UART0即调试串口**看到内核提示E907启动的日志[ 3926.510018] remoteproc0: powering up e907_rproc ... [ 3926.550538] remoteproc0: remote processor e907_rproc is now up同时在连接PH0/PH1的UART3串口终端你会看到E907小核的启动信息最后出现msh 提示符表示已成功进入Melis系统的命令行。5.2 建立双核通信通道RpmsgRpmsgRemote Processor Messaging是基于Virtio的核间通信机制。在E907小核上我们可以使用内置命令来创建通信端点endpoint。在小核的MSH命令行中msh eptdev_bind test 2这条命令创建了一个名为test的Rpmsg服务并指定其端点数量为2即会创建两个通信通道。执行后可以查看当前的监听列表msh rpmsg_list_listen name listen alive test 2 0 console 100 0可以看到test服务有两个监听端点。在Tina Linux大核端我们需要打开对应的通道来建立连接# 打开两个通道对应小核端的两个端点 echo test /sys/class/rpmsg/rpmsg_ctrl0/open echo test /sys/class/rpmsg/rpmsg_ctrl0/open每执行一次open操作内核会创建一个/dev/rpmsgX设备文件X从0开始递增。执行两次后检查设备节点ls /dev/rpmsg* # 应该能看到 /dev/rpmsg0 和 /dev/rpmsg1此时在小核的串口终端你会看到自动输出的绑定成功信息表明通道已建立。5.3 双向数据传输测试通道建立后双核就可以像读写普通文件一样进行通信了。从A7大核发送消息到E907小核 在Tina Linux的终端中echo Hello from A7 Core! /dev/rpmsg0 echo Another message /dev/rpmsg1在E907小核的UART3终端你会立即看到接收到的消息rpmsg0: Rx 20 Bytes Data:Hello from A7 Core! rpmsg1: Rx 16 Bytes Data:Another message从E907小核发送消息到A7大核 在小核的MSH命令行中使用eptdev_send命令。其第一个参数是端点ID对应/dev/rpmsg0是ID 0/dev/rpmsg1是ID 1。msh eptdev_send 0 Hello from E907 Core! will send Hello from E907 Core! to rpmsg0 msh eptdev_send 1 E907 says hi! will send Hello from E907 Core! to rpmsg1在A7大核端可以使用cat命令监听对应的设备文件来接收消息# 终端1监听rpmsg0 cat /dev/rpmsg0 # 输出Hello from E907 Core! # 按 CtrlC 停止监听 # 终端2监听rpmsg1 cat /dev/rpmsg1 # 输出E907 says hi! # 按 CtrlC 停止监听cat命令会阻塞并持续监听直到你按下CtrlC。你可以多次从小核发送消息cat会持续接收并打印。5.4 通信通道的管理与关闭当通信不再需要时应该主动关闭通道以释放资源。在A7大核端操作控制接口即可# 关闭端点0对应的通道 echo 0 /sys/class/rpmsg/rpmsg_ctrl0/close # 关闭端点1对应的通道 echo 1 /sys/class/rpmsg/rpmsg_ctrl0/close关闭后对应的/dev/rpmsg0和/dev/rpmsg1设备文件会消失。同时E907小核端也会收到通道解除绑定的通知。6. 常见问题排查与深度优化建议6.1 编译与启动问题排查表问题现象可能原因排查步骤与解决方案E907编译失败1. 工具链路径错误。2. 源码包不完整或损坏。3. 环境变量未正确设置。1. 检查source/melis-env.sh或 Makefile 中工具链路径是否正确指向riscv64-elf-x86_64-20201104/bin。2. 重新下载并解压BSP包。3. 确保在source目录下执行了source melis-env.sh和lunch。make kernel_menuconfig找不到配置Tina SDK环境未正确设置或方案未选中。在Tina根目录下确保已执行source build/envsetup.sh和lunch并选择了正确的方案如v853_100ask-tina。E907小核启动失败内核报错request_firmware failed1. 固件文件未放入/lib/firmware/。2. 固件文件名不匹配。3. 设备树中firmware-name设置错误。1. 确认melis30.elf已在/lib/firmware/目录。2. 检查设备树e907_rproc节点中firmware-name属性是否为melis-elf默认。3. 使用echo melis30.elf /sys/.../firmware指定固件时确保文件名正确。UART3无输出1. R36电阻未去除。2. 串口线连接错误RX/TX反接。3. Tina设备树中UART3未禁用被内核占用。4. E907配置中未使能UART3驱动或引脚复用错误。1.首要检查用万用表或目检确认R36已去除。2. 交换USB转串口模块的RX和TX线序再试。3. 确认board.dts中uart3的status disabled;。4. 在E907的make menuconfig中确认UART驱动已使能且cli uart port number为3并检查sys_config.fex中[uart3]的引脚配置。双核通信无法建立1. Rpmsg内核驱动未编译进内核或模块未加载。2. 设备树中reserved-memory地址与E907链接脚本不匹配。3. 共享内存vring地址冲突或大小不足。1. 确认内核配置已选中allwinnertech rpmsg driver等并使用lsmod查看相关模块是否加载。2.仔细核对设备树e907_dram的reg属性必须与E907kernel.lds中的ORIGIN完全一致。3. 检查vdev0buffer和vdev0vringx的地址是否连续且无与其他内存区域重叠。6.2 性能优化与高级调试技巧调整E907核心频率在设备树e907_rproc节点中clock-frequency属性可以设置E907的时钟频率。根据实际任务负载和功耗要求进行调整。提高频率可提升计算性能但会增加功耗和发热。优化内存布局默认的4MB内存对于复杂任务可能不够。你可以在设备树中增大e907_dram的LENGTH例如0x00800000为8MB并同步修改E907链接脚本kernel.lds中的LENGTH值。确保预留的内存区域在物理上连续且未被Linux其他部分使用。使用更高效的通信机制Rpmsg是面向消息的对于大量数据流效率可能不是最高。可以考虑共享内存Share Memory在reserved-memory中划分一块更大的区域作为纯共享内存。双核通过约定好的地址直接读写配合Mailbox发送中断通知。这种方式延迟极低适合传输摄像头帧、音频块等大数据。自定义IPCCInter-Processor Communication Controller如果项目对通信实时性和带宽要求极高可以研究芯片手册直接操作Mailbox寄存器实现更底层的协议。E907侧代码调试串口打印最基础的调试手段确保printf或类似接口正确输出到UART3。软件断点由于E907是RISC-V核心可以使用GDB配合OpenOCD进行源码级调试。这需要额外的JTAG调试器如DAPLink和相应的调试服务器配置比较复杂但功能强大。日志存放到共享内存E907将运行日志写入到一块A7也能访问的共享内存中A7侧定期读取并打印。这样可以在不占用调试串口的情况下获取小核日志。电源管理E907小核在空闲时可以进入低功耗状态。需要根据Melis RTOS的电源管理框架配置正确的休眠和唤醒源。例如可以配置E907在完成任务后进入WFIWait For Interrupt状态由A7通过Mailbox发送中断来唤醒它从而节省系统整体功耗。6.3 项目规划与扩展思路成功启动双核并建立通信只是第一步。在实际项目中你需要规划好双核的职责分工A7大核Linux负责复杂的应用逻辑、网络通信、图形显示、文件系统管理等富功能。E907小核RTOS负责高实时性、确定性响应的任务如实时控制PID电机控制、无人机飞控、机械臂伺服。高速数据采集与预处理ADC采样、传感器数据滤波、图像预处理裁剪、格式转换后再交给A7做AI识别。低功耗值守在系统休眠时E907保持运行监听按键、传感器事件并在需要时唤醒A7。一个典型的AI摄像头项目架构可以是E907小核持续从MIPI CSI接口捕获图像进行缩放、色彩空间转换等预处理然后通过共享内存将处理后的图像帧传递给A7大核。A7大核运行Linux和AI推理框架如Tengine、NCNN对图像进行识别并将结果通过网络或屏幕输出。这样繁重的AI计算和丰富的应用功能由A7承担而高帧率、确定性的数据采集和预处理则由E907保障两者通过Rpmsg或共享内存高效协同。最后在开发过程中务必养成随时查阅《V853芯片手册》和《TRM技术参考手册》的习惯。特别是内存映射表、Mailbox寄存器、中断控制器等章节是解决深度问题和进行性能调优的终极依据。双核开发的乐趣和挑战就在于如何让这两颗各有所长的大脑高效地协同工作发挥出“112”的效能。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2614481.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!