[开发生态] 移植 Zephyr-RTOS 至 国民技术 MCU

[复制链接]
836|7
手机看帖
扫描二维码
随时随地手机跟帖
wangqy_ic|  楼主 | 2022-2-15 13:13 | 显示全部楼层 |阅读模式
本帖最后由 wangqy_ic 于 2022-2-15 13:13 编辑

#申请原创#
@21小跑堂
Zephyr-RTOS 简介
Zephyr Project 是托管于 Linux 基金会的一个嵌入式相关项目。主要的目标是提供一个供小型嵌入式系统使用的实时操作系统系统(Zephyr-RTOS),以及相关的工具软件(west 等)。

官网:https://www.zephyrproject.org/
官方介绍:

The Zephyr OS is based on a small-footprint kernel designed for use on resource-constrained and embedded systems: from simple embedded environmental sensors and LED wearables to sophisticated embedded controllers, smart watches, and IoT wireless applications.

Zephyr-RTOS 的开发,类似 Linux 系统/应用程序的开发,包括 KConfig Devicetree 等工具。

Zephyr-RTOS 的特性有:
  • 多种内核服务:多任务,动态内存管理,线程同步,电源管理等
  • 多种调度算法:协作式和抢占式调度,时间片,最早截止日期优先等
  • 高度可配置
  • 支持多种处理器架构:ARM,ARM64,RISC-V,Xtensa,X86……
  • 内存保护
  • 编译期间定义资源(这个不好翻译,作用是可以有效缩小固件尺寸)
  • 设备驱动模型
  • 支持 Devicetree
  • 原生的网络协议栈,支持多种网络协议
  • BLE 5.0
  • 原生支持 Linux, macOS,     Windows 开发
  • VFS 支持(LittleFS 和 FATFS)
  • 强大的日志系统
  • 功能完善的 Shell
  • NVS 支持
  • 兼容 POSIX

这么多的特性,全用上的话,固件尺寸当然也不会太小……

缘起
据我了解,这个操作系统目前在国内使用也不是很广泛,相对于 FreeRTOSRT-Thread 等更是知者甚少。

我大概是在
2018 年接触到这个系统,对于它非常接近 Linux 系统的开发方式,觉得非常有意思,就一直保持着兴趣。

2021
年起,我逐渐在工作中引入了这个系统,并且成功使用在 STM32 的系统上运行一直非常稳定。灵活的配置方式,也非常便于切换到新的硬件系统。

去年底,因为项目需要我们打算切入国产
MCU。经过评估,我们选择了国民技术的 MCU。对于国内的 MCUZephyr 目前官方支持的只有兆易创新(gigadevice)和乐鑫科技(espressif)的一部分热门 MCU。看到 21IC 和国民技术在搞活动,也也就有了这个移植项目。


国民技术简介
官网:https://www.nationstech.com/
官方介绍
国民技术股份有限公司于2000年源于国家“909”集成电路专项工程成立,2010年创业板上市(股票代码:300077),是中国安全芯片、通用MCU领军企业,国家级**技术企业,拥有国内首个企业独立安全芯片攻防技术实验室,博士后科研工作站。总部位于深圳,在北京、上海、武汉、西安、香港、新加坡等地设有分支机构。主营产品包括:安全芯片、通用MCU、可信计算芯片、智能卡芯片、非接读写芯片、蓝牙芯片、RCC创新产品等,广泛应用于网络安全认证、电子银行、电子证照、移动支付与移动安全、物联网、工业联网及工业控制、智能家电及智能家庭物联网终端、消费电子、电机驱动、电池及能源管理、智能表计、医疗电子、汽车电子、安防、生物识别、通讯、传感器、机器自动化等应用方向。

移植目标
我在活动中申请拿到的开发板是 N32G45XVL-STBMCU N32G457VEL7,所以移植的目标是 N32G4567 系列。


