打印
[G32R]

来了来了 G32G501 可以用上 Zephyr 了

[复制链接]
97|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

[i=s] 本帖最后由 wangqy_ic 于 2025-7-4 18:31 编辑 [/i]<br /> <br />

#技术资源# #申请原创#

前言

这是一份移植 Zephyr 到 G32R501 的指南~

关于 Zephyr

我称之为当下全球最火爆的 RTOS 项目,官网:https://www.zephyrproject.org。以下引用来自官网的自述

What is the Zephyr Project? The Zephyr® Project is an open source scalable real-time operating system (RTOS) supporting multiple hardware architectures including ARC, ARM, RISC-V and X86. The Zephyr OS is a proven RTOS used in products today. Zephyr OS is modular and supports multiple architectures, developers can easily tailor an optimal solution to meet their needs. Zephyr OS is used in a broad spectrum of applications from simple connected sensors to complex edge systems. As an open source project, the community contributes to the evolution of Zephyr by adding support for new hardware, developer tools, sensors and device drivers. Enhancements in security, device management capabilities, connectivity stacks and file systems are easily implemented.

!

这个项目目前是托管在 Apache 基金会的一个开源 RTOS 项目。项目成员看包括多个知名的半导体厂商:Intel、Nordic、NXP、瑞萨、英飞凌、TI、ST 等,还有 Meta、Google 等知名互联网公司,我还在成员页看到 Honda ,没错就是本田。 这么多企业参与到其中,肯定是看好 Zephyr 这个项目本身。那这个项目的优势是啥呢?我自己的总结如下:

  • 开源:项目的参与者都可以用代码发声。充分利用社区的同时,也能向社区注入自己的影响,还能给自己的产品增加曝光度。
  • 基于 Devicetree+Kconfig 的开发模式,类似 Linux 开发,可以灵活地在多个型号 MCU 间实现最大程度的兼容。
  • 丰富的生态。八种处理器架构、750+开发板、220+传感器驱动,还有官方集成好的加密库,图形库,多种协议栈……失眠常见的几乎都有。

单是最后这一项,我就强烈推荐这个 RTOS。

关于 G32R501

极海微最新推出的,基于 Cortex-M52 的实时控制 MCU,官网:https://www.geehy.com。下面是引用自官网对这个 MCU 的介绍:

G32R5系列实时控制MCU搭载Arm v8.1-M架构的Arm® Cortex®-M52内核及自研紫电数学指令扩展单元,支持基于矢量扩充方案(MVE)的Arm HeliumTM技术,集成高性能感知,控制外设和灵活的外设互联系统,支持-40°C~105°/125°C的宽环境工作温度,适用于新能源逆变器、商业电源、工业自动化、新能源汽车等广泛领域。

Pastedimage20250626202137.png

本次移植的目的是把 Zephyr 带入 G32R501,让极海的新 MCU 也享用来自全球的热度~~~

移植前的一些说明

本文是移植指南,文中也会提及 Zephyr 的相关概念,但并不能全面的介绍 Zephyr 开发的基本知识,这一部分内容请参考官网文档,点此直达。

构建工具

Zephyr 使用 west+CMake 作为构建工具,开发工程师也需要具备的相关知识。west 是 Zephyr 项目的配套工具,Zephyr 官方文档也有相应说明。CMake 的部分,请自学 OMG~

编译器

关于编译器,有需要注意的点有:

  1. 对于 Zephyr 项目 ARM GCC 编译器的支持是相对完善的。对于 Cortex-M52 内核,需要使用最新的是 14.2,可以从这里下载:https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
  2. ARM Clang 编译器也是得到 Zephyr 的支持,但是我在移植过程中遇到了一些问题。虽然也能解决,但是调试确实是一个麻烦事。我个人不推荐。
  3. IAR 的工具链也是 Zephyr 支持,但同样在移植 G32R501 的过程中也遇到一些麻烦。需要重点关注的是,Zephyr 使用的 IAR 编译器是 IAR Build Tools for Arm,而不是常见的 workbench。可以从 https://github.com/iarsystems/arm/releases 这里下载使用。

基本概念

下面再介绍一些 Zephyr 开发的基本概念,便以后面的移植工作。

SOC

先介绍以下 Zephyr 关于 MCU 架构的一些规定。在 Zephyr 中有如下几个概念与具体的 MCU 相关,需要移植工程师关注:

  • SOC
  • SoC series
  • SoC family
  • CPU Cluster
  • CPU core
  • Architecture

具体参考官方文档 SoC Porting Guide 一节。官方文档中还有一张图和一个表格有助于理解上的几个概念,连接在此 :

