移植 Zephyr 到 Art-Pi

背景

​ 最近工作中接触到了 Zephyr,不由觉得 Zephyr 是个很强大、全面、优秀的实时操作系统,但同时是有一定的上手难度的,其复杂的构建系统让小编倒吸一口凉气。为了深入研究并完全掌控 Zephyr,小编决定把它移植到手头的开发板上,为后续探究 Zephyr 源码仓库的构建原理、系统启动原理、多种调度机制 打下基础。

基础知识

  • 搭建 Zephyr 环境
  • 能够使用基本的 west 命令编译、烧录、调试 bsp

可通过 Zephyr 源码调试 章节验证基础知识的掌握程度。具体 west 工具的细节以及整个 elf 文件链接过程暂时不要深究,这是个很深的坑。

移植

​ Zephyr 仓库下面有很多开发板的基础 bsp,我们可以寻找一个与我们开发板上芯片型号类似的 bsp 作为参考。Art-Pi 主控是 Stm32H750XBH6,主频高达 480Mhz,片上资源非常丰富。

我们可以参考 zephyr/boards/st 目录下的 stm32h750b_dk ,该目录树结构如下:

stm32h750b_dk
├── Kconfig.stm32h750b_dk
├── arduino_r3_connector.dtsi
├── board.cmake
├── board.yml
├── doc
│   ├── img
│   │   └── stm32h750b_dk.png
│   └── index.rst
├── stm32h750b_dk.dts
├── stm32h750b_dk.yaml
├── stm32h750b_dk_defconfig
└── support└── openocd.cfg

各文件描述如下:

  • Kconfig.stm32h750b_dk : 板级 Kconfig 定义,用于控制板级资源,如使能 HAL 层的各个驱动
  • arduino_r3_connector.dtsi : arduino 扩展引脚设备树定义,我们的板子不需要该文件,直接删除
  • board.cmake :板级 CMake 配置,一般用于配置板子所使用的调试器参数,比如使用 openocd 作为调试器 Server
  • board.yml : 板级描述文件,暂时不清楚有什么用,但没有这个文件,构建系统会报错
  • doc:板子介绍
  • stm32h750b_dk.dts : 板子设备树定义
  • stm32h750b_dk.yaml : 板级测试相关(Zephyr 自动化单元测试系统使用)
  • stm32h750b_dk_defconfig : 板级 Kconfig 默认值,如果在此处配置了默认值,就无法通过 menuconfig 或者 App 目录下的 pri.conf 文件中进行修改
  • openocd.cfg : openocd 配置文件,如果 board.cmake 中使用 openocd 作为调试器的 server,该文件将会被传递给 openocd 使用

主要是板子设备树文件比较重要,该文件涉及芯片时钟、外设、内存、flash 配置。其余文件中的内容全部改为自己的开发板,Art-Pi 设备树文件最终配置如下:

/** Copyright (c) 2023 STMicroelectronics** SPDX-License-Identifier: Apache-2.0*//dts-v1/;
#include <st/h7/stm32h750Xb.dtsi>
#include <st/h7/stm32h750xbhx-pinctrl.dtsi>
#include <zephyr/dt-bindings/input/input-event-codes.h>/ {model = "STM32H750XBH6 ART PI";compatible = "st,stm32h750xb-art-pi";chosen {zephyr,console = &uart4;  // uart4 作为控制台输出zephyr,shell-uart = &uart4; // uart4 作为控制台输入zephyr,sram = &sram0; // 使用 sram0 作为片内 sram,sram0 的定义在 dtsi 文件中zephyr,flash = &flash0; // 使用 flash0 作为片内 flash,这个并不决定链接时各符号的加载地址,而是由 CONFIG_FLASH_BASE_ADDRESS 这个宏决定,zephyr 构建系统的链接脚本有点复杂,暂时不深究};leds {compatible = "gpio-leds";blue_led: led_1 {gpios = <&gpioi 8 GPIO_ACTIVE_LOW>; // 定义板子蓝灯引脚label = "USER2 LD7";};red_led: led_2 {gpios = <&gpioc 15 GPIO_ACTIVE_LOW>; // 定义板子红灯引脚label = "USER2 LD7";};};gpio_keys {compatible = "gpio-keys"; // 定义板子按键引脚user_button: button {label = "User";gpios = <&gpioh 4 GPIO_ACTIVE_LOW>;zephyr,code = <INPUT_KEY_0>;};};sdram1: sdram@c0000000 { // 定义板子片外 sdram 地址,使用 fmc 驱动compatible = "zephyr,memory-region", "mmio-sram";device_type = "memory";reg = <0xc0000000 DT_SIZE_M(32)>; // 定义 sdram 起始地址、尺寸zephyr,memory-region = "SDRAM1";zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>;};aliases {led0 = &blue_led;led1 = &red_led;sw0 = &user_button;};
};&clk_hse { // 外部 hse 定义clock-frequency = <DT_FREQ_M(25)>;status = "okay";
};&pll { // pll 配置,h750 系列的时钟树比较复杂,可通过 cubemx 简化配置div-m = <5>;mul-n = <192>;div-p = <2>;div-q = <4>;div-r = <4>;clocks = <&clk_hse>;status = "okay";
};&rcc { // 系统各时钟域配置clocks = <&pll>;clock-frequency = <DT_FREQ_M(480)>;d1cpre = <1>;hpre = <2>;d1ppre = <2>;d2ppre1 = <2>;d2ppre2 = <2>;d3ppre = <2>;
};&uart4 { // uart4 作为 zephyr 控制台pinctrl-0 = <&uart4_tx_pa0 &uart4_rx_pi9>;pinctrl-names = "default";current-speed = <115200>;status = "okay";
};&fmc { // fmc 配置,用于驱动 sdram 芯片status = "okay";pinctrl-0 = <&fmc_nbl0_pe0 &fmc_nbl1_pe1&fmc_sdclk_pg8 &fmc_sdnwe_ph5 &fmc_sdcke0_pc3&fmc_sdne0_pc2 &fmc_sdnras_pf11 &fmc_sdncas_pg15&fmc_a0_pf0 &fmc_a1_pf1 &fmc_a2_pf2 &fmc_a3_pf3 &fmc_a4_pf4&fmc_a5_pf5 &fmc_a6_pf12 &fmc_a7_pf13 &fmc_a8_pf14&fmc_a9_pf15 &fmc_a10_pg0 &fmc_a11_pg1 &fmc_a12_pg2&fmc_a14_pg4 &fmc_a15_pg5 &fmc_d0_pd14 &fmc_d1_pd15&fmc_d2_pd0 &fmc_d3_pd1 &fmc_d4_pe7 &fmc_d5_pe8 &fmc_d6_pe9&fmc_d7_pe10 &fmc_d8_pe11 &fmc_d9_pe12 &fmc_d10_pe13&fmc_d11_pe14 &fmc_d12_pe15 &fmc_d13_pd8 &fmc_d14_pd9&fmc_d15_pd10>;pinctrl-names = "default";sdram {status = "okay";power-up-delay = <100>;num-auto-refresh = <8>;mode-register = <0x221>;refresh-rate = <0x02A5>;bank@0 {reg = <0>;st,sdram-control = <STM32_FMC_SDRAM_NC_9STM32_FMC_SDRAM_NR_13STM32_FMC_SDRAM_MWID_16STM32_FMC_SDRAM_NB_4STM32_FMC_SDRAM_CAS_2STM32_FMC_SDRAM_SDCLK_PERIOD_2STM32_FMC_SDRAM_RBURST_ENABLESTM32_FMC_SDRAM_RPIPE_0>;st,sdram-timing = <2 8 6 6 2 2 2>;};};
};

仅通过如上配置就能够编译并链接通过,其背后是 Zephyr 对 stm32 系列芯片 hal 库以及外设驱动的完美适配,以至于用户仅通过简单的设备树描述就能让外部设备正常工作起来。最终 Art-Pi 目录结构如下:

stm32h750_art_pi
├── Kconfig.defconfig
├── board.cmake
├── board.yml
├── stm32h750_art_pi.dts
├── stm32h750_art_pi_defconfig
└── support└── openocd.cfg // openocd 默认会掉用 openocd.cfg 文件,该文件用于描述 openocd 控制的硬件调试器,如 stlink,jlink 

板级调试

​ 以上步骤全部通过后会面临一个问题:如何将固件搞到芯片里面?由于我是使用的 stm32 系列,同时拥有 stlink 调试器,可通过 STM32CubeProgrammer 工具擦除并将固件下载到 flash。但会遇到一个问题,固件并没有按照预期执行,甚至没跑到 main 线程,此时连串口都不能打印日志,此时如果拥有调试器,那便是如虎添翼。

​ Zephyr 的构建系统是支持下载以及调试能力的,这时候也不需要使用 STM32CubeProgrammer 了。一般调试嵌入式设备需要硬件调试器(板子不足以运行 gdb server,但 Zephyr 貌似支持 gdb stub,这样的话可以不需要硬件调试器)、硬件调试器配套的 gdb server(stlink server、jlink server、openocd)、gdb。我们选择使用 openocd 作为 gdb server。可通过使用 west flash 命令验证能否下载固件,如图:请添加图片描述
​ 这一命令的背后到底发生了什么?其本质是调用 openocd 来将固件下入芯片内,但这背后是如何调用起 openocd,暂时不深追,这个坑很深,也正是 Zephyr 构建系统的复杂且神秘之处,给人一种知其然不知其所以然的感觉,小编决定后续几章来深究 Zephyr 构建系统原理。