移植过程介绍
准备工作
开发 Zephyr-RTOS 至少需要:CMakeNinjaPythonGit以及编译套件(我使用的是 GNU ARMEmbedded)。具体安装方法,可以参考官方的说明:https://docs.zephyrproject.org/latest/getting_started/index.html,也可以参考我自己整理的简要说明:https://www.yuque.com/quincy/zephyr/gyq03s。
确保开发环境正常,就可以正式的移植工作。


一些说明
在我看来,Zephyr-RTOS 的灵活性有一个重要的体现 Out-of-tree-development:在 Zephyr-RTOS 主干代码外进行开发。大白话就是移植和开发的工作完全独立于Zephyr-RTOS 的官方代码,不会影响和干扰官方代码。


我的移植工作就是基于这种特性,而不需要在 Zephyr-RTOS 的代码中开新的分支,也不会存在代码合并等一系列麻烦事。


代码目录介绍
代码已经在 Gitee 上的仓库:https://gitee.com/quincyzh/zephyr-rtos-for-n32-mcu欢迎点赞。另外有个彩蛋,我实际使用的是 N32WB031 系列芯片,所以代码仓库也包含 N32WB031 系列芯片的移植。这个是不是可以奖励双倍 @21小跑堂 2本文只是介绍 N32G4567 的移植。



代码目录结构:
boards         :开发板代码
CMakeLists.txt :CMake 配置文件
drivers        :适配 Zephyr 驱动代码
dts            :Devicetree 支持
hal_library    :国民技术提供的代码库
include        :头文件目录
Kconfig        :KConfig 配置文件
modules        :Zephyr 构建配置
README.md      :README 文件
soc            :N32 SOC 移植代码
zephyr         :Zephyr 构建配置


移植说明
主要步骤:

  • 创建代码目录
  • SOC 相关代码
  • 驱动相关代码
  • 开发板相关代码
  • 测试


1. 创建代码目录
代码目录介绍一节介绍,建立目录及相关文件。各个文件的目录,后续会说明。


2. SOC 相关代码
SOc 目录的详细结构如下:
├─soc
│  └─arm
│      └─nationstech_n32
│          ├─common
│          ├─n32g4
│          └─n32wb03

这个目录结构是按 Zephyr 要求建立,不能随意调整,否则不能编译。
soc/arm/nationstech_n32/n32g4目录及其内容就是对应 N32G4567 这个 MCU,内容有:
CMakeLists.txt
Kconfig.defconfig.n32g457x
Kconfig.defconfig.series
Kconfig.series
Kconfig.soc
linker.ld
soc.c
soc.h

Kconfig 一系列文件,是 KConfig 配置文件,目的是向 KConfig 系统提供与 N32G4567 相关的配置项目.
CMakeLists.txt CMake 配置文件,决定那些文件参与构建.
linker.ld 是链接说明,这个文件是从 Zephyr 代码库复制而来,基本上每个架构的 MCU 都差不多。
soc.c soc.h MCU 最基本的初始化代码,这里主要是初始化基本的时钟系统。soc.c 的主要代码:
static intn32g0_init(const struct device *arg)
{
    uint32_t key;
    ARG_UNUSED(arg);
    key = irq_lock();
    SystemInit();
    NMI_INIT();
    irq_unlock(key);
    SystemCoreClockUpdate();
    return 0;
}

这个目录内容正确的话,会在配置期间看到以下两个的效果。

一是在
Soc/CPU/Configuration Selection 目录下可以看到 N32G4 Series MCU
soc-kconfig-mcu-series.png


二是在 Hardware Configuration → N32G4 MCU Selection 目录下可以看到类似内容:
soc-kconfig-mcu-selection.png
需要注意的是:这些选项默认是隐藏的,要按键盘 "A" 才会显示。

file:///C:/Users/Zoro/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png
其他的驱动适配,结构基本相当,不再赘述。具体可参见代码仓库:https://gitee.com/quincyzh/zephyr-rtos-for-n32-mcu。需要注意的点是,每种驱动的 api 结构定义是不一样的,可参考 Zephyr driver 文件在的各种平台的实现。

