zephyr移植到STM32

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 STM23H750ZBT6source [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 haltgdb_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_initreset 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_8STM32_FMC_SDRAM_NR_12STM32_FMC_SDRAM_MWID_16STM32_FMC_SDRAM_NB_4STM32_FMC_SDRAM_CAS_3STM32_FMC_SDRAM_SDCLK_PERIOD_2STM32_FMC_SDRAM_RBURST_ENABLESTM32_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,重新编译,烧录,板子就正常运行了。

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

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

相关文章

【分糖果——DFS】

题目 代码1 #include <bits/stdc.h> using namespace std; set<string> s; void dfs(int num1, int num2, int u, string ans) {if (u 7){if (num1 num2 > 5)return;ans (char)((num1) * 17 num2);s.insert(ans);return;}for (int i 0; i < num1; i){f…

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二、方…

解决在VS2019/2022中编译c++项目报错fatal error C1189: #error : “No Target Architecture“

解决在VS2019/2022中编译c项目报错fatal error C1189: #error : “No Target Architecture” 报错原因 在winnt.h中&#xff0c;不言而喻&#xff0c;一目了然&#xff1a; 代码节选&#xff1a; #if defined(_AMD64_) || defined(_X86_) #define PROBE_ALIGNMENT( _s ) TY…

Python教程丨Python环境搭建 (含IDE安装)——保姆级教程!

工欲善其事&#xff0c;必先利其器。 学习Python的第一步不要再加收藏夹了&#xff01;提高执行力&#xff0c;先给自己装好Python。 1. Python 下载 1.1. 下载安装包 既然要下载Python&#xff0c;我们直接进入python官网下载即可 Python 官网&#xff1a;Welcome to Pyt…

实现AVL树

目录 AVL树概念 AVL树结构 AVL树插入 LL型 - 右单旋 RR型 - 左单旋 LR型 - 左右双旋 RL型 - 右左双旋 插入代码实现 AVL树测试 附AVL树实现完整代码 AVL树概念 前面的博客介绍了搜索二叉树&#xff0c;二叉搜索树-CSDN博客 在某些特定的情况下&#xff0c;⼆叉搜索树…

极客说|微软 Phi 系列小模型和多模态小模型

作者&#xff1a;胡平 - 微软云人工智能高级专家 「极客说」 是一档专注 AI 时代开发者分享的专栏&#xff0c;我们邀请来自微软以及技术社区专家&#xff0c;带来最前沿的技术干货与实践经验。在这里&#xff0c;您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&am…

React+redux项目搭建流程

1.创建项目 create-react-app my-project --template typescript // 创建项目并使用typescript2.去除掉没用的文件夹&#xff0c;只保留部分有用的文件 3.项目配置&#xff1a; 配置项目的icon 配置项目的标题 配置项目的别名等&#xff08;craco.config.ts&…

HTML+CSS+JS制作高仿小米官网网站(内附源码,含6个页面)

一、作品介绍 HTMLCSSJS制作一个高仿小米官网网站&#xff0c;包含首页、商品详情页、确认订单页、订单支付页、收货地址管理页、新增收获地址页等6个静态页面。其中每个页面都包含一个导航栏、一个主要区域和一个底部区域。 二、页面结构 1. 顶部导航栏 包含Logo、主导航菜…

obs directx11

创建逻辑 obs 在windows 下分为Opengl 和 directx 两种渲染模式&#xff0c;默认使用的是directx &#xff0c;兼容性更好&#xff1b; 代码路径&#xff1a; E:\opensrc\obs_studio_src\obs-studio\UI\obs-app.cpp 选择渲染模式 const char* OBSApp::GetRenderModule() con…

QT实现 端口扫描暂停和继续功能 3

上篇QT给端口扫描工程增加线程2-CSDN博客 为按钮pushButton_Stop添加clicked事件&#xff0c;功能为暂停扫描&#xff0c;并在暂停后显示继续按钮&#xff0c;点击继续按钮之后继续扫描 1.更新UI 添加继续按钮 点击转到槽则会自动声明 2. 更新 MainWindow.h 需要新增的部分…

nginx-限流(请求/并发量)

一. 简述&#xff1a; 在做日常的web运维工作中&#xff0c;难免会遇到服务器流量异常&#xff0c;负载过大等情况。恶意攻击访问/爬虫等非正常性请求&#xff0c;会带来带宽的浪费&#xff0c;服务器压力增大&#xff0c;影响业务质量。 二. 限流方案&#xff1a; 对于这种情…

分布式ID生成-雪花算法实现无状态

雪花算法这里不再赘述&#xff0c;其缺点是有状态&#xff08;多副本隔离时&#xff0c;依赖手动配置workId和datacenterId&#xff09;&#xff0c;代码如下&#xff1a; /*** 雪花算法ID生成器*/ public class SnowflakeIdWorker {/*** 开始时间截 (2017-01-01)*/private st…

Edge SCDN高效防护与智能加速

当今数字化时代&#xff0c;网络安全和内容分发效率已成为企业业务发展的关键因素。酷盾安全推出了Edge SCDN解决方案&#xff0c;为企业提供全方位的安全防护和高效的内容分发服务。 一、卓越的安全防护能力 1.DDoS攻击的精准防御&#xff1a;Edge SCDN具备强大的DDoS攻击检测…

在vscode上

第一步 安装插件 &#xff08;1&#xff09;从菜单处打开vscode&#xff0c;之后点击左侧“拓展”&#xff0c;在搜索栏输入“platform”&#xff0c;安装这个插件。 注&#xff1a;安装过程可能会慢一点&#xff0c;可以尝试连接自己的热点 &#xff08;2&#xff09;安装完…

产品心、用户脑、押重注......解读vivo穿越周期之道

出品 | 何玺 排版 | 叶媛 国内科技企业中&#xff0c;vivo绝对算个“异类”。给人以平和谦逊、稳健踏实的印象&#xff0c;却极具实力&#xff01; 回望vivo发展历程&#xff0c;这家拥有近30年历史的超大型全球化产业科技生态型公司&#xff0c;从功能机到智能机一路走来&am…

jenkins入门4 --window执行execute shell

1、启动关闭jenkins 在Windows环境下&#xff0c;如果你需要关闭Jenkins服务&#xff0c;可以通过以下几种方式&#xff1a; 1、使用Windows服务管理器&#xff1a; 打开“运行”对话框&#xff08;Win R&#xff09;&#xff0c;输入services.msc&#xff0c;然后回车。 在服…

矩阵碰一碰发视频源码搭建全解析,支持OEM

在数字化营销与互动体验需求日益增长的当下&#xff0c;矩阵碰一碰发视频功能以其独特的交互性和高效的信息传播能力&#xff0c;正逐渐成为吸引用户、提升品牌影响力的有力工具。本文将深入探讨如何搭建矩阵碰一碰发视频的源码&#xff0c;帮助开发者实现这一创新功能。 一、技…

软件确认测试和验收测试有什么区别?

在当今快速发展的软件行业中&#xff0c;软件确认测试与验收测试是软件产品生产周期中的重要步骤&#xff0c;但很多人容易混淆&#xff0c;那么这两者之间究竟有什么区别呢? 软件确认测试是一个旨在确保软件产品符合用户需求规格的过程。它对软件的功能、性能和可用性进行深…

cat命令详解

cat 是 Linux/Unix 中的一个非常常用的命令&#xff0c;主要用于 连接 文件并显示文件内容。它的名称来源于 concatenate&#xff08;连接&#xff09;&#xff0c;不仅可以查看文件内容&#xff0c;还能将多个文件合并为一个文件&#xff0c;或用作其他数据流操作。 以下是对 …

[sdx12] Qualcomm SDX12查看基线版本

about.html文件 Build部分 Product SDX12.LE.1.0-00263-NBOOT.NEFS.PROD-1.90789.1 Distribution SDX12.LE.1.0|AMSS|Standard|OEM: Build Components部分 从以上截图可以看到以下模块的版本号及格式 BOOT 基线版本号 BOOT.BF.3.1.c3-00010-SDX12AAAAANAZB-1 Distr…