.. _soc_porting: ================ SoC 移植指南 ================ 本文档介绍如何向 ARCS SDK 添加新的 SoC 支持。完成本指南后,新 SoC 可通过板型 Kconfig ``select`` 自动绑定,无需额外的 CMake 硬编码。 概述 ==== SDK 的 Board→SoC 绑定机制基于 **Kconfig select + soc.cmake 自注册** 模式: 1. Board Kconfig 通过 ``select SOC_`` 声明所使用的 SoC 2. Kconfig 解析后,CMake 扫描 ``soc/`` 目录下的 ``soc.cmake`` 文件 3. 根据 ``CONFIG_SOC_`` 的值自动推导 ``CHIP`` 变量 :: Board Kconfig Kconfig 解析 CMake 扫描 soc.cmake select SOC_ARCS ───► CONFIG_SOC_ARCS=y ───► CHIP=arcs │ ▼ arcs-chip.cmake arcs-toolchain.cmake SoC 目录结构 ============ 新增 SoC 需要在 ``soc/`` 目录下创建以下结构: :: soc/ └── / ├── soc.cmake # SoC 自注册文件(必需) └── hal/ ├── Kconfig # SoC Kconfig 配置(必需) ├── CMakeLists.txt # HAL 构建配置 └── ... # HAL 源码与头文件 同时需要在 ``cmake/`` 目录下提供对应的芯片和工具链配置: :: cmake/ ├── -chip.cmake # 芯片编译选项 └── -toolchain.cmake # 工具链配置 移植步骤 ======== Step 1: 创建 soc.cmake ----------------------- 在 ``soc//`` 目录下创建 ``soc.cmake`` 文件,声明 Kconfig 符号与 CHIP 名称的映射: .. code-block:: cmake set(SOC_KCONFIG_SYMBOL "SOC_MYSOC") set(SOC_CHIP_NAME "mysoc") .. list-table:: :widths: 30 70 :header-rows: 1 * - 变量 - 说明 * - ``SOC_KCONFIG_SYMBOL`` - 对应 Kconfig 中 ``config SOC_`` 的符号名(不含 ``CONFIG_`` 前缀) * - ``SOC_CHIP_NAME`` - 用于定位 ``cmake/-chip.cmake`` 和 ``cmake/-toolchain.cmake`` 的名称 Step 2: 编写 HAL Kconfig ------------------------- 在 ``soc//hal/Kconfig`` 中定义 SoC 特定的配置项: .. code-block:: kconfig menu "MySoC HAL" config MYSOC_CLOCK_FREQ int "System clock frequency (Hz)" default 160000000 # ... 其他 SoC 配置项 ... endmenu .. note:: HAL Kconfig **不需要** 定义 ``SOC_`` 符号或添加 ``if`` 守卫。``SOC_`` 的定义和可见性守卫由父仓库 ``soc/Kconfig`` 统一管理,HAL 子仓库只关注自身的配置项。 Step 3: 注册 Kconfig 到 soc/Kconfig ------------------------------------- 在 ``soc/Kconfig`` 中定义 ``SOC_`` 符号,并用 ``if`` 守卫包裹 HAL Kconfig 引用: .. code-block:: kconfig config SOC_ARCS bool if SOC_ARCS rsource "arcs/hal/Kconfig" endif # SOC_ARCS config SOC_MYSOC bool if SOC_MYSOC rsource "mysoc/hal/Kconfig" endif # SOC_MYSOC ``SOC_`` 定义为不带 ``default`` 的 ``bool``,由 Board Kconfig 通过 ``select`` 激活。``if`` 守卫确保仅在对应 SoC 被选中时才加载其 HAL 配置,避免多 SoC 间冲突。 使用 ``rsource``(相对路径静态引用),不要使用 ``osource``,以避免对环境变量的依赖。 Step 4: 创建板型并绑定 SoC --------------------------- 在 ``boards//Kconfig`` 中通过 ``select`` 声明该板型使用的 SoC: .. code-block:: kconfig config BOARD_NAME string default "my_board" prompt "Board Name" help Board Name config BOARD_MY_BOARD bool default y select SOC_MYSOC help Board is my_board ``select SOC_MYSOC`` 确保选择该板型时自动启用对应的 SoC 配置。 .. note:: 板型目录下 **不需要** ``board.cmake`` 文件。SoC 绑定完全通过 Kconfig ``select`` 机制完成。 Step 5: 提供芯片和工具链 CMake 配置 ------------------------------------- 在 ``cmake/`` 目录下创建两个文件: **-chip.cmake** — 芯片编译选项: .. code-block:: cmake # 芯片特定的编译定义、头文件路径等 listenai_include_directories( ${ARCS_SDK_BASE}/soc/mysoc/hal/include ) add_compile_definitions( __MYSOC__ ) **-toolchain.cmake** — 工具链配置: .. code-block:: cmake # 工具链路径、架构标志等 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv32imc") .. note:: 可参考现有的 ``cmake/arcs-chip.cmake`` 和 ``cmake/arcs-toolchain.cmake`` 作为模板。 验证 ==== 完成上述步骤后,按以下方式验证: .. code-block:: shell # 编译测试 ./build.sh -C -S samples/helloworld -DBOARD=my_board # 检查构建日志中的 CHIP 来源 # 期望输出: "CHIP=mysoc (from CONFIG_SOC_MYSOC via soc.cmake)" # 验证 CLI 覆盖仍可用 ./build.sh -C -S samples/helloworld -DBOARD=my_board -DCHIP=mysoc # 验证 menuconfig 正常 ./build.sh -S samples/helloworld -t menuconfig -DBOARD=my_board 完整清单 ======== .. list-table:: :widths: 40 15 45 :header-rows: 1 * - 文件 - 操作 - 说明 * - ``soc//soc.cmake`` - 新建 - Kconfig 符号 → CHIP 映射 * - ``soc//hal/Kconfig`` - 新建 - SoC HAL 配置项(无需定义 ``SOC_``) * - ``soc/Kconfig`` - 追加 - 定义 ``SOC_`` + ``if`` 守卫 + ``rsource`` 引用 * - ``boards//Kconfig`` - 新建 - ``select SOC_`` 绑定 SoC * - ``cmake/-chip.cmake`` - 新建 - 芯片编译选项 * - ``cmake/-toolchain.cmake`` - 新建 - 工具链配置 CHIP 解析优先级 ================ 构建系统按以下优先级确定 ``CHIP`` 值: 1. **命令行** ``-DCHIP=`` — 最高优先级,直接覆盖 2. **Kconfig 推导** — 扫描 ``soc/*/soc.cmake``,匹配 ``CONFIG_SOC_=y`` 自动设置 若两者均未匹配,构建系统会报错并提示检查板型 Kconfig 的 ``select`` 配置。