2025-06-2711.07.59docs.zephyrproject.org9631ebd608d3.png

对应到移植对象 G32R501 应该是这样:

概念 对应内容
architecture Armv8.1-M
CPU core Cortex-M52
SoC family Geehy G32R
SoC Series G32R5
SoC G32R501
board qualifiers G32R501
board name G32R501 EVAL Board /G32R501 Micro-EVB

G32R501 是基于 Cortex-M52,Zephyr 暂时还不支持。从这个层次开始移植,工程量也非常巨大,我个人也没有能力完成。已知 Cortex-M52 属于 Armv8.1-M 一系,同系中 Zephyr 支持 Cortex-M55,我们就以此为基础修改,不再移植与处理器架构方面的内容。

Module

Module 可以理解为一个功能相对完整的”包“,可以是某个 lib 或者 SDK 。Module 遵循一定的规则组织提供配置、编译规则,可以通过 west 工具加入构建项目,如有必要也提供 Kconfig 等选项,具体可参考官方文档中Modules (External projects) 部分。

准备工作

一些约定

为了便于描述后续的移植工作,先约定一些内容。

  1. 工作目录:源码相关的目录都集中放在这个目录,设置环境变量 WORK_DIR 就是这个目录的路径。这个目录可以是其他目录,强烈建议目录路径不要有空格或者中文。我的机器上这个目录是 D:\zephyrproject。
  2. 必须的 Python 环境,使用虚拟环境,操作步骤后续会说明。
  3. Python 虚拟环境以及其他非源码相关的内容,统一放置在 D:\zephyrproject.asset 目录。与工作目录分开,也是为了保持工作目录整洁~同样的,这个目录也不是强制要求,可根据实际情况确定。

准备工作

准备工作就是搭建开发环境了,步骤是这样的:

  1. 安装依赖的软件工具
  2. 创建 Python 虚拟环境
  3. 安装 west
  4. 初始化工作目录
  5. 提高工作效率的小技巧
  6. 验证开发环境

下面详细说明搭建步骤:

首先安装依赖的软件工具

可参考官方文档 Install dependencies 一节。特别需要说明的时,如果你电脑上已经安装有 Python 但是版本低于 3.12,也建议安装 3.12 版本,后续我们会使用虚拟环境,多个版本的 Python 不影响开发工作。

第二步,创建 Python 虚拟环境

打开命令行窗口(cmd 或者 Powershell 都行,符合你习惯就好~后面没有特殊说明,都统一用命令行窗口指代)执行以下命令,并等待执行完成:

python -m venv D:\zephyrproject.asset\.venv

D:\zephyrproject.asset.venv 这就是虚拟环境所在目录。其父级目录就是 D:\zephyrproject.asset 前文约定3的内容。 使用 Python 肯定就会安装一些软件包,我们使用国内的软件源会方便一些,在命令行执行:

pip config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

上述是清华大学的软件园地址,你可以更换为其他源:

第三步,安装 west

移植的工作,需要在 Python 虚拟环境里操作,所以先要在命令行工具里激活虚拟环境。 如果使用 cmd ,请执行

D:\zephyrproject.asset\.venv\activate.bat

如果使用 Powershell ,请执行

D:\zephyrproject.asset\.venv\Activate.ps1

无论是 cmd 或者 Powershell,执行成功后命令提示符前都会多一个 (.venv),例如我用的是 Powershell 执行后的是这样的:

Pastedimage20250626213144.png

注意绿色的文字。cmd 窗口不会有颜色,也没有 PS 这两个字~

激活虚拟环境后,就可以使用 pip 安装 west。在命令行窗口执行:

pip install west

安装完成后,可以执行一下 west -V 命令,查看版本,正常输出版本号就表明安装正常。下面我们使用 west 初始化工作目录:

第四步,初始化工作目录

west init D:\zephyrproject

D:\zephyrproject 就是我们约定的工作目录。如果与你自己的工作目录不一致,请使用你的工作目录路径。

上面的命令会从 Github 拉取 zephyr 源码,请确保网络正常~

这个命令顺利执行后,我们就拥有了 zephyr 的源码。除此之外,还需要其他的 module,请执行下面的命令:

cd D:\zephyrproject
west update

这个命令也会从 Github 拉取 Module 的源码。命令执行完成后,工作目录也就初始化完成。

第五步,提高工作效率的小技巧

正式开始工作前,我们还需要设定一些环境变量,激活虚拟环境。每次都敲很多命令确实也挺麻烦的。所以我准备了一个脚本,用于启动命令行时配置开发环境。也分为 cmd 和 Powershell 两种,请根据你的命令行工具选择一个。

