123下一页
返回列表 发新帖我要提问本帖赏金: 2.00元(功能说明)

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

[复制链接]
 楼主| 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 的移植。



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


移植说明
主要步骤:

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


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


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

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

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

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

一是在
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 系统的驱动框架,主要代码:
  1. static const struct clock_control_driver_api n32_cc_api = {
  2.         .on = n32_cc_on,
  3.         .off = n32_cc_off,
  4.         .get_rate = n32_cc_get_subsys_rate,
  5. };

  6. static int n32_cc_init(const struct device *dev)
  7. {
  8.         return 0;
  9. }

  10. DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
  11.                                  &n32_cc_init,
  12.                                  NULL,
  13.                                  NULL, NULL,
  14.                                  PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
  15.                                  &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 配置文件,决定构建内容:
  1. zephyr_library_amend()

  2. zephyr_library_sources_ifdef(CONFIG_CLOCK_CTRL_N32 clock_control_n32.c)



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

drivers\clock_control\Kconfig 是KConfig 配置文件。
  1. menuconfig CLOCK_CTRL_N32
  2.         bool "CLOCK_CTRL Driver for N32 family of MCUs"
  3.         depends on SOC_FAMILY_N32
  4.         select USE_NS_STD_LIB_RCC
  5.         help
  6.           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这个开发板的配置说明:
  1. board.cmake
  2. Kconfig.board
  3. Kconfig.defconfig
  4. n32g45xvl_stb.dts
  5. n32g45xvl_stb.yaml
  6. n32g45xvl_stb_defconfig

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

  7. /dts-v1/;

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

  10. / {
  11.           model = "N32G45XVL-STB";
  12.           compatible = "nationstech,n32g45xvl_stb";

  13.           chosen {
  14.                     /* ... */
  15.           };

  16.           leds {
  17.                     compatible = "gpio-leds";
  18.                     /* ... */
  19.           };

  20.           gpio_keys {
  21.                     compatible = "gpio-keys";
  22.                     /* ... */
  23.           };

  24.           aliases {
  25.                     led0 = &green_led;
  26.                     /* ... */
  27.           };
  28. };

  29. &rcc {
  30.           status = "okay";
  31. };

  32. &pinmux {
  33.           status = "okay";
  34. };

  35. &gpioa {
  36.           status = "okay";
  37. };

  38. &gpiob {
  39.           status = "okay";
  40. };

  41. &usart1 {
  42.           status = "okay";
  43.           current-speed = <115200>;

  44.           pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
  45. };

具体的语法,可以参考: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 选项:
  1. # N32G45XVL-STB
  2. #
  3. # Copyright (c) 2022 Quincy<wangqyfm@foxmail.com>
  4. # SPDX-License-Identifier:Apache-2.0

  5. CONFIG_SOC_SERIES_N32G4=y
  6. CONFIG_SOC_N32G45X=y
  7. CONFIG_BOARD_N32G45XVL_STB=y

  8. #enable MPU
  9. CONFIG_MPU=n
  10. CONFIG_ARM_MPU=n

  11. # Enable HW stack protection
  12. CONFIG_HW_STACK_PROTECTION=y

  13. # Enable Clocks
  14. CONFIG_CLOCK_CONTROL=y
  15. CONFIG_CLOCK_CTRL_N32=y

  16. # enable pinmux
  17. CONFIG_PINMUX=y
  18. CONFIG_PINMUX_N32=y

  19. # enable GPIO
  20. CONFIG_GPIO=y
  21. CONFIG_GPIO_N32=y

  22. # enable uart driver
  23. CONFIG_SERIAL=y
  24. CONFIG_UART_N32=y

  25. # console
  26. CONFIG_CONSOLE=y
  27. CONFIG_UART_CONSOLE=y

  28. # LOG
  29. CONFIG_LOG=y

  30. # enable FLASH
  31. CONFIG_FLASH=y
  32. CONFIG_FLASH_N32=y
  33. CONFIG_FLASH_PAGE_LAYOUT=y

  34. CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=24000000


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

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

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


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

打赏榜单

crz21 打赏了 1.00 元 2024-04-17
理由:感谢给初学者起了个好头

li777 打赏了 1.00 元 2024-03-20
理由:有用,我也在做zephyr移植

评论

