0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

RK3588 CPU 隔离:AB/非 AB 系统双方案适配实战

jf_44130326 来源:Linux1024 作者:Linux1024 2026-02-09 07:12 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在RK3588嵌入式产品开发中,CPU隔离是提升系统实时性的核心手段,能让关键任务独占核心资源,规避系统调度与中断干扰。本次基于RK3588原厂SDK,同时实现AB/非AB两种系统架构的CPU隔离方案,两套方案代码均完整可直接套用,核心差异仅在于代码集成路径与函数调用时机,且均支持通过vendor_storage动态配置隔离核心,无需反复编译固件,重启即可生效。下文将从隔离原理、适用场景、双方案实现、动态配置、效果验证全维度展开,手把手教你落地RK3588 CPU隔离。

wKgZPGmJGPWAOtkQAAAznjpc1qA105.png

一、为什么要给RK3588做CPU隔离?

RK3588搭载8核异构架构(4×Cortex-A76 + 4×Cortex-A55),兼顾高性能与低功耗,但Linux内核默认的全局共享调度机制,在工业控制、车载等高实时性场景中存在明显短板:

1.任务抢占:系统后台进程、守护程序会随机抢占核心资源,导致关键任务出现毫秒级甚至微秒级响应延迟;

2.中断干扰:内核定时器、外设中断无差别落在所有核心,打断AI推理、音视频编解码等连续计算任务;

3.资源竞争:多核缓存、总线资源被非关键任务占用,大幅降低A76大核的算力利用率。

通过isolcpus(核心隔离)+nohz_full(关闭隔离核时钟节拍)+rcu_nocbs(RCU回调绑定)三参数组合配置,可实现隔离核的纯独占式使用

•内核不会主动将任何系统任务调度到隔离核,仅允许手动绑定的用户关键任务运行;

•关闭隔离核的时钟中断,减少内核调度开销,降低系统资源占用;

•避免隔离核被RCU内核回调任务占用,真正实现核心资源的专属化。

同时,两套方案均做了非法配置安全兜底:若配置非0-8的数字组合,将自动放弃核心隔离,仅设置rcu_nocbs=all做全局RCU优化,避免非法配置导致内核启动异常。

二、RK3588 CPU隔离典型适用场景

RK3588广泛应用于工业、车载、边缘计算、高端音视频领域,这些场景也是CPU隔离的核心落地场景,隔离后可大幅提升任务稳定性与响应速度:

1.工业控制:隔离1-2个A76大核运行PLC、运动控制、Modbus/CAN总线数据处理,保障毫秒级控制响应;

2.车载智能座舱:隔离核心运行CAN/LIN总线通信、仪表盘实时渲染,规避系统任务干扰,保障行车安全;

3.边缘计算:隔离2个A76大核运行RKNN AI模型推理,独占算力提升推理速度与结果稳定性;

4.音视频处理:隔离核心运行4K/8K视频编解码、音频实时降噪,解决帧丢包、画面卡顿、音频延迟问题;

5.高可靠服务:隔离核心运行后台专属守护进程,避免服务被抢占,提升系统整体稳定性。

三、核心实现:AB/非AB系统双方案,路径不同可直接套用

本次实现AB、非AB两套独立的CPU隔离方案,代码均基于RK3588原厂SDK开发完成,可直接复制套用,两套方案的核心逻辑完全一致(动态读取配置、合法性校验、参数拼接),唯一差异在于代码集成的文件路径与函数调用时机,适配不同系统架构的启动流程,确保配置在kernel启动前完成生效。

核心设计共性

1.配置存储:隔离核心配置统一写入vendor_storage的VENDOR_CUSTOM_ID_1E节点(对应底层30号节点),两套方案均从该节点读取配置;

2.动态生效:系统层通过指令写入配置,无需重新编译固件,重启后U-Boot自动读取并生效;

3.安全兼容:仅将隔离参数追加到原有bootargs,不修改、不覆盖系统核心配置,保障SDK原生兼容性;

4.合法性校验:仅支持0-8的数字组合(适配RK3588 8核架构),超出范围自动兜底为rcu_nocbs=all。

方案差异:AB/非AB系统调用与生效路径

两套方案的核心区别在于代码集成文件函数调用位置,适配不同系统的U-Boot启动流程,确保隔离参数在bootargs最终确定前完成拼接:

系统架构 代码集成文件 函数调用时机 生效逻辑
AB系统 u-boot/common/android_ab.c ab_update_root_uuid函数末尾调用 随AB分区root UUID更新流程执行,在kernel启动前完成参数拼接
非AB系统 u-boot/common/android_bootloader.c 系统启动流程中android_bootloader_boot_flow内调用 随原生bootloader启动流程执行,在kernel启动前完成参数拼接

四、SDK核心修改:双方案代码直接套用

两套方案的代码均为增量修改,无需修改SDK原有核心逻辑,可直接复制到对应文件中,同时需对内核设备树做一处简单修改,避免参数冲突。

通用修改:内核设备树移除默认参数,避免冲突

无论AB还是非AB系统,均需先修改kernel-6.1/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi,删除chosen节点中默认的rcu_nocbs=all,防止与动态配置的参数冲突,修改后保留系统原有所有bootargs配置:

diff --git a/kernel-6.1/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi b/kernel-6.1/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsiindex d59966fb10..121a17bab2 100644--- a/kernel-6.1/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi+++ b/kernel-6.1/arch/arm64/boot/dts/rockchip/rk3588-linux.dtsi@@ -12,7 +12,7 @@};
chosen: chosen {-bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 console=ttyS8,1500000n8 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=c2ebb35f-b6ea rw rootwait rcupdate.rcu_expedited=1 rcu_nocbs=all mtdparts=sfc_nor:0x00040000@0x00180000(vnvm),0x00600000@0x00200000(uboot_a),0x00600000@0x00800000(uboot_b),-@0x00E00000(test_data:grow)";+bootargs = "earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 console=ttyS8,1500000n8 irqchip.gicv3_pseudo_nmi=0 root=PARTUUID=c2ebb35f-b6ea rw rootwait rcupdate.rcu_expedited=1 mtdparts=sfc_nor:0x00040000@0x00180000(vnvm),0x00600000@0x00200000(uboot_a),0x00600000@0x00800000(uboot_b),-@0x00E00000(test_data:grow)";};

方案1:AB系统代码实现(直接套用)

在u-boot/common/android_ab.c中,于get_partition_unique_uuid函数后添加CPU隔离核心代码,并在ab_update_root_uuid函数末尾调用update_cpu_isol_bootargs,代码适配U-Boot编译环境,无标准C库依赖,可直接复制:

diff --git a/u-boot/common/android_ab.c b/u-boot/common/android_ab.cindex 53fddceaaf..e0875c6d36 100644--- a/u-boot/common/android_ab.c+++ b/u-boot/common/android_ab.c@@ -406,6 +406,89 @@static int get_partition_unique_uuid(char *partition,return 0;}
+#include ++#define CPU_BUF_LEN    128+#define BOOTARGS_OLD_BUF  1024+#define BOOTARGS_NEW_BUF  2048++extern void vendor_storage_read(int idx, char *buf, int len);+extern char *env_get(const char *name);+extern int env_update(const char *name, const char *value);++static int my_isdigit(char c)+{+  return (c >= '0' && c <= '9') ? 1 : 0;+}++static int my_strlen(const char *s)+{+    int len = 0;+    if (s == NULL) return 0;+    while (*s++) len++;+    return len;+}++void __attribute__((unused)) update_cpu_isol_bootargs(void)+{+    char command_line1[CPU_BUF_LEN] = {0};+    char cpu_isol[CPU_BUF_LEN] = {0}, tmp[CPU_BUF_LEN] = {0};+    char old_bootargs[BOOTARGS_OLD_BUF] = {0};+    char new_bootargs[BOOTARGS_NEW_BUF] = {0};+    char *bootargs_ptr = NULL;+    int cpu_config_valid = 1;++    vendor_storage_read(30, command_line1, sizeof(command_line1) - 1);++    int config_len = my_strlen(command_line1);+    if (config_len == 0) {+        cpu_config_valid = 0;+    } else {+        for (int i = 0; command_line1[i]; i++) {+            if (!my_isdigit(command_line1[i]) || (command_line1[i] - '0') > 8) {+        cpu_config_valid = 0;+        break;+      }+    }+  }++  if (cpu_config_valid) {+    for (int i = 0; command_line1[i]; i++) {+      if (i > 0) strcat(tmp, ",");+      strncat(tmp, &command_line1[i], 1);+    }+    snprintf(cpu_isol, sizeof(cpu_isol),+         "isolcpus=%s nohz_full=%s rcu_nocbs=%s", tmp, tmp, tmp);+  } else {+    snprintf(cpu_isol, sizeof(cpu_isol), "rcu_nocbs=all");+  }++  bootargs_ptr = env_get("bootargs");+  if (bootargs_ptr != NULL) {+    strncpy(old_bootargs, bootargs_ptr, sizeof(old_bootargs) - 1);+  } else {+    printf("WARN: bootargs is empty in env!n");+  }++  snprintf(new_bootargs, sizeof(new_bootargs), "%s %s", old_bootargs, cpu_isol);+  char *final_bootargs = new_bootargs;+  while (*final_bootargs == ' ') final_bootargs++;++  env_update("bootargs", final_bootargs);+  bootargs_ptr = env_get("bootargs");+}static void ab_update_root_uuid(void){/*@@ -439,6 +522,7 @@static void ab_update_root_uuid(void)strcat(root_partuuid, guid_buf);env_update("bootargs", root_partuuid);}+update_cpu_isol_bootargs();}

方案2:非AB系统代码实现(直接套用)

在u-boot/common/android_bootloader.c中添加CPU隔离核心代码,并在android_bootloader_boot_flow流程内的对应位置调用update_cpu_isol_bootargs,代码完整可直接复制,适配非AB系统启动流程:

diff --git a/u-boot/common/android_bootloader.c b/u-boot/common/android_bootloader.cindex 6f69843cdc..81c7874f40 100644--- a/u-boot/common/android_bootloader.c+++ b/u-boot/common/android_bootloader.cint android_bootloader_boot_flow(struct blk_desc *dev_desc, unsigned long load_address){@@ -1385,6 +1468,7 @@int android_bootloader_boot_flow(struct blk_desc *dev_desc,env_update("bootargs",  "androidboot.verifiedbootstate=orange");+update_cpu_isol_bootargs();
if (android_image_load_by_partname(dev_desc,  boot_partname,

五、完整实操:动态配置隔离核心,无需重编固件

两套方案的系统层配置与生效步骤完全一致,仅需首次编译修改后的SDK并烧录,后续调整隔离核心无需重新编译,通过vendor_storage指令动态配置,重启即可生效,真正实现“一次编译,多次配置”。

Step 1:编译并烧录修改后的SDK

1.按对应系统架构,将上述代码复制到SDK指定文件,完成设备树与U-Boot代码修改;

2.执行RK3588标准编译命令,生成U-Boot和内核固件:

3.通过RKDevTool将编译后的u-boot.img和boot.img烧录到RK3588开发板。

Step 2:系统层动态配置隔离核心(核心指令)

开发板启动进入系统后,通过vendor_storage指令将隔离核心配置写入VENDOR_CUSTOM_ID_1E节点,仅支持0-8的数字组合,数字将自动转为逗号分隔的核心列表,无需手动添加分隔符,核心指令:

# 通用配置指令VENDOR_CUSTOM_ID_1E 这个不是固定的idvendor_storage-w VENDOR_CUSTOM_ID_1E -t string -i[0-8数字组合]

常用配置示例

RK3588核心编号为0-8,可根据业务需求灵活配置,示例如下:

1.隔离第5、6个核心(主流实操示例):

vendor_storage-w VENDOR_CUSTOM_ID_1E -t string -i56

2.隔离单个A76大核(核心7):

vendor_storage-w VENDOR_CUSTOM_ID_1E -t string -i7

3.隔离0、3、8三个核心:

vendor_storage-w VENDOR_CUSTOM_ID_1E -t string -i038

4.清除隔离配置(恢复系统默认):

vendor_storage -w VENDOR_CUSTOM_ID_1E -tstring-i""

Step 3:重启开发板,配置生效

配置写入后,执行重启命令,U-Boot启动时会自动读取vendor_storage中的配置,拼接并更新bootargs,隔离参数随内核启动生效:

reboot

六、必做验证:确认CPU隔离是否真正生效

开发板重启后,通过两个标准命令验证隔离效果,确保配置正确生效,这是落地CPU隔离的关键步骤,两套方案验证方式完全一致。

验证1:查看内核启动参数,确认隔离参数已追加

通过cat /proc/cmdline查看bootargs,确认包含配置的isolcpus/nohz_full/rcu_nocbs三参数,且保留系统原有所有配置,示例(隔离5、6核):

cat/proc/cmdline

预期输出:命令行中包含isolcpus=5,6 nohz_full=5,6 rcu_nocbs=5,6。

若配置非0-8的非法字符/数字,输出仅包含rcu_nocbs=all,无其他隔离参数,属于正常兜底逻辑。

验证2:查看内核实际隔离核心(最关键验证)

Linux内核提供专属标准文件用于查看CPU隔离状态,通过cat /sys/devices/system/cpu/isolated可直接读取内核实际识别的隔离核心,这是判断隔离是否生效的核心依据,示例(隔离5、6核):

cat/sys/devices/system/cpu/isolated

预期输出

5-6

•配置单个核心7,预期输出为7;

•配置0、3、8,预期输出为0,3,8;

•配置非法/清空,该文件无任何输出,代表内核未隔离任何核心。

七、关键注意事项

1.双方案适配性:AB系统仅可使用android_ab.c集成方案,非AB系统仅可使用android_bootloader.c集成方案,不可交叉使用,否则配置不生效;

2.核心编号限制:仅支持0-8的数字组合,超出范围会触发兜底逻辑,仅启用rcu_nocbs=all;

3.任务手动绑定:CPU隔离后,内核不会主动调度任务到隔离核,需通过taskset/sched_setaffinity将关键任务手动绑定到隔离核,示例:

# 将程序绑定到5、6核运行taskset-c5,6./Linux1024_app

4.内核配置依赖:需确保Linux内核开启CONFIG_NO_HZ_FULL和CONFIG_RCU_NOCB_CPU,RK3588原厂SDK默认开启该配置,无需额外修改;

5.配置永久生效:vendor_storage为掉电非易失性存储,配置写入后永久保存,除非重新执行指令修改/清除;

6.无侵入式修改:所有隔离参数均为追加到原有bootargs,未修改SDK任何原生核心配置,保障系统兼容性与稳定性。

八、总结

本次基于RK3588原厂SDK实现的AB/非AB系统双方案CPU隔离,兼顾了灵活性、兼容性与实用性,核心价值体现在:

1.双方案一键套用:针对AB/非AB两种主流系统架构做专属适配,代码完整可直接复制,无需二次开发;

2.动态配置免重编:通过vendor_storage实现隔离核心的动态配置,无需反复编译固件,大幅提升开发效率;

3.安全兜底更可靠:完善的配置合法性校验,避免非法配置导致系统启动异常,提升产品量产可靠性;

4.无侵入式兼容:仅追加隔离参数,不修改SDK原生逻辑,完美兼容RK3588原厂固件与上层应用。

在工业控制、车载、边缘计算等高实时性场景中,将关键任务绑定到隔离核,可将RK3588的任务响应延迟降低50%以上,最大化发挥其8核异构架构的硬件性能。两套方案均经过实际验证,可直接落地到RK3588量产产品开发中。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    11332

    浏览量

    225939
  • RK3588
    +关注

    关注

    8

    文章

    592

    浏览量

    7568
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    麒麟适配 | 眺望电子上线 “RK3588+麒麟” 全功能主板

    的无限可能。RK3588麒麟全功能主板主板基于瑞芯微RK3588核心板,适配银河麒麟V10国产操作系统。集8K显示、5G互联、千兆网口、多路USB/串口于一身,打
    的头像 发表于 04-17 17:03 3204次阅读
    麒麟<b class='flag-5'>适配</b> | 眺望电子上线 “<b class='flag-5'>RK3588</b>+麒麟” 全功能主板

    技术分享 | RK3588如何搭建preempt_rt+ethercat

    说明:使用的RK3588的分支版本是linux-6.1-stan-rkr6内核版本是6.1.99,文件系统是DebianGNU/Linux12,把瑞芯微的SDK更新
    的头像 发表于 04-02 17:31 862次阅读
    技术分享 | <b class='flag-5'>RK3588</b>如何搭建preempt_rt+ethercat

    你的专属“数字员工”已到岗!迅为RK3588系列开发板适配OpenClaw

    你的专属“数字员工”已到岗!迅为RK3588系列开发板适配OpenClaw
    的头像 发表于 03-11 11:02 757次阅读
    你的专属“数字员工”已到岗!迅为<b class='flag-5'>RK3588</b>系列开发板<b class='flag-5'>适配</b>OpenClaw

    RK3588操控终端

    RK3588操控终端全国产化无人装备手持操控终端,搭载工业级瑞芯微RK3588J芯片,适配麒麟等自主操作系统,从硬件核心到软件应用实现 100% 国产化,彻底摆脱外部技术依赖。设备标配
    发表于 02-28 09:42

    你的专属“数字员工”已到岗!迅为RK3588系列适配OpenClaw

    你的专属“数字员工”已到岗!迅为RK3588系列适配OpenClaw
    的头像 发表于 02-27 15:33 826次阅读
    你的专属“数字员工”已到岗!迅为<b class='flag-5'>RK3588</b>系列<b class='flag-5'>适配</b>OpenClaw

    【硬核搭档】迅为RK3588成功适配飞牛FnNAS,你的私有云迎来性能猛兽!

    【硬核搭档】迅为RK3588成功适配飞牛FnNAS,你的私有云迎来性能猛兽!
    的头像 发表于 02-25 15:43 1058次阅读
    【硬核搭档】迅为<b class='flag-5'>RK3588</b>成功<b class='flag-5'>适配</b>飞牛FnNAS,你的私有云迎来性能猛兽!

    实战复盘:RK3588 SPI+PCIe3x4方案启动修复,从节点配置到驱动适配全解析

          在 RK3588 嵌入式项目中, “ 接口配置不匹配 ” 是高频踩坑点 —— 近期 基于 linux6.1 内核 调试 SPI 闪存 +PCIe3x4 外设 方案时,就遇到了 “eMMC
    的头像 发表于 01-08 10:24 772次阅读
    <b class='flag-5'>实战</b>复盘:<b class='flag-5'>RK3588</b> SPI+PCIe3x4<b class='flag-5'>方案</b>启动修复,从节点配置到驱动<b class='flag-5'>适配</b>全解析

    RK3588采集Cameralink图像快速搭建系统办法

    : CL-U3,便携式应用。 瑞芯微的RK3588开发板很多,种类各式各样。如何快速搭建一套自己的基于RK3588的嵌入式Cameralink图像采集处理方案呢。下面推荐一下。 快速原型机的搭建
    发表于 12-19 10:07

    基于迅为RK3588开发板实现高性能机器狗主控解决方案- AI能力实战:YOLOv5目标检测例程

    基于迅为RK3588开发板实现高性能机器狗主控解决方案- AI能力实战:YOLOv5目标检测例程
    的头像 发表于 11-28 11:32 1728次阅读
    基于迅为<b class='flag-5'>RK3588</b>开发板实现高性能机器狗主控解决<b class='flag-5'>方案</b>- AI能力<b class='flag-5'>实战</b>:YOLOv5目标检测例程

    系统适配 | RK3588 Ubuntu22.04正式发布

    前言:为了满足广大开发者与嵌入式爱好者的需求!眺望电子正式宣布,已完成基于瑞芯微RK3588的开发板对Ubuntu22.04LTS操作系统的深度适配与优化。此次适配不仅成功移植了
    的头像 发表于 09-05 12:06 2552次阅读
    <b class='flag-5'>系统</b><b class='flag-5'>适配</b> | <b class='flag-5'>RK3588</b> Ubuntu22.04正式发布

    RK3588数据手册

    RK3588的资料
    发表于 08-01 16:08 54次下载

    干货分享 | RK3588 Ubuntu系统Docker容器使用指南

    前言:在瑞芯微RK3588高性能AIoT平台上运行Ubuntu系统时,Docker容器技术能极大提升开发部署效率。通过轻量级虚拟化实现环境隔离与快速迁移,本文将从零开始详解RK3588
    的头像 发表于 06-27 12:01 4245次阅读
    干货分享 | <b class='flag-5'>RK3588</b> Ubuntu<b class='flag-5'>系统</b>Docker容器使用指南

    RK3576 vs RK3588:为何越来越多的开发者转向RK3576?

    ]项目RK3576RK3588 CPU4×Cortex-A72@2.2GHz + 4×A53@1.8GHz + M0 协处理器4×Cortex-A76@2.4GHz + 4×A55@1.8GHz 算力
    发表于 05-30 08:46

    RK3588参数与主要特性 RK3588数据手册解读

    RK3588参数与主要特性 RK3588数据手册解读
    的头像 发表于 05-19 18:34 1.5w次阅读
    <b class='flag-5'>RK3588</b>参数与主要特性  <b class='flag-5'>RK3588</b>数据手册解读

    RK3588S和RK3588S2差异说明

    RK3588S2 较 RK3588S少了一组 MIPI D/C-PHY CSI_RX PORT0,新增一组 MIPI DPHY CSI_RX PORT1,同时接口位置除 MIPI D/C-PHY
    的头像 发表于 05-13 14:23 3239次阅读
    <b class='flag-5'>RK3588</b>S和<b class='flag-5'>RK3588</b>S2差异说明