3. 驱动相关代码
目前已经实现驱动 clock_ctrl, pinmux, GPIO, Uart 这四个驱动。这里已 clock_ctrl 为例,说明移植的步骤。

创建文件夹 drivers\clock_control,创建3个文件:
  • drivers\clock_control\clock_control_n32.c
  • drivers\clock_control\CMakeLists.txt
  • drivers\clock_control\Kconfig
  • drivers\CMakeLists.txt


drivers\clock_control\clock_control_n32.c 文件是适配 Zephyr 系统的驱动框架,主要代码:
static const struct clock_control_driver_api n32_cc_api = {
        .on = n32_cc_on,
        .off = n32_cc_off,
        .get_rate = n32_cc_get_subsys_rate,
};

static int n32_cc_init(const struct device *dev)
{
        return 0;
}

DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
                                 &n32_cc_init,
                                 NULL,
                                 NULL, NULL,
                                 PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
                                 &n32_cc_api);


  • n32_cc_api 这个结构体是填充相关的操作 api 函数指针;
  • n32_cc_init 函数是时钟初始化
  • DEVICE_DT_DEFINE 这个宏,是向系统注册 clock_ctrl 设备。


系统启动期间,这些内容是这样使用的:
1. 依据优先级,DEVICE_DT_DEFINE 宏里的 PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY。
2. 调用设备注册的初始化函数,也就是 n32_cc_init。
3. 使用相关 API 时,就会调用 n32_cc_api 结构体的那些函数(指针)。例如 获取某个子系统的时钟频率就是这样调用:clock_control_get_rate(cc_dev, subsys, &rate); 这个函数最终会调用 n32_cc_get_subsys_rate。

drivers\clock_control\CMakeLists.txt 文件是 CMake 配置文件,决定构建内容:
zephyr_library_amend()

zephyr_library_sources_ifdef(CONFIG_CLOCK_CTRL_N32 clock_control_n32.c)



zephyr_library_amend 函数会把这个目录下的代码,链接至驱动相关代码块。

drivers\clock_control\Kconfig 是KConfig 配置文件。
menuconfig CLOCK_CTRL_N32
        bool "CLOCK_CTRL Driver for N32 family of MCUs"
        depends on SOC_FAMILY_N32
        select USE_NS_STD_LIB_RCC
        help
          Enable CLOCK_CTRL driver for N32 MCUs


这个会增加一个配置目录,让用户选择是否启用该配置。实际的效果是在配置界面中 Modules → Nationstech N32 Porting 目录下,看到如下,空格键切换是否启用:
clock_ctrl.png

其他的驱动适配,结构基本相当,不再赘述。具体可参见代码仓库:https://gitee.com/quincyzh/zephyr-rtos-for-n32-mcu 。需要注意的点是,每种驱动的 api 结构定义是不一样的,可参考 Zephyr 的 driver 文件在的各种平台的实现。

4. 开发板相关代码
boards\arm\n32g45xvl_stb目录就是 N32G45XVL-STB这个开发板的配置说明:
board.cmake
Kconfig.board
Kconfig.defconfig
n32g45xvl_stb.dts
n32g45xvl_stb.yaml
n32g45xvl_stb_defconfig

boards\arm\n32g45xvl_stb\board.cmake文件配置
Kconfig 系列文件是增加板级 KConfig 配置选项。选项可以在配置界面 BoardSelection 目录下看到。
boards\arm\n32g45xvl_stb\n32g45xvl_stb.dts文件是设备树(Devicetree)描述文件:
/*
* N32G45XVL-STB
*
* Copyright (c) 2022 Quincy<wangqyfm@foxmail.com>
* SPDX-License-Identifier: Apache-2.0
*/

/dts-v1/;

#include<nationstech/g4/n32g457xE.dtsi>
#include <nationstech/g4/n32g4-pinctrl.dtsi>