博主,你好我按照你的方法,构建了一个板子,但是输出信息说,没有这个板子  发表于 2023-9-13 16:58
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 | 显示全部楼层
又是一个新系统么
感觉万物生的样子
haileysun 发表于 2022-9-3 12:40 | 显示全部楼层
本帖最后由 haileysun 于 2022-9-3 12:42 编辑

Hi,wangqy,可以向您请教一些在移植Zephyr过程中的问题吗?
 楼主| wangqy_ic 发表于 2022-9-6 10:44 | 显示全部楼层
haileysun 发表于 2022-9-3 12:40
Hi,wangqy,可以向您请教一些在移植Zephyr过程中的问题吗?

可以啊,直接回帖,或者私信都可以

评论

您这边方便加个微信好友或者QQ好友吗?向您请教一下,我21ic上面目前私信不了。  发表于 2022-9-7 11:09
请问一下,您这边用过exFAT吗?我在它的官网上看到它是支持exFAT的,但是相关资料太少。另:我编译了一个它的关于文件系统的DEMO,然后使用ninja menuconfig进入它的配置界面了,也找到了exFAT这里,但是它的具体使用,以及怎样支持的,目前还不清楚,您这边有相关经验吗?  发表于 2022-9-7 10:59
芯路例程 发表于 2022-9-6 11:46 | 显示全部楼层
Zephyr系统在国内用的比较少,我记得NRF系列就比较常用这个系统。
haileysun 发表于 2022-9-7 11:07 | 显示全部楼层
wangqy_ic 发表于 2022-9-6 10:44
可以啊,直接回帖,或者私信都可以

请问一下,您这边用过exFAT吗?我在它的官网上看到它是支持exFAT的,但是相关资料太少。另:我编译了一个它的关于文件系统的DEMO,然后使用ninja menuconfig进入它的配置界面了,也找到了exFAT这里,但是它的具体使用,以及怎样支持的,目前还不清楚,您这边有相关经验吗?
Bowclad 发表于 2022-9-7 20:52 | 显示全部楼层
又发现个没听说过的操作系统
天天向善 发表于 2022-9-9 13:11 | 显示全部楼层
这个移植教程很详细,希望大佬多出一些类似的教程。

评论

关注这个系统的工程师还是太少了~移植的话呢,这个系统在分层这一块做得很细致,移植到新 MCU 其实真的不难。系统也基本能覆盖到市面上常见的架构,常见的 MCU。  发表于 2022-9-16 09:33
 楼主| wangqy_ic 发表于 2022-9-16 09:30 | 显示全部楼层
haileysun 发表于 2022-9-7 11:07
请问一下,您这边用过exFAT吗?我在它的官网上看到它是支持exFAT的,但是相关资料太少。另:我编译了一个 ...

实在不好意思,这两个星期没时间上论坛~

在 Zephyr 里 FAT 是通过 ELM FAT 实现,看代码确实是支持 exFAT。具体的使用,你可以看看 samples\subsys\fs\fat_fs 这个官方提供的例程。

我只是使用过 littlefs。必须的配置项目有:DISK_ACCESS、FILE_SYSTEM 和 FILE_SYSTEM_LITTLEFS。
当然你用的是 FAT,那 FILE_SYSTEM_LITTLEFS 应该为 FAT_FILESYSTEM_ELM 。其他的,还是重点看看自带的例程。例程里已经把重要的事情都实现了。

再次抱歉这么久才回复~

夜声 发表于 2022-11-6 23:04 | 显示全部楼层
不看看内存占用的多少吗?
Sam131208 发表于 2023-1-16 16:28 | 显示全部楼层
    近来接触到国民技术的芯片,发现WB031在国内的蓝牙芯片中,在低功耗是做的比较好的(WCH系列似乎更好,低功耗下可以保存外设,就是主频低,FLASH,RAM资源少)。
    zephyr是一款比较优秀的RTOS,统一的API接口,平台移植非常方便。很高兴看到楼主进行的工作,也希望国民技术官方可以跟进,整合进入zephyr的官方库中。对于nordic的用户来说,可以低成本的转移。
数据采集存储 发表于 2023-1-28 10:47 | 显示全部楼层
这个帖子不错,学习了很多。
名字是啥样 发表于 2023-1-28 10:53 | 显示全部楼层
感谢楼主的分享。不错的。
james03 发表于 2023-1-29 11:01 | 显示全部楼层
必须顶起
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

22

主题

117

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部