先上 cmd 的方法: 新建脚本 D:\zephyrproject.asset\setup_env.bat:

[@echo](home.php?mod=space&uid=3148) off

REM 设置环境变量,注意对应实际路径
set "ZEPHYR_BASE=D:\zephyrproject\zephyr"
set "ZEPHYR_TOOLCHAIN_VARIANT=gnuarmemb"
set "GNUARMEMB_TOOLCHAIN_PATH=D:\apps\arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi"

REM 把各个工具的可执行文件路径加入 PATH,如果它们不在 PATH 里~
set Path=C:\Program Files\Git\cmd;C:\Program Files\CMake\bin;C:\ProgramData\chocolatey\bin;%GNUARMEMB_TOOLCHAIN_PATH%\bin;C:\Program Files\SEGGER\JLink;%Path%

REM 激活虚拟环境,注意实际路径
call D:\zephyrproject.asset\.venv\Scripts\activate.bat

REM 显示各个工具版本号,以确认工具可用~
cmake --version
ninja --version
python -V
west --version

每次启动还需要输入这个脚本的路径,也不够便利,还有一招:“一键创建开发环境”。请按以下步骤操作:

  1. 打开文件管理器,切换到 D:\zephyrproject.asset 目录。
  2. 鼠标右键点击目录的空白处,选择【新建】→【快捷方式】。
  3. 在“请键入对象的位置”写 cmd 三个字,点击【下一步】。
  4. 在”键入该快捷方式的名称“处写 zephyrproject,点击【完成】。
  5. 回到文件夹里,能看到一个快捷方式,鼠标选中这个快捷方式。
  6. 点击右键选择【属性】,在”目标“处填入C:\Windows\System32\cmd.exe /K D:\zephyrproject.asset\setup_env.bat,在”起始位置“处填入D:\zephyrproject,点击【确定】。 完成后是这一个样子:

Pastedimage20250626225022.png

现在,鼠标双击这个快捷方式,就是一个配置好的 zephyr 开发环境了。这个快捷方式可以复制到其他地方,比如桌面~

下面说说 Powershell 的方法: Powershell 的脚本 D:\zephyrproject.asset\setup_env.ps1:

#

# 设置环境变量,注意对应实际路径
$env:ZEPHYR_BASE = "D:\zephyrproject\zephyr"
$env:ZEPHYR_TOOLCHAIN_VARIANT = "gnuarmemb"
$env:GNUARMEMB_TOOLCHAIN_PATH = "D:\apps\arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi"

# 把各个工具的可执行文件路径加入 PATH,如果它们不在 PATH 里~
$env:Path = "C:\Program Files\Git\cmd;C:\Program Files\CMake\bin;C:\ProgramData\chocolatey\bin;$env:GNUARMEMB_TOOLCHAIN_PATH\bin;C:\Program Files\SEGGER\JLink;$env:Path"

# 激活虚拟环境,注意实际路径
$venvPath = "D:\zephyrproject.asset\.venv\Scripts"
$activateScript = Join-Path -Path $venvPath -ChildPath "Activate.ps1"

& $activateScript

# 显示各个工具版本号,以确认工具可用~
cmake --version
ninja --version
python -V
west --version

创建快捷方式的步骤:

  1. 打开文件管理器,切换到 D:\zephyrproject.asset 目录。
  2. 鼠标右键点击目录的空白处,选择【新建】→【快捷方式】。
  3. 在“请键入对象的位置”写 powershell ,点击【下一步】。
  4. 在”键入该快捷方式的名称“处写 zephyrproject_ps,点击【完成】。
  5. 回到文件夹里,能看到一个快捷方式,鼠标选中这个快捷方式。
  6. 点击右键选择【属性】,在”目标“处填入C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoExit -File "D:\zephyrproject.asset\setup_env.ps1",在”起始位置“处填入D:\zephyrproject,点击【确定】。 完成后是这一个样子:

Pastedimage20250626230331.png

双击两个快捷方式,各自出现的窗口应该类似这样:

Pastedimage20250626230551.png

左边是 cmd,右边是 Powershell。需要提醒的是,我的系统安装了 Windows Terminal,这个终端会把 cmd 和 Powershell 都“装”在一个框里,与传统的命令行窗口不太一样,请忽略这个差异~

第六步,验证开发环境

开发环境搭建好了,除了向上面脚本末尾显示各个软件的版本号,我们还可以试着编译一个工程,看看必备的东西是否都齐全。 打开命令行(可以用上前面准备的快捷方式了~~~),执行:

west build -p -b stm32_min_dev[@blue](home.php?mod=space&uid=17879) zephyr\samples\hello_world

如果一切正常,你应该能看到类似的编译结果:

Pastedimage20250626231638.png

这个命令是编译一个程序:led 闪烁,开发板就是淘宝上常见的 stm32f103xb 开发板:

Pastedimage20250626231909.png

编译成功,你可以烧录看看运行效果。选择 j-link 进行烧录:

west flash -r jlink

至此,开发环境搭建完成,后续的内容就是实际的移植教程了。

移植-第一部分

根据本人的开发经验,把 zephyr 移植到一个全新的 MCU,大致的流程是:

  1. 创建基本的文件(夹)结构。
  2. 修改并确保能编译通过。
  3. 增加必要的驱动。
  4. 继续完善驱动,直至满足项目需求。

其中,第一步是非常难的。因为构建一个 zephyr 的步骤比较多,涉及的工具也不少,每个工具对输入的要求不一而足,导致这个构建系统事实上是一个比较繁杂的过程。也希望我的这些经验能帮助有需要的工程师,快速上手移植工作。

先介绍一个小贴士:在移植中完成“修改”→“编译验证”→“再修改”→“再验证”这样的“移植循环”,本质是:每个相对完整的修改,都要尽快编译验证。

第三步增加必要的驱动后,我们就可以点个灯之类的简单任务,剩余的就是测试和完善。

整个移植过程,会通过 git 进行管理,当然也会开放出来,供有需要的工程师使用。需要提前声明的一点是:这份移植说明和相关的代码,是本人再工作之余花费时间和精力总结、编写,未能对全部内容进行充分验证。如果要把这些内容使用到产品开发,请自行验证以确保各项功能完备。本人不提供任何担保,不承担因使用软件而产生的任何直接或间接损害的责任。

起手式

也就是第一部分的移植工作:创建基本的文件(夹)结构。由于涉及的内容较多,请按说明步骤完成。

前文提到,这个移植工作是以 module 形式组织,所以第一步就是创建符合 module 的文件结构。在工作目录(我这里是 D:\zephyrproject,下文不再赘述)创建文件夹 g32r5_zephyr 文件夹。移植代码就在这个文件夹完成,我们称之为“移植目录”,最开始的文件(夹)是这样的:

D:\zephyrproject
├─g32r5_zephyr
  ├─zephyr
    ├─module.yml

D:\zephyrproject\g32r5_zephyr\zephyr\module.yml 这个文件目前就只需要一行内容:

name: hal_g32r5

遵循“移植循环”,我们先验证这个 module 是不是有效的。进入开发环境(简单地说就是打开前文所述两个快捷方式的其中一个),切换到工作目录,执行一次编译:

west build -p -b stm32_min_dev[@blue](home.php?mod=space&uid=17879) zephyr\samples\hello_world -- -DZEPHYR_EXTRA_MODULES="D:\zephyrproject\g32r5_zephyr

这个编译命令与前文”第六步,验证开发环境“的命令类似,不同的是增加了” -- -DZEPHYR_EXTRA_MODULES="D:\zephyrproject\g32r5_zephyr“。增加的部分就是告诉构建工具(west),有一个附加的 module 需要处理。

如果一切正常,命令执行后 build 目录下有 zephyr_modules.txt 这样一个文件。你能在这个文件中找到类似下面这一行:

"hal_g32r5":"D:/zephyrproject/g32r5_zephyr":""

这样的内容表明我们确实创建了一个能被 west 识别的、完备的 module,虽然这个 module 没有任何实质内容:)

迈出的第一步,是成功的!值得庆贺。

创建一个简单的测试程序

为了方便移植工作,我们先加入一个简单的程序以便后续移植过程中可随时修改而不会改动 zephyr 源码。

在移植目录中创建 test 文件夹,把 zephyr\samples\hello_world 文件夹下的全部内容复制到这里。

另外,在后续的修改过程中大部分都需要清除现有构建内容重新配置、构建,为了避免每次都需要输入冗长的构建命令,我会在移植目录中创建一个脚本 do_build.bat 专用于启动重新构建:

[@echo](home.php?mod=space&uid=3148) off

setlocal enabledelayedexpansion

set "CURRENT_PATH=%~dp0"

set "PARENT_PATH=!CURRENT_PATH:~0,-1!"
set "PARENT_PATH=!parent_path:\=/!"

set "PROJECT_ROOT=%parent_path%/test"
set "BOARD=stm32_min_dev@blue"