/ {
          model = "N32G45XVL-STB";
          compatible = "nationstech,n32g45xvl_stb";

          chosen {
                    /* ... */
          };

          leds {
                    compatible = "gpio-leds";
                    /* ... */
          };

          gpio_keys {
                    compatible = "gpio-keys";
                    /* ... */
          };

          aliases {
                    led0 = &green_led;
                    /* ... */
          };
};

&rcc {
          status = "okay";
};

&pinmux {
          status = "okay";
};

&gpioa {
          status = "okay";
};

&gpiob {
          status = "okay";
};

&usart1 {
          status = "okay";
          current-speed = <115200>;

          pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
};

具体的语法,可以参考:https://docs.zephyrproject.org/latest/guides/dts/index.html

boards\arm\n32g45xvl_stb\n32g45xvl_stb.yaml
文件开发板描述。描述开发板的一些特性:mcu 及架构,支持的外设等。

boards\arm\n32g45xvl_stb\n32g45xvl_stb_defconfig
文件是 KConfig 的选项文件,这个文件是代替手动选择 KConfig 选项:
# N32G45XVL-STB
#
# Copyright (c) 2022 Quincy<wangqyfm@foxmail.com>
# SPDX-License-Identifier:Apache-2.0

CONFIG_SOC_SERIES_N32G4=y
CONFIG_SOC_N32G45X=y
CONFIG_BOARD_N32G45XVL_STB=y

#enable MPU
CONFIG_MPU=n
CONFIG_ARM_MPU=n

# Enable HW stack protection
CONFIG_HW_STACK_PROTECTION=y

# Enable Clocks
CONFIG_CLOCK_CONTROL=y
CONFIG_CLOCK_CTRL_N32=y

# enable pinmux
CONFIG_PINMUX=y
CONFIG_PINMUX_N32=y

# enable GPIO
CONFIG_GPIO=y
CONFIG_GPIO_N32=y

# enable uart driver
CONFIG_SERIAL=y
CONFIG_UART_N32=y

# console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

# LOG
CONFIG_LOG=y

# enable FLASH
CONFIG_FLASH=y
CONFIG_FLASH_N32=y
CONFIG_FLASH_PAGE_LAYOUT=y

CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000


每个文件的详细内容可以参考代码仓库。
5. 测试
可以运行 do_build.bat 构建编译测试的代码,如果一切没有问题的话,最后有类似的构建信息:
Memory region         Used Size  Region Size %age Used
           FLASH:       21404 B       512 KB      4.08%
            SRAM:        6960 B       48 KB     14.16%
        IDT_LIST:          0 GB         2 KB      0.00%

这个脚本使用的 Zephyr 自带的hello_world 例程,打印 HelloWorld! 后结束运行。

结语
Zephyr-RTOS 的高可配置性,完善的构建工具,使得移植工作显得条理清晰,排查问题也比较容易。建议大家多多尝试~也希望国内 MCU 厂家积极适配更多 RTOS,让用户由更多的可选项,也让广大工程师能轻松工作,少加班~~~


最后的最后,第一次在 21IC 发这么长的帖子,希望兄弟姐妹们多多回复,给些支持~~~

使用特权

评论回复
6552918| | 2022-2-15 13:17 | 显示全部楼层
支持一下,对操作系统而言,生态为王!!!

使用特权

评论回复
海滨消消| | 2022-2-15 14:31 | 显示全部楼层
这个操作系统还真的没怎么听说

使用特权

评论回复
WoodData| | 2022-2-16 16:33 | 显示全部楼层
支持一下,听过这个系统,还比较复杂

使用特权

评论回复
yangxiaor520| | 2022-2-16 20:53 | 显示全部楼层
这又是一个什么操作系统

使用特权

评论回复
guijial511| | 2022-2-18 08:21 | 显示全部楼层
还没听说过这个系统

使用特权

评论回复
yljon| | 2022-2-18 13:33 | 显示全部楼层
感觉这个系统有点复杂

使用特权

评论回复
sparrow054| | 2022-3-2 10:50 | 显示全部楼层
又是一个新系统么
感觉万物生的样子

使用特权

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

本版积分规则