Zephy如何移植到单片机

  • 1. Window下搭建开发环境
  • 1.1 安装Choncolatey
  • 1.2 安装相关依赖
  • 1.3创建虚拟python环境
  • 1.4 安装west
  • 1.4.1 使用 pip 安装 west
  • 1.4.2 检查 west 安装路径
  • 1.4.3 将 Scripts路径添加到环境变量
  • 1.4.4 验证安装
  • 1.5 获取zephyr源码和[安装python](https://so.csdn.net/so/search?q=安装python&spm=1001.2101.3001.7020)依赖
  • 1.6 安装Zephyr SDK
  • 2.编译构建程序(虚拟开发板)
  • 3.在STM32H750上运行zephyr
  • 3.1 新建boards相关文件
  • 3.2 修改boards相关配置文件
  • 4.测试
  • 开发板:DshanMCUF407

    官方开发文档:入门指南 — Zephyr Project Documentation

    1. Window下搭建开发环境

    1.1 安装Choncolatey

    powershell 管理员下执行如下命令:

    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
    

    1.2 安装相关依赖

    choco feature enable -n allowGlobalConfirmation
    choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
    choco install ninja gperf python311 git dtc-msys2 wget 7zip
    

    同样是在管理员模式下执行以上命令,使用cmd也是可以的;

    1.3创建虚拟python环境

    以普通用户身份打开终端窗口

    cd %HOMEPATH%
    python -m venv zephyrproject\.venv
    

    激活虚拟环境:

    cmd 下使用以下命令激活:

    zephyrproject\.venv\Scripts\activate.bat
    

    powershell 下使用以下命令激活:

    zephyrproject\.venv\Scripts\Activate.ps1
    

    退出虚拟环境:

    (.venv)deactivate
    

    1.4 安装west

    1.4.1 使用 pip 安装 west

    west是Zephyr自己的构建元工具,实际上Zephyr是基于Cmake编写的,west会根据当前环境去调用cmake去编译,这样为我们省去了许多编译步骤.

    pip install west
    
    1.4.2 检查 west 安装路径

    完成安装后,执行以下命令验证 west 是否安装成功:

    west --version
    

    如果显示 west 的版本号,说明安装成功,可以继续使用 west 命令。如果仍然出现无法识别 west 命令的情况,尝试west 安装路径添加到环境变量:

    默认情况下,pip 安装的包会放在 Scripts 目录中。请确认 Scripts 路径是否已添加到系统环境变量中。

    west 的安装目录可能在以下路径中(假设 Python 安装在默认位置):

    C:\Users\100ask\AppData\Roaming\Python\Python311\Scripts
    
    1.4.3 将 Scripts路径添加到环境变量
    1. 打开 “环境变量” 设置(右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”)。
    2. 在 “系统变量” 中找到 Path 变量并编辑。
    3. 添加 Scripts 文件夹路径,例如:
    C:\Users\100ask\AppData\Roaming\Python\Python311\Scripts
    
    1. 确保更改后点击 “确定” 并重启 PowerShell。
    1.4.4 验证安装

    重启 PowerShell,然后运行以下命令验证 west 是否安装成功:

    west --version
    

    如果仍然出现无法识别 west 命令的情况,尝试直接使用以下命令执行:

    python -m west ...
    

    1.5 获取zephyr源码和安装python依赖

    新建一个文件夹zephyrproject,执行以下操作:

    west init zephyrproject // 初始化zephyr环境并获取源码
    cd zephyrproject        // 进入zephyrproject目录
    west update				// 更新zephyr源码
    

    导出 Zephyr Cmake package

    west zephyr-export
    

    这个package可以让Cmake自动加载构建Zephyr应用程序需要的样本代码

    安装 python依赖

    pip install -r %HOMEPATH%\zephyrproject\zephyr\scripts\requirements.txt
    

    -r是指定依赖文件;

    %HOMEPATH%是哪个路径下。

    1.6 安装Zephyr SDK

    Zephyr 软件开发工具包 (SDK) 包含适用于 Zephyr 支持的每个架构的工具链,这些工具链 包括编译器、汇编器、链接器和其他构建所需的程序 Zephyr 应用程序。

    使用 安装 Zephyr SDK

    cd %HOMEPATH%\zephyrproject\zephyr
    west sdk install
    

    如果安装不成功,大多数是网络原因,可跟换网络重新进行,也可以进入官网直接获取,然后解压

    最后运行文件夹下 setup.cmd,只需要运行一次就好,如果不更改SDK源码的情况下:

    2.编译构建程序(虚拟开发板)

    首先我们可以编译一个例程,Sample文件下有很多的示例,我这里编译一个Blinky,led闪烁的示例:

    如果您不确定 west 为您的开发板使用什么名称,可以使用该名称来获取 Zephyr 支持的所有开发板的列表。west boards

    使用 west 构建 Blinky,为您的板进行适当的更改:<your-board-name>

    cd %HOMEPATH%\zephyrproject\zephyr
    west build -p always -b <your-board-name> samples\basic\blinky
    

    例如:我们采用qemu_cortex_m3,运行Blinky程序,编译结果如下:

    打开cmd.exe,进入zephyr目录,启动虚拟环境:

    运行Blinky程序:

    在zephyr目录中有一个虚拟的qemu开发板类型,我们可以安装qemu使用虚拟开发板验证我们的环境:

    cd zephyrproject\zephyr
    west build -p always -b <qemu_cortex_m3> samples/hello_world
    

    执行以下命令运行程序:

    west build -t run
    

    3.在STM32H750上运行zephyr

    当你拿到一个板时可以在zephyr的boards目录下查看是否支持,根据你板子的核以及型号去查

    比如我的是stm32h750系列的,这里我通过开发板上的板名去查

    cd /scr/zephyrproject/zephyr/boards/st
    dir
    

    使用dir命令列出st目录下所有开发板,看一下有没有符合自己的开发板;

    也可以使用vscode 打开zephyrproject工程文件,进入boards/st目录下手动找到符合我们的开发板,或者vscode搜索STM32h750,找到我们需要的:

    注意:搜索时需要找到boards目录下的,如下图所示:

    3.1 新建boards相关文件

    我们需要在zephyr/boards/st/ 下新建一个我们的开发板的文件夹,如果官方支持的开发板里没有和我们板子主控相同的,需要找个相近的复制一下,这里我复制的是stm32h750b_dk

    将我们复制下来的开发板文件夹改成我们自己开发板的名字,文件夹内与板子名称有关的文件同一样修改成对应的名字:

    3.2 修改boards相关配置文件

    我们从上往下一次查看并修改每个文件得内容:

    修改openocd配置文件:

    source [find interface/stlink-dap.cfg]
    transport select "dapdirect_swd"
    
    set WORKAREASIZE 0x2000
    set CHIPNAME STM32H750ZBTx
    set BOARDNAME STM23H750ZBT6
    
    source [find target/stm32h7x.cfg]
    
    # Use connect_assert_srst here to be able to program
    # even when core is in sleep mode
    # reset_config srst_only srst_nogate connect_assert_srst
    
    $_CHIPNAME.cpu0 configure -event gdb-attach {
            echo "Debugger attaching: halting execution"
            #reset halt
            gdb_breakpoint_override hard
    }
    
    $_CHIPNAME.cpu0 configure -event gdb-detach {
            echo "Debugger detaching: resuming execution"
            resume
    }
    
    # Due to the use of connect_assert_srst, running gdb requires
    # to reset halt just after openocd init.
    rename init old_init
    proc init {} {
            old_init
            reset halt
    }
    

    如果想使用openocd进行烧录,安装好openocd,按照如上配置既可。

    修改board.cmake文件:

    这里要指定我们使用那种方法进行烧录,这个支持使用stm32cubeprogrammer、Jlink、openocd

    stm32cubeprogrammer和openocd我这里都是使用Stlink进行烧录

    **修改board.yml文件 **

    修改Kconfig.defconfig和Kconfig.stm32h750zbt6文件

    仅修改名字,其他保持不变。

    修改stm32h750zbt6_defconfig文件:

    修改stm32h750zbt6.dts文件:

    修改为对应头文件和开发板名称

    修改配置文件:

    修改led和串口

    串口需要修改为usart1,TX->pa9,RX->pa10

    完整dts的配置如下:

    /*
     * Copyright (c) 2023-2024 STMicroelectronics
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    /dts-v1/;
    #include <st/h7/stm32h750Xb.dtsi>
    #include <st/h7/stm32h750xbhx-pinctrl.dtsi>
    #include "arduino_r3_connector.dtsi"
    #include <zephyr/dt-bindings/input/input-event-codes.h>
    
    / {
    	model = "STMicroelectronics STM32H750ZBT6";
    	compatible = "st,stm32h750zbt6";
    
    	chosen {
    		zephyr,console = &usart1;
    		zephyr,shell-uart = &usart1;
    		zephyr,sram = &sram0;
    		zephyr,flash = &flash0;
    		zephyr,flash-controller = &mt25ql512ab1;
    		zephyr,display = &ltdc;
    	};
    
    	sdram2: sdram@d0000000 {
    		compatible = "zephyr,memory-region", "mmio-sram";
    		device_type = "memory";
    		reg = <0xd0000000 DT_SIZE_M(16)>; /* 128Mbit */
    		zephyr,memory-region = "SDRAM2";
    		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>;
    	};
    
    	ext_memory: memory@90000000 {
    		compatible = "zephyr,memory-region";
    		reg = <0x90000000 DT_SIZE_M(256)>; /* max addressable area */
    		zephyr,memory-region = "EXTMEM";
    		/* The ATTR_MPU_EXTMEM attribut causing a MPU FAULT */
    		zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_IO) )>;
    	};
    
    	leds {
    		compatible = "gpio-leds";
    		led_1: led_1 {
    			gpios = <&gpiof 9 GPIO_ACTIVE_LOW>;
    			label = "User1 LD1";
    		};
    		led_2: led_2 {
    			gpios = <&gpiof 10 GPIO_ACTIVE_LOW>;
    			label = "User2 LD2";
    		};
    	};
    
    	gpio_keys {
    		compatible = "gpio-keys";
    		user_button: button {
    			label = "User";
    			gpios = <&gpioc 13 GPIO_ACTIVE_HIGH>;
    			zephyr,code = <INPUT_KEY_0>;
    		};
    	};
    
    	aliases {
    		led0 = &led_1;
    		led1 = &led_2;
    		sw0 = &user_button;
    		die-temp0 = &die_temp;
    	};
    };
    
    &clk_hse {
    	clock-frequency = <DT_FREQ_M(25)>;
    	status = "okay";
    };
    
    &clk_lse {
    	status = "okay";
    };
    
    &ltdc {
    	pinctrl-0 = <&ltdc_r0_pi15 &ltdc_r1_pj0 &ltdc_r2_pj1 &ltdc_r3_ph9
    		&ltdc_r4_pj3 &ltdc_r5_pj4 &ltdc_r6_pj5 &ltdc_r7_pj6
    		&ltdc_g0_pj7 &ltdc_g1_pj8 &ltdc_g2_pj9 &ltdc_g3_pj10
    		&ltdc_g4_pj11 &ltdc_g5_pi0 &ltdc_g6_pi1 &ltdc_g7_pk2
    		&ltdc_b0_pj12 &ltdc_b1_pj13 &ltdc_b2_pj14 &ltdc_b3_pj15
    		&ltdc_b4_pk3 &ltdc_b5_pk4 &ltdc_b6_pk5 &ltdc_b7_pk6
    		&ltdc_de_pk7 &ltdc_clk_pi14 &ltdc_hsync_pi12 &ltdc_vsync_pi9>;
    	pinctrl-names = "default";
    
    	disp-on-gpios = <&gpiod 7 GPIO_ACTIVE_HIGH>;
    
    	ext-sdram = <&sdram2>;
    	status = "okay";
    
    	clocks = <&rcc STM32_CLOCK_BUS_APB3 0x00000008>,
    		<&rcc STM32_SRC_PLL3_R NO_SEL>;
    
    	width = <480>;
    	height = <272>;
    	pixel-format = <PANEL_PIXEL_FORMAT_RGB_565>;
    	display-timings {
    		compatible = "zephyr,panel-timing";
    		de-active = <1>;
    		pixelclk-active = <0>;
    		hsync-active = <0>;
    		vsync-active = <0>;
    		hsync-len = <1>;
    		vsync-len = <10>;
    		hback-porch = <43>;
    		vback-porch = <12>;
    		hfront-porch = <8>;
    		vfront-porch = <4>;
    	};
    	def-back-color-red = <0xFF>;
    	def-back-color-green = <0xFF>;
    	def-back-color-blue = <0xFF>;
    };
    
    &pll {
    	div-m = <5>;
    	mul-n = <192>;
    	div-p = <2>;
    	div-q = <2>;
    	div-r = <5>;
    	clocks = <&clk_hse>;
    	status = "okay";
    };
    
    &pll3 {
    	div-m = <5>;
    	mul-n = <192>;
    	div-p = <2>;
    	div-q = <20>;
    	div-r = <99>;
    	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>;
    };
    
    &usart1 {
    	pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
    	pinctrl-names = "default";
    	current-speed = <115200>;
    	status = "okay";
    };
    
    &quadspi {
    	pinctrl-names = "default";
    	pinctrl-0 = <&quadspi_clk_pf10 &quadspi_bk1_ncs_pg6
    		     &quadspi_bk1_io0_pd11 &quadspi_bk1_io1_pf9
    		     &quadspi_bk1_io2_pf7 &quadspi_bk1_io3_pf6
    		     &quadspi_bk2_io0_ph2 &quadspi_bk2_io1_ph3
    		     &quadspi_bk2_io2_pg9 &quadspi_bk2_io3_pg14>;
    	dual-flash;
    	status = "okay";
    
    	mt25ql512ab1: qspi-nor-flash-1@90000000 {
    		compatible = "st,stm32-qspi-nor";
    		reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */
    		qspi-max-frequency = <72000000>;
    		spi-bus-width = <4>;
    		reset-cmd;
    		status = "okay";
    
    		partitions {
    			compatible = "fixed-partitions";
    			#address-cells = <1>;
    			#size-cells = <1>;
    
    			partition@0 {
    				reg = <0x0 DT_SIZE_M(64)>;
    			};
    		};
    	};
    
    	mt25ql512ab2: qspi-nor-flash-2@90000000 {
    		compatible = "st,stm32-qspi-nor";
    		reg = <0x90000000 DT_SIZE_M(64)>; /* 512 Mbits */
    		qspi-max-frequency = <72000000>;
    		status = "okay";
    	};
    };
    
    &fmc {
    	pinctrl-0 = <&fmc_nbl0_pe0 &fmc_nbl1_pe1
    		&fmc_sdclk_pg8 &fmc_sdnwe_ph5 &fmc_sdcke1_ph7
    		&fmc_sdne1_ph6 &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_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";
    	status = "okay";
    
    	sdram {
    		status = "okay";
    		power-up-delay = <100>;
    		num-auto-refresh = <8>;
    		mode-register = <0x230>;
    		refresh-rate = <0x603>;
    		bank@1 {
    			reg = <1>;
    			st,sdram-control = <STM32_FMC_SDRAM_NC_8
    				STM32_FMC_SDRAM_NR_12
    				STM32_FMC_SDRAM_MWID_16
    				STM32_FMC_SDRAM_NB_4
    				STM32_FMC_SDRAM_CAS_3
    				STM32_FMC_SDRAM_SDCLK_PERIOD_2
    				STM32_FMC_SDRAM_RBURST_ENABLE
    				STM32_FMC_SDRAM_RPIPE_1>;
    			st,sdram-timing = <2 7 4 7 2 2 2>;
    		};
    	};
    };
    
    &rtc {
    	clocks = <&rcc STM32_CLOCK_BUS_APB4 0x00010000>,
    		 <&rcc STM32_SRC_LSE RTC_SEL(1)>;
    	status = "okay";
    };
    
    &die_temp {
    	status = "okay";
    };
    
    &adc3 {
    	st,adc-clock-source = <SYNC>;
    	st,adc-prescaler = <4>;
    	status = "okay";
    };
    
    /* Arduino Header pins: Tx:D1, Rx:D0 */
    /* LPUART1 can also be used with this pins */
    &usart1 {
    	dma-names = "tx", "rx";
    	pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>;
    	pinctrl-names = "default";
    	current-speed = <115200>;
    	status = "okay";
    };
    
    

    4.测试

    修改好之后,我们编译一个zephyr自带的跑马灯demo试一下,使用指令:

    west build -p always -b stm32h750zbt6 samples/basic/blinky
    

    编译无问题,接好调试器后,我们使用以下命令进行下载:

    west flash //使用stm32cubeprogrammer 进行下载
    west flash -r openocd   //使用openocd进行下载
    west flash -r jlink     //使用jlink进行下载
    

    烧录完成后,我们可以看到开发板led1开始闪烁,并且也可以通过串口查看到打印出led的状态;

    注意:

    如果成功烧录没有反应,检查stm32h750zbt6_defconfig文件有没有配置系统时钟和外部HSE时钟

    关闭HSE旁路模式

    去掉hse-bypass,重新编译,烧录,板子就正常运行了。

    作者:韦东山

    物联沃分享整理
    物联沃-IOTWORD物联网 » zephyr移植到STM32

    发表回复