异构R5实时系统开发笔记-基于米尔芯驰D9360
2024-06-13
2316
来源:米尔电子
本篇测评由与非网的优秀测评者“短笛君”提供。
本处参考<R5协处理器开发笔记>对D9360中的协处理器进行开发测试
开发之前请确认编译环境正常可以正常对镜像进行编译
具体参考之前编译Ubuntu系统文章,自行编译buildroot系统测试
1.1打开RTOS驱动
freeRTOS的源码放在ssdk包下面,我们可以通过图形化界面启动RTOS系统。D9的ssdk图形化界面是通过menuconfig.sh脚本配置打开,此脚本在ssdk/tools下。以D9360为例,如下:
ddj@ubuntu:~/YD9X/MYD-YD9X-SDK_V1.0/source/ssdk$ pwd/home/ddj/YD9X/MYD-YD9X-SDK_V1.0/source/ssdk~/MYD-JD9X-ubuntu/MYD-JD9X-SDK_V1.0/source/ssdk$ ./tools/menuconfig.sh -b d9360_ref -p ref -c secure


1.2 添加RTOS例程驱动
RTOS系统例程在examples/kunlun/drivers
ddj@ubuntu:~/YD9X/MYD-YD9X-SDK_V1.0/source/ssdk/examples/kunlun/drivers$ ls


新建一个abc目录
并配置Kconfig和rules.mk文件

返回driver目录下 配置Kconfig添加ABC去东门模块初始状态和图形界面类型
ABC驱动模块的初始状态和图形界面类型

在rules.mk文件下,添加如下内容

MODULES += $(LOCAL_DIR)/abc: 如果配置选项 CONFIG_ABC_TEST 为 "y",则会将 $(LOCAL_DIR)/abc 添加到变量 MODULES 中。这意味着当启用了 "ABC Test" 功能时,会将 $(LOCAL_DIR)/abc 模块添加到模块列表中。
R5核数据发送到A55核中
将rpmsg目录下的rpmsg_test.c文件复制到abc.c文件中,该驱动描述如何通过RPMSG协议进行核间通信。我们可以在此程序基础上加入自己的协议,以下是R5核发送“Hello, RPMSG!”字符串到A55核,并打印出接收到的信息的函数。
void send_receive_string(rpmsg_channel_t channel, const char *message) {int max_payload;struct dcf_ccm_hdr *snd_pkg;struct dcf_ccm_hdr *rcv_pkg;status_t ret;max_payload = rpmsg_channel_max_payload(channel);snd_pkg = osAlloc(max_payload);rcv_pkg = osAlloc(max_payload);ASSERT(snd_pkg && rcv_pkg);memset(snd_pkg, 0x0, max_payload);memset(rcv_pkg, 0x0, max_payload);snd_pkg->dmsg.msg_type = COMM_MSG_CCM_ECHO;snd_pkg->dmsg.opflags |= DCF_MSGF_TMS;snd_pkg->dmsg.msg_len = sizeof(struct dcf_ccm_hdr) - sizeof(struct dcf_message);strncpy(snd_pkg->data, message, max_payload - sizeof(struct dcf_ccm_hdr));ret = rpmsg_channel_send(channel, RPMSG_ECHO_EPT_ADDR, snd_pkg, max_payload, 3000);if (ret == RPMSG_SUCCESS) {printf("Sent: %sn", message);} else {printf("Failed to send messagen");}int received_len;ret = rpmsg_channel_recv(channel, rcv_pkg, max_payload, &received_len, 3000);if (ret == RPMSG_SUCCESS) {printf("Received: %sn", rcv_pkg->data);} else {printf("Failed to receive messagen");}osFree(snd_pkg);osFree(rcv_pkg);}
将以上函数添加至abc.c文件内,并在主函数(rpmsg_test)编写调用该函数条件,如下:
const char* message_to_send = "Hello,rpmsg";if (argc == 0) {rpmsg_test_show();goto exit;}if (argc == 2) {test_case = 0;type = atoi(argv[0]);rproc = atoi(argv[1]);}else if (!strcmp(argv[0], "ping")) {test_case = 1;type = atoi(argv[1]);rproc = atoi(argv[2]);times = atoi(argv[3]);}else if (!strcmp(argv[0], "iperf")) {test_case = 2;type = atoi(argv[1]);rproc = atoi(argv[2]);times = atoi(argv[3]);}//新添加的条件else if(!strcmp(argv[0], "send")){test_case = 3;type = atoi(argv[1]);rproc = atoi(argv[2]);times = atoi(argv[3]);}else {printf("Unknown cmd %sn", argv[0]);goto exit;}switch (test_case) {case 0:do_rpmsg_echo_test(channel);break;case 1:do_rpmsg_ping_test(channel, times);break;case 2:do_rpmsg_iperf_test(channel, times);break;case 3:send_receive_string(channel, message_to_send);break;default:printf("Unknown case %dn", test_case);break;}//加入串口打印提示(跳至rpmsg_test_show函数)printf("nTest command:n");printf("trpmsg_test <type> <remote-proc>n");printf("trpmsg_test ping <type> <remote-proc> <times>n");printf("trpmsg_test iperf <type> <remote-proc> <times>n");printf("trpmsg_test send <type> <remote-proc> <times>n");printf("ne.g: test ping rpmsg.virtio 10 times with secure, use command:n");printf("trpmsg_test ping 0 1 10n");
通过5.1小节打开图形化配置界面,进入到Driver and Application Examples/Driver Example Support下,可以看到我们新加的abc test Support驱动配置选项,需要关闭RPMSG Example Application Support选项,如下:




选中此选项编译进内核,将串口线(debug)接到10_TX,10_RX和GND,打开终端调试工具。编辑source/ssdk/ middleware/rpmsg_service/rpmsg_echo.c文件,添加代码如下:
static int echo_channel_cb(void *data, int len, unsigned long src, void *arg){rpmsg_channel_t chan = arg;struct dcf_ccm_hdr *ccm_pkg = data;const char *char_data = (char *)data;int ret = 0;if (ccm_pkg->dmsg.msg_type == COMM_MSG_CCM_ECHO) {ccm_pkg->time[2] = timer_get_current_time(g_syscnt_timer) * g_sdrv_syscnt_dev.cnt_per_us;ret = rpmsg_channel_send(chan, src, data, len, 1000);printf("Sending data (length %d): ", len);for (int i = 8; i < len; i++) {printf("%c ", char_data[i]);}printf("n");}else if (ccm_pkg->dmsg.msg_type == COMM_MSG_CCM_ACK) {ret = rpmsg_channel_send(chan, src, (char *)"ACK", 4, 1000);ssdk_printf(SSDK_INFO,"send ACKn");}else {ssdk_printf(SSDK_WARNING, "echo_channel_cb: unknown %d bytes from addr %ldn",len, src);}if (ret != 0) {ssdk_printf(SSDK_WARNING, "echo_channel_cb: channel send failedn");}return ret;}
A55发送数据给R5
自定义一个发送和接收字符串的函数,如下:
int send_receive_string(int fd, const char *send_str,int ntimes, int seconds) {int i = 0, j = 0;int size, bytes_rcvd, bytes_sent;long elapse = 0;err_cnt = 0;i_payload = (struct _payload *)malloc(sizeof(struct _payload) + payload_max_size);r_payload = (struct _payload *)malloc(sizeof(struct _payload) + payload_max_size);if (i_payload == 0 || r_payload == 0) {printf("ERROR: Failed to allocate memory for payload.n");return -1;}if (seconds)gettimeofday(&start_test, NULL);i_payload->magic = 0xA5;for (j = 0; j < ntimes; j++) {i_payload->num = i;i_payload->size = size;strcpy(i_payload->data, send_str);if (verbose) printf("rn sending payload number");if (verbose) printf(" %d of size %lurn", i_payload->num,(sizeof(struct _payload)) + strlen(i_payload->data));bytes_sent = write(fd, i_payload, sizeof(struct _payload) + strlen(i_payload->data));if (bytes_sent <= 0) {if (verbose) {perror("rn Error sending datan");break;} elsefprintf(stderr, "#");err_cnt++;continue;}printf("send string:%sn",i_payload->data);r_payload->num = 0;bytes_rcvd = read(fd, r_payload,sizeof(struct _payload) + payload_max_size);while (bytes_rcvd <= 0) {usleep(10000);bytes_rcvd = read(fd, r_payload,sizeof(struct _payload) + payload_max_size);}r_payload->data[bytes_rcvd] = '�';printf("receive string:%sn",r_payload->data);if (interval)sleep(interval);}free(i_payload);free(r_payload);return 0;}