​ 此时一般会发现固件跑不起来,这时候,可以使用 west debugserver 命令来起一个 gdb server,这个 gdb server 就是 openocd,它在某个端口上起一个 tcp 服务,通过 tcp 与 gdb client 交互,双方通信是明文传输,如图:请添加图片描述
​ Openocd 说它监听 3333 端口,此时我们便可以通过 gdb 来连接 3333 端口进行调试了,如图:

请添加图片描述

​ 使用命令行的方式虽然能进行调试,但是很麻烦,效率不高,这时候可参考 Zephyr 源码调试章节 进行图形化界面调试,这样子能大大提高解决问题的效率,终极调试界面如图:

请添加图片描述
我的开发环境是 wsl ubuntu,使用 wsl 连接 usb 设备需要简单的配置一下,可网上搜索 wsl usb 关键字查看相关教程。

应用配置

​ 移植完毕后,可通过 Zephyr 仓库 zephyr/samples/basic/blinky 下的应用来验证,比如可在 main 函数中翻转 led 灯来验证。但此时,Zephyr 的 shell 还不能使用,因为 shell 作为 Zephyr 的一个子系统此时还未使能,这也是 Zephyr 构建系统的一大优势,以搭积木的形式构建系统,缺少某一模块,仍然能够编译链接通过,仅仅是该能力缺失而已。可在 zephyr/samples/basic/blinky 下的 prj.conf 文件中添加如下配置:

CONFIG_GPIO=y
CONFIG_UART_CONSOLE=y //使能 uart console
CONFIG_SHELL=y //使能 shell 模块
CONFIG_MEMC=y
CONFIG_MEMC_STM32=y
CONFIG_MEMC_STM32_SDRAM=y

​ 最终就能丝滑的感受 Zephyr 了,这才有点操作系统的味道。
请添加图片描述
最终附上 项目地址 ,欢迎 Star~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768645.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot实现合并单元格的excel文件导入到数据库(多模块)

最近做项目的时候一直在遇到excel导入导出的问题&#xff0c;本篇博文也是为了记录我这几天的血泪史&#xff0c;并做以记录&#xff0c;希望各位看完之后能有所收获。 以下是我excel文档里面的具体内容&#xff1a; excel文件中的编码信息属于另外一张表&#xff0c;所以以下…

android emulator windows bat启动

android emulator windows bat启动 先上结果 // 模拟器路径 -netspeed full -avd 模拟器名称 C:\Users\name\AppData\Local\Android\Sdk\emulator\emulator.exe -netdelay none -netspeed full -avd Pixel_3a_API_34_extension_level_7_x86_64一般来说 windows 如果不做…

2023年全国职业院校技能大赛(网络系统管理赛项)样题一

2023****年全国职业院校技能大赛 GZ073****网络系统管理赛项 赛题第1套 模块A&#xff1a;网络构建 目 录 任务清单… 1 &#xff08;一&#xff09;基础配置… 1 &#xff08;二&#xff09;有线网络配置… 1 &#xff08;三&#xff09;无线网络配置… 3 &#xff0…

初探Flink集群【持续更新】

周末下雨&#xff0c;倒杯茶&#xff0c;在家练习Flink相关。 开发工具&#xff1a;IntelliJ Idea 第一步、创建项目 打开Idea&#xff0c;新建Maven项目&#xff0c;包和项目命名 在pom.xml 文件中添加依赖 <properties><flink.version>1.13.0</flink.vers…

使用Python进行股票分析(2)

简介 我们在之前的文章《使用Python进行股票分析&#xff08;1&#xff09;》中&#xff0c;通过自动获取股票的历史数据&#xff0c;然后选择在一定时间内处于上涨的股票作为我们投资的标的。在本文中&#xff0c;我们进一步通过分析股票的短期趋势&#xff0c;选择处于短期上…

Ubuntu Desktop 安装谷歌拼音输入法

Ubuntu Desktop 安装谷歌拼音输入法 1. Installation1.1. 汉语语言包​1.2. 谷歌拼音输入法1.3. 安装语言包1.4. 键盘输入方式系统1.5. 重启电脑1.6. 输入法配置 2. configuration2.1. Text Entry Settings… 3. ExecutionReferences 1. Installation 1.1. 汉语语言包 strong…

springcloud第4季 负载均衡的介绍3

一 loadbalance 1.1 负载均衡的介绍 使用注解loadbalance&#xff0c;是一个客户端的负载均衡器&#xff1b;通过之前已经从注册中心拉取缓存到本地的服务列表中&#xff0c;获取服务进行轮询负载请求服务列表中的数据。 轮询原理 1.2 loadbalance工作流程 loadBalance工作…

再仔细品品Elasticsearch的向量检索