echo ZEPHYR_EXTRA_MODULES: !PARENT_PATH!
echo ZEPHYR_TOOLCHAIN_VARIANT: !ZEPHYR_TOOLCHAIN_VARIANT!

REM Delete build directory
del build /q /f /s >NUL 2>&1

west build -p -b stm32_min_dev[@blue](home.php?mod=space&uid=17879) !PROJECT_ROOT! -- -DZEPHYR_EXTRA_MODULES=!PARENT_PATH!

endlocal

好了,现在工作目录,只需要执行:

g32r5_zephyr\do_build.bat

就可以进行一次全新的配置、构建。后续的移植工作中,我们会加入配套开发板的移植内容,到那时只需要修改 do_build.bat 文件的 BOARD 一行就可以重新构建~

增加 soc 相关内容

这一部分移植过程中最难的一步,准备的文件比较多,类型(格式)也相对繁杂。因为是一个整体的移植部分,若是每次修改或者增加文件都编译一次再排错,文章就会过于冗长。所以本节内容工会在整体介绍完成后才进行编译测试。

我会为这一个阶段移植的步骤增加标题增加序号,以便阅读。

1. 修改 g32r5_zephyr\zephyr\module.yml 文件

修改这个文件的目的是让 west 构建工具知晓移植目录里有新增的 soc 需要加入构建。修改后的文件应该是这样:

name: hal_g32r5
build:
  cmake: .
  kconfig: Kconfig
  settings:
    board_root: .
    dts_root: .
    soc_root: .

相较于之前的内容,新增了 build 及后续行。目的是告诉 west 工具,当前目录(其实是移植目录,这里很关键!)中有开发板和 soc 的相关内容,构建期间需要与 zephyr 源码目录的相关内容一起处理~

2. 增加 soc 目录

在移植目录下,创建 soc 两个目录,文件见名称不要随意修改,否则 west 工具会找不到~

soc 目录下的完整文件/文件夹是这样的:

│  CMakeLists.txt
│
└─geehy
    └─g32r5
        │  CMakeLists.txt
        │  Kconfig
        │  Kconfig.defconfig
        │  Kconfig.soc
        │  linker.ld
        │  soc.yml
        │
        ├─common
        │      CMakeLists.txt
        │      pinctrl_soc.h
        │
        └─g32r501
                CMakeLists.txt
                Kconfig.soc
                soc.c
                soc.h

文件不少,下文会重点介绍文件的用途和关键内容,完整内容请直接查看源码。

→ g32r5_zephyr\soc\CMakeLists.txt 这个文件是说明 soc 目录如何加入构建。其他 CMakeLists.txt 文件的用途相同,不再赘述。

→ g32r5_zephyr\geehy\g32r5 这个目录结构对应前文“基本概念”里的知识,如不理解,请返回阅读。

→ g32r5_zephyr\geehy\g32r5\Kconfig 这个文件定义了 SOC-Family 的配置项,也同时选定了依赖的项目,文件关键内容如下:

config SOC_FAMILY_G32R5
    bool
    select BUILD_OUTPUT_HEX
    select USE_G32R5_HAL
    select CPU_HAS_ARM_MPU
    select CPU_HAS_MPU
    select CPU_HAS_FPU
    select ARMV8_M_DSP

以上内容的目的是:定义了 SOC_FAMILY_G32R5 及依赖配置项,也就是使用 G32R5 这个 SOC_FAMILY 的话,必须还要选择 select 条目列明的所有项。需要特别说明的是除 USE_G32R5_HAL 都是 zephyr 本身定义的配置项,USE_G32R5_HAL 这个项目是我们移植的一部分。

→ g32r5_zephyr\geehy\g32r5\Kconfig.defconfig 这个文件是可选的。它的目的是选定一些关于 G32R5 的可选项~有点拗口哈。当前可以保持是一个没有内容的空文件。

→ g32r5_zephyr\geehy\g32r5\Kconfig.soc 这个文件主要内容是:

config SOC_FAMILY
    default "g32r5" if SOC_FAMILY_G32R5

config SYS_CLOCK_HW_CYCLES_PER_SEC
    int
    default 240000000 if SOC_FAMILY_G32R5

rsource "*/Kconfig.soc"

config SOC_FAMILY 一行的作用是提供一个字符串类型的配置项,主要目的提供一个 CONFIG_SOC_FAMILY 的全局宏定义,配置,构建过程都会用到。

config SYS_CLOCK_HW_CYCLES_PER_SEC 一行定义了硬件系统时钟频率,这里先写一个固定的数值,后面可以修改为从 DeviceTree 的内容获取。