在main函数内添加新增函数条件:

编辑source/linux/ drivers/rpmsg/virtio_rpmsg_bus.c文件,代码如下:


保存所有代码
编译系统 烧录

1.5结果显示
在R5核调用rpmsg_test例程,向A55核发送信息
R5界面>rpmsg_test send 0 3 1>Sent: 123456789Received: 123456789>rpmsg_test send 1 3 1>Sent: 123456789Received: 123456789A55界面root@myd-jd9x:~# [ 22.223170] virtio_rpmsg_bus virtio0: virtio send susses[ 34.943644] sd,rpmsg-ipcc soc:ipcc@1: ipcc send susses
在A55核调用echo_test例程,向R5发送信息,打印如下:
A55界面root@myd-jd9x:~# echo_test -d virtio0.rpmsg-echo.-1.30 -c 1Echo test startupdate rpmsg-mtu=496 from kernelsend string:Hello,RPMsg!receive string:Hello,RPMsg!R5界面>Sending data (length 20): H e l l o , R P M s g !
2026-01-29
新法规欧标AC桩一站式技术实现方案
面对欧盟Delegated Regulation (EU) 2025/656条例设定的明确技术路线与2027年强制生效节点,开发符合 EN ISO 15118-20:2022 标准的下一代智能交流充电桩,已成为产品进入欧洲市场的唯一路径。这意味着,传统PWM通信方式即将淘汰,全面转向基于 GreenPHY电力线载波(PLC)的高层通信,并强制集成即插即充(PnC)与车辆到电网(V2G)能力。01硬
2026-01-22
看过来,米尔RK3576 NPU方案你用对了吗?
本文基于米尔MYD-LR3576开发板,详细记录了如何利用500万像素USB摄像头实现640×640分辨率的YOLO5s目标检测,并将结果实时输出至1080P屏幕的全流程。通过系统级的软硬件协同优化,最终将端到端延迟控制在40ms以内,实现了 20FPS的稳定实时检测性能。文章重点剖析了摄像头特性分析、显示通路选择、RGA硬件加速、RKNN NPU集成等关键技术环节,为嵌入式AI视觉系统的开发与调
2026-01-22
全场景工控与网关解决方案:从入门到旗舰的一站式选型
在工业自动化与物联网向深度智能迈进的浪潮中,工业设备对成本控制、运行可靠性及智能算力的要求正持续攀升。无论是追求极致性价比的基础工控终端,还是需要强劲算力支撑的AIoT边缘节点,开发者都在为不同场景寻觅适配的“工业之芯”。对此,我们基于MYC-YR3506、MYC-LT536、MYC-LR3576三款核心板,打造了覆盖低、中、高端全场景的工业控制与网关解决方案,以一站式选型体系,助力工业产品实现“
2026-01-15
当国产芯遇上机器人:RK3576的ROS2奇幻之旅
当RK3576的强劲“大脑”(四核A72+四核A53)与强大的GPU、VPU、NPU加速模块相遇,一场高性价比的机器人开发革命正在悄然发生。我们成功将完整的Ubuntu 22.04与ROS2 Humble生态系统,完美移植到了这颗国产芯片上。一个稳定、全功能的机器人软件开发平台已经就绪,现在就来一起探索它的强大魅力!一、系统启动与基础性能展示1.硬件平台简介开发板:MYD-LR3576存储:eMM
2026-01-15
内置全栈安全,一站式满足CRA法案与IEC 62443标准-米尔MYC-LF25X核心板
面对日益严峻的网络安全挑战,欧盟《网络弹性法案》(CRA)的出台与工业安全标准IEC 62443的广泛应用,为设备制造商筑起了新的合规门槛。安全不再是可选功能,而是产品设计的强制基石。米尔电子推出的MYC-LF25X嵌入式处理器模组,基于已通过SESIP 3级认证的意法半导体STM32MP257F处理器,提供从硬件信任根到应用层的全栈、可验证安全架构,是您高效开发符合国际法规与标准的安全关键型应用
2025-12-26
补贴太香了!158元买米尔NXP i.MX 91开发板,限购300套
太香了!限时补贴狂欢,回馈您的支持!米尔基于NXP i.MX 91开发板仅158元,限量300套,先到先得。该开发板基于新一代NXP i.MX 91系列处理器设计,搭载Arm Cortex-A55核心,集成双千兆以太网和双 USB 端口等丰富外设,支持Linux、Android等主流操作系统,赋能新一代入门级Linux应用,适用于工业控制、智能终端、物联网等领域的原型开发与教学实践。产品型号:MY
2025-12-19
Buildroot MQTT-Modbus 网关开发,实现设备远程监控方案-米尔RK3506
在工业物联网与智能家居场景中,远程设备监控的核心痛点是工业总线协议与物联网协议的兼容性问题。基于RK3506 Buildroot系统开发的MQTT-Modbus网关产品,通过协议桥接技术完美解决这一难题,为低成本、高可靠的远程监控提供了高效解决方案。一、核心开发平台与技术选型硬件平台选用RK3506处理器作为网关核心硬件,该芯片具备低功耗、高性价比特性,支持多接口扩展,完全适配工业级嵌入式场景需求
2025-12-19
SDK重磅升级,RK3506核心板解锁三核A7实时控制新架构
在工业控制与边缘智能领域,开发者的核心需求始终明确:在可控的成本内,实现可靠的实时响应、稳定的通信与高效的开发部署。米尔电子基于RK3506处理器打造的MYC-YR3506核心板平台,近期完成了一次以“实时性”和“可用性”为核心的SDK战略升级,致力于将多核架构的潜力转化为工程师可快速落地的产品力。本次升级围绕两大主线展开:系统生态的多样化与实时能力的深度释放。我们不仅提供了从轻量到丰富的操作系统
2025-12-11
赋能欧标充电桩市场:OCPP协议实战开发指南
随着全球电动汽车产业的迅猛发展,充电基础设施的智能化与标准化已成为行业迫切需求。OCPP(Open Charge Point Protocol即开放充电点协议)作为连接充电桩与中央管理系统的"通用语言",正成为解决设备互联互通难题的关键技术。一、OCPP:为何是出海欧标的必选项?OCPP是一个开放、标准的通信协议,它确保了不同制造商生产的充电桩能够与任何兼容的后台管理系统进行无
2025-12-11
打造本地化智能的“最强大脑”, 米尔RK3576 AI边缘计算盒
在人工智能与边缘计算深度融合的浪潮中,本地化智能需求正重塑产业格局。米尔电子推出的RK3576边缘计算盒,具备高算力、低功耗与强扩展性,凭借其卓越的硬件架构与多场景适配能力,正成为推动工业视觉、工程机械及智慧城市等领域智能化产业升级的有力工具。米尔MYD-LR3576-B边缘计算盒基于瑞芯微中高端RK3576芯片,采用异构计算架构,集成4核Cortex-A72与4核Cortex-A53处理器,搭配