我在es一开始有向量检索&#xff0c;就开始关注这方面内容了。特别是在8.X之后的版本&#xff0c;更是如此。我也已经把它应用在亿级的生产环境中&#xff0c;用于多模态检索和语义检索&#xff0c;以及RAG相关。 也做过很多的优化&#xff1a;ES 8.x 向量检索性能测试 & 把…

Swift 从获取所有 NSObject 对象聊起:ObjC、汇编语言以及底层方法调用链(三)

概览 承接上一篇博文: Swift 从获取所有 NSObject 对象聊起:ObjC、汇编语言以及底层方法调用链(二)我们在其中讨论了如何使用第三方强大通用的钩子库 SwiftHook 来协助我们完成 NSObject 构造器 init 的 SWIZZ 操作。我们还讨论了为什么用 print 打印对象信息时会发生崩溃…

Unity 布局元素Layout Element

Layout Element是一种用于控制UI元素在布局组件&#xff08;如Horizontal Layout Group、Vertical Layout Group、Grid Layout Group、Content Size Fitter和Aspect Ratio Fitter&#xff09;中的大小和位置的组件。Layout Element组件可以附加到UI元素上&#xff0c;以便在布局…

opencv各个模块介绍(2)

Features2D 模块&#xff1a;特征检测和描述子计算模块&#xff0c;包括SIFT、SURF等算法。 Features2D 模块提供了许多用于特征检测和描述子匹配的函数和类&#xff0c;这些函数和类可用于图像特征的提取、匹配和跟踪。 FeatureDetector&#xff1a;特征检测器的基类&#xf…

arm 外部中断

main.c: #include"key_inc.h" //封装延时函数 void delay(int ms) {int i,j;for(i0;i<ms;i){for(j0;j<2000;j){}} } int main() {//按键中断的初始化key1_it_config();key2_it_config();key3_it_config();while(1){printf("in main pro\n");delay(1…

查看Linux系统重启的四种基本命令

目录 前言1. last2. uptime3. journalctl4. dmesg 前言 对于排查其原因推荐阅读&#xff1a;详细分析服务器自动重启原因&#xff08;涉及Linux、Window&#xff09; 在Linux中&#xff0c;有多种命令可以查看系统重启的信息 以下是其中一些常用的命令及其解释&#xff1a; …

EasyPOI操作Excel从零入门

教程介绍 我们不造轮子&#xff0c;只是轮子的搬运工。&#xff08;其实最好是造轮子&#xff0c;造比别人好的轮子&#xff09;开发中经常会遇到excel的处理&#xff0c;导入导出解析等等&#xff0c;java中比较流行的用poi&#xff0c;但是每次都要写大段工具类来搞定这事儿…

【新版】系统架构设计师 - 新版架构备考索引<附2023年11月原题回忆>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 新版架构备考索引机考详情备考索引与方向&#xff08;个人观点&#xff0c;仅供参考&#xff09;总结附&#xff1a;2023年11月改版机试原题简单回忆 架构 - 新版架构备考索引 首先&#xff0c;此…

Spring 简介

1. Spring简介 1.1 Spring 核心设计思想 1.1.1 Spring 是什么&#xff1f; Spring 是包含了众多⼯具⽅法的 IoC 容器。Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个开源框架&#xff0c;Spring ⽀持⼴泛的应⽤场景&#xff0c;它…

月之暗面Kimi代码分析能力评测

最近打算重构一下PawSQL优化引擎中的OR条件的SELECT重写优化策略的代码&#xff0c;时间有点久&#xff0c;代码有点复杂&#xff0c;看到网上对新出了KIMI评价很高。于是尝试用它来理解一下代码。上传了此优化重写的代码&#xff0c;提问&#xff1a; 第一问&#xff0c;设计…

java多线程编程面试题总结

一些最基本的基础知识就不总结了&#xff0c;参考之前写的如下几篇博客&#xff0c;阅读顺序从上到下&#xff0c;依次递进。 java 多线程 多线程概述及其三种创建方式 线程的常用方法 java 线程安全问题 三种线程同步方案 线程通信&#xff08;了解&#xff09; java 线程池…

炸裂消息,全球首创全员持股短视频平台诞生

平台简介&#xff1a;享视是国内首家基于区块链打造的共益型短视频平台&#xff0c;也是全球首家真正践行共益模式的科技型创新企业&#xff0c;计划将80%的股权免费分发和共享给平台的会员&#xff0c;共同打造一家全员持股的共益商业模式示范标杆企业。 平台愿景&#xff1a…

Spark Streaming DStream

Spark Streaming DStream DStream 即Discretized Stream&#xff0c;中文叫做离散流&#xff0c;Spark Streaming提供的一种高级抽象&#xff0c;代表了一个持续不断的数据流。 DStream可以通过输入数据源来创建&#xff0c;比如Kafka、Flume&#xff0c;也可以通过对其他DS…