最后一行是遍历全部子目录中的 Kconfig.soc 文件,如果有的话~对于本项目的移植只有 g32r5_zephyr\geehy\g32r5\g32r501\Kconfig.soc 这个文件。

→ g32r5_zephyr\geehy\common 目录是 G32R5 这个 Family 公用的一些资源。

→ g32r5_zephyr\geehy\g32r5\g32r501 这个目录的内容也就是对应 g32r501 这个 soc-series。

→ g32r5_zephyr\soc\geehy\g32r5\g32r501\Kconfig.soc 定义 g32r501 这个 soc-series 以及这个 series 下具体的 soc,主要内容是:

config SOC_SERIES_G32R501
    bool "G32R501 Series MCU"
    select ARM
    select SOC_FAMILY_G32R5
    select CPU_HAS_FPU
    select CPU_CORTEX_M55
    select ARMV8_1_M_MVEI
    select ARMV8_1_M_MVEF

    help
      Enable support for Geehy G32R501 MCU series

config SOC_SERIES
    default "g32r501" if SOC_SERIES_G32R501

config SOC_G32R501DVXT
    bool "G32R501DVXT"
    select SOC_SERIES_G32R501

config SOC_G32R501DRXT
    bool "G32R501DRXT"
    select SOC_SERIES_G32R501

# ...

config SOC
    default "g32r501dvxt" if SOC_G32R501DVXT
    default "g32r501drxt" if SOC_G32R501DRXT
    default "g32r501dmxt" if SOC_G32R501DMXT
    default "g32r501dnxt" if SOC_G32R501DNXU

config FLASH_SIZE
    default 256

config SRAM_SIZE
    default 16

config FLASH_BASE_ADDRESS
    default 0x08000000

config SRAM_BASE_ADDRESS
    default 0x20000000

config NUM_IRQS
    default 227

config SOC_SERIES_G32R501 定义了 G32R501 这个 SOC-SERIES(这个概念请回顾前文)。这里可以看出我们是基于 Cortex-M55 这个核而不是 Cortex-M52 ,之所以这样做,前文也有提到:zephyr 尚未支持 Cortex-M52,架构移植难度我目前尚未掌握。而 M52 和 M55 同处一系,只是某些特性有差异。而这一部分差异不影响目前的移植工作,所以就直接基于 M55 进行移植开发。文件的后续,定义了具体的 MCU 型号以及 Flash-Size 等必要的信息。

→ g32r5_zephyr\soc\geehy\g32r5\g32r501\soc.c/.h 这两个 c 源码是本系列 soc 的必须的基础源码,特别是 soc.h 一定不能省略,很多 zephyr 底层代码会包含这个头文件。

soc.h 文件不能缺,内容可以很简单:

#ifndef SOC_H_
#define SOC_H_

#include <g32r501.h>

#endif /* SOC_H_ */

没错,有效内容就一行,包含 SDK 中 G32R501 对应的头文件。

soc 目录的介绍到此未知,内容其实繁杂,可以结合代码仓库的实际文件加深理解。

3. 增加 dts 目录

dts 相关的文件,是 DeviceTree 的“配料表”,dtc 工具会根据一系列 dts 文件处理生成完整的 DeviceTree、相关头文件供后面的编译。

dts 文件除了 .dts 扩展名的文件外,还有 .dtsi 文件,类似 .h 文件之于 .c 文件。

在移植目录创建文件夹多级的文件夹:dts\geehy\g32r5 ,并在这个文件夹下创建文件 g32r501.dtsi 主要内容:

#include <arm/armv8.1-m.dtsi>
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/gpio/gpio.h>
#include <zephyr/dt-bindings/adc/adc.h>
#include <freq.h>
#include <mem.h>

/ {
    cpus {
        #address-cells = <1>;
        #size-cells = <0>;

        cpu0: cpu[@0](home.php?mod=space&uid=2514928) {
            compatible = "arm,cortex-m52";
            reg = <0>;
            #address-cells = <1>;
            #size-cells = <1>;
            clock-frequency = <DT_FREQ_M(168)>;

            mpu: mpu@e000ed90 {
                compatible = "arm,armv8m-mpu";
                reg = <0xe000ed90 0x40>;
            };
        };
    };
};

&nvic {
    arm,num-irq-priority-bits = <4>;
};

很简练的内容,也只说明了内核的一些信息。

4. 加入 SDK

这一步会把官方针对 G32R501 的 SDK 加入到工程中。由于没有找到官方的代码仓库,这里引用了 Gitee 上的一个仓库。

