一、如何新建工程这里依然参考官网。主要是翻译一遍给自己留下印象。引用Application Development — Zephyr Project Documentation******************基本上是翻译官网内容不感兴趣可跳过直接上手第二章****************从引用可知***引用的文档约定如下1、app文件目录存放在zephyrproject/app。2、构建输出目录放在app/build。***将应用放在工作区也就是zephyrproject内部使用weist相关命令更方便。但是只要环境变量ZEPHYR_BASE配置正确应用可以放在电脑上任意位置。***Zephyr基于cmake。***应用目录里的文件负责把Zephyr、各类模块和写的应用关联起来。这个目录存放所有应用专属文件比如应用独立配置文件、业务源码。举例app文件夹的结构这些文件的作用如下CMakeLists.txt该文件告诉构建系统去哪里查找其他应用文件并把应用目录接入 Zephyr 的 CMake 构建体系。通过这个关联就可以使用 Zephyr 构建系统提供的能力例如板级专属配置文件、在真实硬件或模拟器上运行和调试编译出的固件等。app.overlay这是设备树覆写文件用来针对你编译的任意开发板在基础设备树之上追加应用专属的修改。设备树覆写一般用来配置应用用到的硬件资源。 构建系统默认会读取app.overlay你也可以添加更多设备树覆写文件系统还会自动查找其他默认名称的配置文件。 更多设备树相关内容请参见「Devicetree」文档。prj.conf这是一份Kconfig 片段用于为一个或多个 Kconfig 选项设置应用专属的值。这些应用配置会和其他配置合并生成最终生效的配置。Kconfig 片段一般用来开启、配置应用需要用到的软件功能。 构建系统默认读取prj.conf你也可以添加更多 Kconfig 配置片段系统还会自动查找其他默认名称的配置文件。 更多内容见下文「Kconfig Configuration」。VERSION文本文件里面包含若干版本信息字段。借助这些字段可以管理应用的生命周期并且在固件镜像签名时自动填充应用版本号。 关于该文件的用法详见「Application version management」。main.c源码文件。应用代码一般使用 C、C 或者汇编语言编写。Zephyr 的规范约定源码统一放在app下名为src的子目录中。应用创建完成之后需要使用cmake生成构建目录build。该目录存放编译应用与Zephyr内核后的各类文件之后将它们链接合并生成可在开发板上运行的最终二进制固件。最简便的构建方式是使用west build当然你也可以直接调用cmake。应用编译的产物永远都在build中Zephyr不支持源码内构建。应用类型我们根据app所在的位置把Zephyr应用分为三种基础类型应用类型app的存放位置repository仓库内应用zephyr 源码仓库内部workspace工作区应用安装了 Zephyr 的 west 工作区内freestanding独立应用其他任意位置下面展开说明这三种类型Zephyr仓库内应用参考下图文件夹中的应用注意看目录Zephyr工作区应用存放在 west 工作区内、但不在 zephyr 源码仓库内部的应用称为 Zephyr 工作区应用。参考下图Zephyr独立应用存放在Zephyr工作区之外的Zephyr程序。如下所示创建应用程序在Zephyr中既可以使用一个参考工作区的应用或者手动创建应用。这里我选择前者从历程中拷贝一个例程。使用参考工作区的应用example-application这个 Git 仓库包含了一个参考工作区应用。推荐在创建自己的应用时以它作为参考后续章节会进行说明。参考链接GitHub - zephyrproject-rtos/example-application: Example out-of-tree application that is also a module · GitHub该example-application仓库演示了多项常用功能的使用方法例如自定义板级移植自定义设备树绑定自定义设备驱动持续集成CI配置包含 twister 工具的使用自定义 west 扩展命令example-application 的基础用法在已有的Zephyr工作区中使用example-application 仓库最简便的方式是执行以下步骤cd home/zephyrproject git clone https://github.com/zephyrproject-rtos/example-application my-app这个目录名my-app可以自定义按需求修改即可。之后就可以进入这个目录修改里面的内容来满足自身需求。因为是在已有 Zephyr 工作区内使用你可以通过west build或者其他 west 命令来完成编译、烧录与调试。example-application 高级用法这里内容是搭建基于Zephyr的自定义软件发行包。我移植例程貌似用不到用到再看吧。详细内容参见引用链接。手动创建应用程序可以按照以下步骤从零开始创建基础应用目录。不过以example-application仓库或者 Zephyr 的示例与演示工程作为起点通常会更加简单。1、创建应用目录不支持在路径包含空格的目录下编译 Zephyr 或者创建应用。 所以 Windows 路径C:\Users\YourName\app可以正常使用但C:\Users\Your Name\app不行。2、创建源代码文件建议将所有应用源码放在名为src的子目录中便于区分工程配置文件和源码文件。承接上一步示例执行3、将应用源码放到src子目录。本示例假设新建了src/main.c文件。4、在app目录下新建CMakeLists.txt内容如下备注cmake_minimum_required()是 CMake 的必需调用。下一行的 Zephyr 包也会调用它。如果 CMake 版本低于CMakeLists.txt中指定的版本或是低于 Zephyr 包要求的版本CMake 就会报错。find_package(Zephyr)会引入 Zephyr 构建系统并创建一个名为app的 CMake 目标参见 Zephyr CMake 包文档。向该目标添加源码文件就是把文件纳入编译。Zephyr 包会将Zephyr-Kernel定义为 CMake 工程并启用 C、CXXC、ASM汇编语言支持。project(my_zephyr_app)用于定义你的应用对应的 CMake 工程。必须写在find_package(Zephyr)之后避免和 Zephyr 的project(Zephyr-Kernel)产生冲突。target_sources(app PRIVATE src/main.c)的作用是把源码文件添加到app目标中。这一句必须放在定义该目标的find_package(Zephyr)之后。你可以多次使用target_sources()添加任意多的源码文件。5、至少为你的应用创建一个 Kconfig 片段文件通常命名为prj.conf在里面设置应用所需的 Kconfig 选项值详见 Kconfig 配置文档。如果不需要设置任何 Kconfig 选项创建一个空文件即可。6、配置应用所需的设备树覆盖文件通常使用app.overlay详见设置设备树覆盖文档。7、根据需要准备其他文件例如 twister 测试配置文件、持续集成配置文件、文档等。重要的构建系统变量可以通过大量变量控制Zephyr构建系统。下面是开发者都需要了解的核心变量。BOARD,CONF_FILE, andDTC_OVERLAY_FILE这三个变量有三种方式传给构建系统优先级从高到低1、在执行west build或者cmake命令时通过-D参数传入。如果需要多个设备树叠加文件overlay要用引号包裹file1.overlay;file2.overlay2、设置为环境变量3、在CMakeLists.txt里用set(变量名 值)语句定义ZEPHYR_BASE构建系统使用的Zephyr根目录变量find_package(Zephyr)会自动把它设置为 CMake 缓存变量。也可以将ZEPHYR_BASE设置成环境变量强制 CMake 使用指定路径下的 Zephyr 源码。BOARD选择应用编译时使用的开发板作为默认配置。 内置开发板信息参见【支持的开发板与扩展板】新增板级移植请查阅【开发板移植指南】。CONF_FILE指定一个或多个 Kconfig 配置片段文件。 多个文件名可以用空格或者分号分隔。文件内的 Kconfig 配置项会覆盖默认配置。 更多细节见【初始配置】章节。EXTRA_CONF_FILE附加 Kconfig 配置片段文件。 多个文件名可用空格 / 分号分隔。适合保留CONF_FILE默认值的同时追加一部分额外配置选项。DTC_OVERLAY_FILE指定一个或多个要加载的设备树叠加文件。多个文件使用分号隔开。示例参考【配置设备树叠加文件】设备树基础概念见【设备树简介】。EXTRA_DTC_OVERLAY_FILE额外追加的设备树叠加文件。多个文件使用分号隔开。适合保留DTC_OVERLAY_FILE默认值的前提下混入新增的 overlay 文件。SHIELD参见【扩展板Shields】文档。Shields — Zephyr Project DocumentationZEPHYR_MODULESCMake 列表存放附加目录的绝对路径这些目录内包含源码、Kconfig 等资源参与应用编译。详情见【模块外部工程】。 重点一旦手动设置该变量它就是一份完整模块清单构建系统不会再自动加载 west 管理的模块。EXTRA_ZEPHYR_MODULES作用类似ZEPHYR_MODULES区别是它追加到 west 自动搜索得到的模块列表尾部而不是替换整个列表。FILE_SUFFIX可选文件名后缀用于 Kconfig 配置片段、设备树 overlay 文件。构建时优先查找带此后缀的文件如果找不到就回退到不带后缀的原始文件名。详情见【文件后缀机制】。KCONFIG_WARNING_AS_ERROR将所有 Kconfig 警告升级为编译错误包含默认仅打印提示的警告。详情见【Kconfig 警告当作错误处理】注意你可以使用Zephyr Build Configuration CMake 包在多个工程间共享这些变量的通用配置。应用CMakeLists.txt每个应用工程都必须有CMakeLists.txt文件它是构建系统的入口顶层文件。最终的zephyr.elf镜像同时包含应用代码与内核库。下面介绍可以在CmakeLists.txt里实现的部分功能务必按照如下顺序。首先如果只需要给一块板子编译固件可以另起一行在工程里设置目标板的名称。示例更多板子可用信息参考Supported Boards and Shields — Zephyr Project DocumentationZephyr 构建系统会按下面顺序查找 BOARD 的值一旦找到就停止继续查找1CMake 缓存里已经存在的值优先级最高。这样可以保证后续编译不会使用和配置阶段不一样的 BOARD。2CMake 命令行传入的值直接传或者通过west build间接传入也就是-DBOARDYOUR_BOARD。3如果设置了环境变量BOARD则使用环境变量的值。4最后才会使用应用CMakeLists.txt里面通过set(BOARD ...)设置的值。其次如果你的应用不使用默认的prj.conf而是使用其他配置文件需要添加代码设置CONF_FILE变量指向这些配置文件。多个文件名之间用单个空格或者分号分隔。 如果你不想在一处一次性写死全部配置文件可以用 CMake list 的方式模块化拼接配置片段文件。Setting Kconfig configuration values — Zephyr Project Documentation如果你的应用用到设备树叠加文件可能需要设置DTC_OVERLAY_FILE。Devicetree HOWTOs — Zephyr Project Documentation如果你的应用需要自定义内核配置项在应用的CMakeLists.txt同级目录新建Kconfig文件。Configuration System (Kconfig) — Zephyr Project Documentation这属于比较少见的高级用法适合应用需要新增专属配置选项并且在不同编译配置下取不同值的场景。 如果你仅仅是想给 Zephyr 已有的配置项设置自定义值直接用上面讲的CONF_FILE就够了。Kconfig文件模板写法在完成上面所有步骤后另起一行声明本应用依赖Zephyr注意find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})用于强制使用环境变量ZEPHYR_BASE指定的 Zephyr 源码版本。Zephyr 的所有官方示例都支持ZEPHYR_BASE环境变量。接下来把应用源码添加到app目标库中一个文件一行写法如下下面是一份简单的cmakelist.txtCMake 属性HEX_FILES_TO_MERGE可以结合 Kconfig、CMake 的工程配置把外部独立编译出来的 hex 文件和 Zephyr 应用编译生成的 hex 文件合并在一起。示例CMakeCache.txtCMake 使用CMakeCache.txt文件作为持久化的键值字符串存储用于在多次编译之间缓存参数包含编译选项、构建选项以及库依赖路径。 当在空的构建目录里第一次运行 CMake 时就会生成这个缓存文件。关于CMakeCache.txt的更多细节请查阅 CMake 官方的 Cache 文档。CMake Cache — Mastering CMake应用配置应用配置目录Zephyr会从应用配置目录读取配置文件但前面提到的参数CONF_FILE、EXTRA_CONF_FILE、DTC_OVERLAY_FILE、EXTRA_DTC_OVERLAY_FILE如果填写绝对路径不受该目录约束。应用配置目录由变量APPLICATION_CONFIG_DIR控制。APPLICATION_CONFIG_DIR的取值优先级靠前更高用户通过-DAPPLICATION_CONFIG_DIRpath命令行传入或者在find_package(Zephyr)之前在 CMake 脚本里设置则使用该路径作为应用配置目录。默认值应用源码根目录。Kconfig配置应用的配置项一般在应用目录下的prj.conf中设置。例如启用 C 支持可以这样写Samples and Demos — Zephyr Project DocumentationSetting Kconfig configuration values — Zephyr Project DocumentationSetting Kconfig configuration values — Zephyr Project DocumentationHardening Tool — Zephyr Project DocumentationConfiguration System (Kconfig) — Zephyr Project Documentation一、实验性特征暂时不研究了。设备树叠加层Devicetree HOWTOs — Zephyr Project DocumentationFile Suffixes 文件后缀机制很多 Zephyr 项目希望一套源码多套配置用来适配不同产品版本、不同编译变体它们需要不同的 Kconfig 和设备树配置。 Zephyr 提供FILE_SUFFIX参数会自动给配置文件名追加后缀这个机制同时作用于 Kconfig 片段、板级 overlay 文件。并且有降级逻辑带后缀的文件找不到时自动回退加载不带后缀的基础文件。示例工程目录结构应用专属代码应用源码默认放在src目录下。如果文件很多可以在src下自行建立多层子目录分组。应用代码不要使用内核预留的符号前缀详细见命名规范Naming Conventions文档。第三方代码库库代码可以放在src目录之外参与编译但有一个重点应用和第三方库必须使用相同的 ABI应用二进制接口。 多数架构靠编译选项控制 ABI所以库和应用的编译标志必须保持一致适配胶水代码一般也需要能包含 Zephyr 内核头文件。为方便集成第三方组件Zephyr 构建系统提供了一组 CMake 函数让应用脚本拿到 Zephyr 的编译参数。 函数定义在cmake/modules/extensions.cmake命名格式zephyr_get_type_format。第三方构建系统通常需要传入这些变量CMAKE_C_COMPILER、CMAKE_ARARCH、BOARD以及标识 Zephyr 内核版本的相关变量示例工程samples/application_development/external_lib演示了第三方库集成用法。https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/application_development/external_lib————————————————————编译应用Zephyr 构建系统会编译、链接应用所有组件最终生成单一镜像文件可以跑在仿真硬件或者真实板子上。和其他基于CMake的系统应用编译分为两个阶段1、生成构建文件阶段用cmake 指定 generator生成构建规则generator 决定第二阶段用什么底层构建工具。2、实际编译阶段调用底层构建工具编译源码、链接生成镜像。Zephyr默认使用原工具westwest在内部自动调用cmake 底层构建工具ninja /make。你也可以直接手动调用 cmake。Basic基础用法1、进入应用目录app。2、执行下面命令为指定板子编译输出zephyr.elf。west方式west build -b board如果你想使用另一份.conf配置文件可以用CONF_FILE参数。这份配置会覆盖应用原来的.config或默认prj.confwest build -b board -- -DCONF_FILEprj.alternate.conf可以持久化指定板子和配置导出环境变量BOARD、CONF_FILE或者在CMakeLists.txt里用set()设置 另外 west 还支持设置默认板子。Build Directory Contents 构建目录内容使用 Ninja 生成器时build 目录结构如下build目录里重点文件build.ninjaninja 的构建规则文件ninja 靠它编译程序。zephyr子目录构建系统的工作目录绝大多数编译生成文件放在这里执行完ninja编译后产物放在build/zephyr下.config本次编译用到的全部 Kconfig 配置zephyr.elf最终 ELF 可执行文件同时还会输出.hex、.bin等固件格式重新编译应用开发时频繁修改、测试是最高效的方式。源码、CMakeLists.txt、配置改动后建议重新编译测试方便调试。Zephyr 构建系统是增量编译只重新编译受改动影响的文件所以再次编译通常比首次快很多。有时候构建系统判断出错该重编的文件没有重编这时需要强制全量清理重建1、进入app/build目录2、清理命令二选一保留.config配置文件只删编译产物west build -t cleanwest build -t pristine不保留.config3、清理完成后再用正常编译命令重新构建。为指定版本板子编译用到再看吧。运行应用Zephyr 支持的大多数板子都可以用west flash把固件烧录到板子并启动。在真实硬件上烧录运行步骤先完成编译前面 Building an Application 章节板子连接主机一般是 USB 方式在app/build目录执行每次执行这个命令都会先增量编译再烧录west flashZephyr 构建系统会结合板级支持文件调用对应硬件的烧录工具下载固件并启动。Linux 环境开发时通常需要安装对应板子的 udev 规则才能让普通用户访问 USB 调试器。烧录失败时优先检查这点。自定义板子、设备树以及 SOC 定义如果你开发的板子 / 平台还没有被 Zephyr 主线支持可以直接在你的应用工程里添加板子、设备树、SOC 相关定义不需要提交到 Zephyr 源码仓库内部out-of-tree树外开发。这套树外板子与 SOC 的目录组织方式和 Zephyr 主线内部维护板子、SOC 的结构保持一致。这样做的好处前期开发完成后如果后续想把这套平台代码合入 Zephyr 主线迁移、提交上游会轻松很多。在你的应用工程或者单独仓库里用下面这套目录结构存放自定义板子上面的boards目录中存放自定义的板子soc目录用来存放 SOC 相关代码当然你也可以直接使用 Zephyr 主线里已经支持的 SOC 来做自定义板子。Boards 板子目录规范boards下一级文件夹使用厂商名作为目录名如果后续打算提交到 Zephyr 主线厂商名必须和dts/bindings/vendor-prefixes.txt里的厂商前缀保持一致非厂商自研板这里用othersdoc/文档、support/支持文件是可选的但如果要上游合入 Zephyr就必须提供。my_custom_board目录内文件需要遵循 Zephyr 板子规范包含这些文件目录搭建完成后编译时通过-DBOARD_ROOT参数告诉 CMake 去哪里找这套自定义板子west build -b board name -- -DBOARD_ROOTpath to boards这样编译就会加载你的自定义板子配置固件生成在应用工程内。也可以在应用的CMakeLists.txt里设置BOARD_ROOT必须放在find_package(Zephyr …)之前。注意在 CMakeLists.txt 里写BOARD_ROOT时必须用绝对路径示例list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/extra-board-root)命令行传-DBOARD_ROOT时绝对路径、相对路径都可以相对路径以应用目录为基准。注意如果使用 sysbuildBOARD_ROOT需要在模块或者 sysbuild 的 CMakeLists.txt 中定义。SOC定义和板级支持的方式类似目录结构和 Zephyr 源码树里维护 SOC 的方式保持一致示例soc/Kconfig文件会在 Kconfig 中生成顶层SoC/CPU/ 配置选择菜单。可以借助 CMake 变量SOC_ROOT将树外out-of-tree的 SOC 定义添加到这个菜单中。该变量是一个用分号分隔的目录列表这些目录存放 SOC 支持相关文件。遵循上面的目录结构你可以添加下述文件从而在菜单中加载更多 SOC上面这些 Kconfig 文件可以用来描述该 SOC或是加载其他额外的 SOC Kconfig 文件。下面是在这套目录结构里加载stm32l0专属 Kconfig 文件的示例只需要在st/stm32/Kconfig.soc写入下面内容即可实现SOC 目录结构准备好之后你就可以给应用程序指定这个自定义平台进行编译构建向 CMake 构建系统传入-DSOC_ROOT参数指定自定义平台信息所在路径。使用west构建west build -b 开发板名 -- -DSOC_ROOTsoc目录路径 -DBOARD_ROOT开发板目录路径构建时会启用你的自定义平台配置并把 Zephyr 固件生成到应用目录下。你可以查阅【构建设置】文档了解如何在模块的zephyr/module.yml文件中配置SOC_ROOT。Modules (External projects) — Zephyr Project Documentation也可以在应用的CMakeLists.txt中定义SOC_ROOT变量。注意必须在执行find_package(Zephyr ...)引入 Zephyr 基础脚本之前定义它。如果在CMakeLists.txt里设置SOC_ROOT必须使用绝对路径示例写法list(APPEND SOC_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/extra-soc-root)如果是通过-DSOC_ROOTsoc-root参数传入则绝对路径、相对路径都支持 相对路径是以应用程序目录作为基准进行解析。设备树定义设备树目录默认会从APPLICATION_SOURCE_DIR应用源码目录、BOARD_DIR开发板目录以及ZEPHYR_BASEZephyr 根目录中查找。你也可以自行新增设备树目录也就是DTS_ROOT需要创建如下目录结构其中arm需要替换成对应的芯片架构。上面所有目录都是可选的。bindings目录存放设备树绑定描述文件其余目录存放可在设备树源码中被#include引入的文件。目录结构搭建完成后就可以通过 CMake 缓存变量DTS_ROOT指定这个目录路径来启用它使用west构建west build -b 开发板名 -- -DDTS_ROOTdts根目录路径你同样可以在应用的CMakeLists.txt文件里定义该变量。一定要放在find_package(Zephyr ...)引入 Zephyr 基础构建脚本之前。如果在CMakeLists.txt内设置DTS_ROOT必须填写绝对路径示例list(APPEND DTS_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/extra-dts-root)如果是通过参数-DDTS_ROOTdts-root传入绝对路径、相对路径都支持相对路径是以应用程序目录作为基准解析。设备树源码会经过 C 预处理器处理因此你可以#include放在DTS_ROOT目录下的文件。按照惯例设备树头文件后缀为.dtsi。你还可以借助预处理器控制设备树文件内容通过 CMake 缓存变量DTS_EXTRA_CPPFLAGS传递预处理指令使用west构建west build -b 开发板名 -- -DDTS_EXTRA_CPPFLAGS-DTEST_ENABLE_FEATURE**************************************************************************************************************二、点灯完成第十三章 跑马灯实验我这里参考工作区应用模版创建工程。首先打开自己的Zephyr工作区也就是zephyrproject。注意首先要激活Python虚拟环境venv才可以使用west工具参考下图下面的指令查看工作区目录。west topdir1、在工作区目录输入如下指令cd home/zephyrproject git clone https://github.com/zephyrproject-rtos/example-application my-app注意my-app可以自定义这里我换成lab_1如下图所示2、使用VSCode打开这个文件夹3、先让app能正常编译经过一番试错先修改prj.conf删掉CONFIG_BLINKy再修改main.c/* * Copyright (c) 2021 Nordic Semiconductor ASA * SPDX-License-Identifier: Apache-2.0 */ #include zephyr/kernel.h #include zephyr/drivers/sensor.h #include zephyr/logging/log.h #include zephyr/app_version.h LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL); int main(void) { while(1); return 0; }之后进行编译结果如下4、实现跳转我这里用的插件是clangd如下图但是会出现上图的提示在app目录新建.clangd文件内容如下CompileFlags: Remove: - -fno-printf-return-value - -mfp16-formatieee - -fno-reorder-functions之后再restart一下即可5、修改板子的设备树我想用开发Linux驱动的方式来写这份例程要不然直接用gpio点灯也不能突出Zephyr的优势。根据Linux经验需要找到对应的驱动然后看说明文件。我这里使用如下图驱动同样的说明文档如下图所示先来阅读右边的说明文档文档内容略主要是描述了这个驱动的功能和设备树示例。开始参考右边重写左边led节点。修改如下/dts-v1/; #include st/f1/stm32f103Xe.dtsi #include st/f1/stm32f103z(c-d-e)tx-pinctrl.dtsi #include zephyr/dt-bindings/input/input-event-codes.h / { model alientek jingying stm32f103ze board; compatible alientek,stm32f103ze; chosen { zephyr,console usart1; zephyr,shell-uart usart1; zephyr,sram sram0; zephyr,flash flash0; }; aliases { led0 led_0; led1 led_1; }; // 格式【标签:】节点名 { 属性 }; leds { compatible gpio-leds; led_0: led_0 { gpios gpiob 5 GPIO_ACTIVE_LOW; label LED 0; }; led_1: led_1 { gpios gpioe 5 GPIO_ACTIVE_LOW; label LED 1; }; }; }; clk_lsi { status okay; }; clk_hse { clock-frequency DT_FREQ_M(8); status okay; }; pll { mul 9; clocks clk_hse; status okay; }; rcc { clocks pll; clock-frequency DT_FREQ_M(72); ahb-prescaler 1; apb1-prescaler 2; apb2-prescaler 1; }; usart1 { pinctrl-0 usart1_tx_pa9 usart1_rx_pa10; pinctrl-names default; current-speed 115200; status okay; }; usart2 { pinctrl-0 usart2_tx_pa2 usart2_rx_pa3; pinctrl-names default; current-speed 115200; status okay; }; usart3 { pinctrl-0 usart3_tx_pb10 usart3_rx_pb11; pinctrl-names default; current-speed 115200; }; i2c1 { pinctrl-0 i2c1_scl_remap1_pb8 i2c1_sda_remap1_pb9; pinctrl-names default; status okay; clock-frequency I2C_BITRATE_FAST; }; spi1 { pinctrl-0 spi1_sck_master_pa5 spi1_miso_master_pa6 spi1_mosi_master_pa7; pinctrl-names default; cs-gpios gpiob 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP); status okay; }; spi2 { pinctrl-0 spi2_nss_master_pb12 spi2_sck_master_pb13 spi2_miso_master_pb14 spi2_mosi_master_pb15; pinctrl-names default; status okay; }; timers1 { st,prescaler 10000; status okay; pwm1: pwm { status okay; pinctrl-0 tim1_ch1_pwm_out_pa8; pinctrl-names default; }; }; timers2 { st,prescaler 255; status okay; pwm2: pwm { status okay; pinctrl-0 tim2_ch2_pwm_in_pa1; pinctrl-names default; }; }; iwdg { status okay; }; rtc { clocks rcc STM32_CLOCK(APB1, 28), rcc STM32_SRC_LSI RTC_SEL(2); status okay; }; adc12_common { status okay; }; adc1 { pinctrl-0 adc1_in0_pa0; pinctrl-names default; status okay; }; die_temp { status okay; }; dma1 { status okay; };注意下图因为c的宏定义不能有下划线但是我这里命名了下划线故需要写 标签节点名。这是参考的说明文档内容6、修改如下文件上图是应用配置文件怎么写也可以参考官方例程。调整配置1、在工程目录执行west build -t menuconfig改完不会写进prj.conf会写进哪2、直接在下图所示路径找zephyrproject/zephyr/drivers/led参考如下7、写main.c这个led.h是起什么作用的我明明用的驱动头文件也不这样啊我怀疑这个是上层引用Zephyr API Documentation: LED G:\zephyrproject\zephyr\samples\basic里的例程Light-Emitting Diode (LED) — Zephyr Project Documentation参考例程上图中的例程使用了两种点灯方式第一种是纯gpio点灯我觉得不能突出Zephyr类Linux的特点所以用第二种驱动方式点灯。#include zephyr/kernel.h #include zephyr/drivers/led.h // 从设备树别名led0获取LED规格 这里的宏里面不能写下划线 所以设备树要加aliases // const struct led_dt_spec led0 LED_DT_SPEC_GET(DT_ALIAS(led_0)); const struct led_dt_spec led0 LED_DT_SPEC_GET(DT_ALIAS(led0)); const struct led_dt_spec led1 LED_DT_SPEC_GET(DT_ALIAS(led1)); int main(void) { // 检查LED驱动是否就绪 if (!led_is_ready_dt(led0)) { return 0; } if (!led_is_ready_dt(led1)) { return 0; } while (1) { led_on_dt(led0); led_off_dt(led1); k_msleep(500); led_on_dt(led1); led_off_dt(led0); k_msleep(500); } }8、编译烧录west build -b jingying_f103ze . --pristine最后一个参数用来强制解析设备树。如何省去输入开发板的名字加入下图这一行即可。之后输入下面命令即可west build .9、烧录延时west flash实验​1演示本文为个人学习总结难免存在疏漏与错误欢迎大家在评论区批评指正。***********************************草稿************************************************************系统构建变量放在哪