这里要补充一下,移植的工程是使用 git 管理。在移植目录执行命令可以创建 git 仓库:

git init .

然后使用这个命令引入 SDK:

git submodule add https://gitee.com/quincyzh/hal_geehy_g32r501.git sdk/g32r501

成功拉取代码后,移植目录会出现 sdk\g32r501 这个目录。

为了能使 SDK 能加入到编译中,我们需要增加两个 CMakeLists.txt 和两个 Kconfig 文件。两组文件的其中一组是在移植目录,另一组使在 sdk 目录。 移植目录下的 CMakeLists.txt:

# G32R5

add_subdirectory_ifdef(CONFIG_SOC_FAMILY_G32R5 sdk)
zephyr_include_directories_ifdef(CONFIG_SOC_FAMILY_G32R5 include)

移植目录下的 Kconfig:

# Kconfig
rsource "sdk/Kconfig"

有效内容是引用 sdk/Kconfig

sdk 目录下的 CMakeLists.txt:

# sdk/CMakeLists.txt

zephyr_library()

zephyr_compile_definitions(
    -D__ARM_ARCH_8_1M_MAIN___ 
    -D__ARM_TARGET_COPROC 
    -D__G32R501__  
    -D__G32R501XX__ 
    -D__CORE_CPU0__
)

zephyr_include_directories(g32r501/device_support/g32r501/common/device/Geehy)
zephyr_include_directories(g32r501/device_support/g32r501/common/device/CMSIS/Core/Include)
zephyr_include_directories(g32r501/device_support/g32r501/common/device/Geehy/system_eval/include)
zephyr_include_directories(g32r501/driverlib/g32r501/driverlib)
zephyr_include_directories(g32r501/device_support/g32r501/headers/include)

file(GLOB_RECURSE HAL_SOURCES
    g32r501/driverlib/g32r501/driverlib/*.c
)

# Remove some files
set(BLACKLIST_HAL_SOURCES
 "${CMAKE_CURRENT_SOURCE_DIR}/g32r501/driverlib/g32r501/driverlib/interrupt.c"
)

list(REMOVE_ITEM HAL_SOURCES ${BLACKLIST_HAL_SOURCES})

zephyr_library_sources(${HAL_SOURCES})

SDK 下的 Kconfig 文件是个空文件~保留它主要是为了后面增加功能。

这两个 CMakeLists.txt 文件把 SDK 目录下的相关文件加入到构建中,还增加了必要的宏定义。其中需要注意的有两点:

  1. zephyr_ 开头的函数,均是 zephyr 扩展的内容而不是 cmake 内建函数。
  2. _ifdef 结尾的函数,会在执行构建检查,只有第一个参数代表的变量已经定义的情况下才会执行。而第一个参数由 Kconfig 工具依据 Kconfig 选项文件解析得到。

5. 增加开发板相关内容

我们移植的开发板是 G32R501 Micro-EVB:

Pastedimage20250701213036.png

文档在此,这个板子的主要资源有:

  • 板载 CMSIS-DAP 兼容仿真器:Geehy-Link调试器 x1
  • 外设资源:
    • RESET KEY x1
    • LED x2
    • 40-pin ExpandPack接口 x1

移植步骤: 在移植文件夹,创建目录 boards\geehy\g32r501_micro_evb,新建如下文本文件:

board.yml
    g32r501_micro_evb.dts
    g32r501_micro_evb.yaml
    g32r501_micro_evb_defconfig
    Kconfig.defconfig
    Kconfig.g32r501_micro_evb

各个文件的具体内容请参考代码仓库,这里介绍一下 g32r501_micro_evb.dts

/dts-v1/;
#include <geehy/g32r5/g32r501.dtsi>

/ {
    model = "Geehy G32R501 Eval";
    compatible = "geehy,g32r501";

    chosen {
        zephyr,flash = &flash0;
    };
};

文件的 include 一行,就包含了我们之前编写的 dtsi 文件,至此我们就可以进行编译了~

6. soc 的初始化

每个 MCU 都有一些必要的初始化工作,以确保复位后软件系统也能处于一个确定的状态。

对于 G32R501 soc 最基本的初始化工作必须包括:

  • 使能 CP12 协处理器功能:G32R501 的“写寄存器保护(WRPRT)”功能依赖协处理器。
  • 禁用看门狗:G32G501 看门狗默认是开启的,暂时先关闭~ 具体可以参考 G32R501 的用户手册。

找到 soc\geehy\g32r5\g32r501\soc.c 文件,这个文件是个空文件,我们加入以下内容:

#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include "soc.h"

#if defined(CONFIG_SOC_PREP_HOOK)

// execute before z_bss_zero and z_data_copy(C runtime initialize)
void soc_prep_hook(void)
{
    // Enable CP0 Full Access and CP0 Non-secure Access
    SCB->CPACR |= (3U << 0U*2U);
    SCB->NSACR |= (3U << 0U*2U);

    // Enable WRPRT Protection COP
    SCB->CPACR |= 0xC;

    __DSB();
    __ISB();

    // Disable the Watchdog Timer
    __wrprt_disable();
    WD->WDCR = (0x5U << WD_WDCR_WDCHK_Pos) |
               (0x1U << WD_WDCR_WDDIS_Pos);
    __wrprt_enable();
}

#endif /* CONFIG_SOC_PREP_HOOK */

soc.c 的主要功能就是上面所述的两点。

另外,从源码可以看出,这个函数是在宏 CONFIG_SOC_PREP_HOOK 已经定义的情况下才会被编译。前面提到过 CONFIG_ 这一类宏都是 Kconfig 工具生成的,所以要到 Kconfig 文件去处理,有两种方法可以使能这个宏:

  • 一是在工程级别的 Kconfig 文件使能这个选项
  • 二是在 soc 级别的 kconfig 文件中直接启用这个选项

因为这个特性是 soc 相关的,所以直接在 soc 相关文件直接启用这个选项,具体的方法是修改 soc\geehy\g32r5\g32r501\Kconfig.soc 这个文件:

config SOC_SERIES_G32R501
    bool "G32R501 Series MCU"
    select ARM
    select SOC_FAMILY_G32R5
    select CPU_HAS_FPU
    select CPU_CORTEX_M55
    select ARMV8_1_M_MVEI
    select ARMV8_1_M_MVEF

    select SOC_PREP_HOOK

在 SOC_SERIES_G32R501 这个选项下增加 select SOC_PREP_HOOK,这样就可以了~

最简答的 soc 的初始化工作完成,下面我们编译测试~

6. 简单测试

修改移植目录下 do_build.bat 文件中的 BOARD :

[@echo](home.php?mod=space&uid=3148) off
setlocal enabledelayedexpansion

set "CURRENT_PATH=%~dp0"
set "PARENT_PATH=!CURRENT_PATH:~0,-1!"
set "PARENT_PATH=!parent_path:\=/!"
set "PROJECT_ROOT=%parent_path%/test"
set "BOARD=g32r501_micro_evb"

echo ZEPHYR_EXTRA_MODULES: !PARENT_PATH!
echo ZEPHYR_TOOLCHAIN_VARIANT: !ZEPHYR_TOOLCHAIN_VARIANT!

REM Delete build directory
del build /q /f /s >NUL 2>&1

west build -p -b !BOARD! !PROJECT_ROOT! -- -DZEPHYR_EXTRA_MODULES=!PARENT_PATH!

endlocal

是的,把 BOARD 改为我们定义的开发板名称:g32r501_micro_evb

然后,执行这个脚本:

Pastedimage20250701223248.png

上图是我编译的结果,显然成功了。两个红色框显示已经使用了新定义的开发板。

这个编译成功的程序,是可以下载并执行的,虽然看不出任何动静。

启动调试,可以看到代码运行到 main 函数。不要小看进入到 main 的这个过程,zephyr 系统的启动过程其实还是比较复杂的,main 函数是系统内置的一个任务(task)。进入到 main 函数已经说明系统已经初始化完成,包括:C 运行时环境,zephyr 内核,已经定义好的驱动……所以,调试中能进入 main 证明我们上面的移植是成功的。

小结

移植工作进行到这里,最基本移植工作就算是完成了。

这一部分难度也是比较高:我们借用了 Cortex-M55 架构的内容,把 Zephyr 内核移植到 G32R501 这一新的 MCU。虽然时钟还未正确初始化,系统滴答频率肯定不准确,但是它真的跑起来了。接下来,我们需要移植更多的驱动程序:时钟、GPIO、UART 等,我们将在第二部分介绍。

最后,移植的内容已经公开在 gitee 的代码仓库。可以在代码仓库中查看“增加 soc 驱动”那一次提交。代码仓库: https://gitee.com/quincyzh/g32r5_zephyr

第一部分到此,敬请期待第二部分。

使用特权

评论回复
沙发
wangqy_ic|  楼主 | 2025-7-4 18:30 | 只看该作者
@21小跑堂 Markdown 编辑器,怎么添加 #技术资源# #申请原创#

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:感恩的心对人。

20

主题

107

帖子

4

粉丝