2022-12-13 note

news2024/11/25 16:45:58

1、linux内核的特点

1. linux内核是完全开源的
	作者:linus
	git --> 代码版本管理工具
2. linux内核源码支持多种不同的架构,比如arm架构,powerPC,mips,Risc-V,X86等
3. linux内核采用模块化的编译的思想
4. 在linux内核中只允许出现C代码或者汇编代码
5. 在嵌入式设备开发中基本上使用的都是linux内核源码。

2、分析linux内核源码

1> 将linux-stm32mp-5.10.61-stm32mp-r2-r0.7z压缩包在windows下进行解压缩,解压缩之后得到linux-stm32mp-5.10.61-stm32mp-r2-r0文件夹,

linux-stm32mp-5.10.61-stm32mp-r2-r0.7z压缩包上传到qq群中。

2> 拷贝linux-stm32mp-5.10.61-stm32mp-r2-r0文件夹到ubuntu中,并cd到linux-stm32mp-5.10.61-stm32mp-r2-r0文件中

	cd linux-stm32mp-5.10.61-stm32mp-r2-r0

3> 分析linux-stm32mp-5.10.61-stm32mp-r2-r0文件夹中的所有的文件

.
├── 0001-ARM-5.10.61-stm32mp1-r2-MACHINE.patch   ---> linux内核的补丁文件
├── 0002-ARM-5.10.61-stm32mp1-r2-CLOCK.patch
├── 0003-ARM-5.10.61-stm32mp1-r2-CPUFREQ.patch
├── 0004-ARM-5.10.61-stm32mp1-r2-CRYPTO.patch
├── 0005-ARM-5.10.61-stm32mp1-r2-DMA.patch
├── 0006-ARM-5.10.61-stm32mp1-r2-DRM.patch
├── 0007-ARM-5.10.61-stm32mp1-r2-HWSPINLOCK.patch
├── 0008-ARM-5.10.61-stm32mp1-r2-I2C-IIO-IRQCHIP.patch
├── 0009-ARM-5.10.61-stm32mp1-r2-MAILBOX-REMOTEPROC-RPMSG.patch
├── 0010-ARM-5.10.61-stm32mp1-r2-MEDIA-SOC-THERMAL.patch
├── 0011-ARM-5.10.61-stm32mp1-r2-MFD.patch
├── 0012-ARM-5.10.61-stm32mp1-r2-MMC.patch
├── 0013-ARM-5.10.61-stm32mp1-r2-NET-TTY.patch
├── 0014-ARM-5.10.61-stm32mp1-r2-PERF.patch
├── 0015-ARM-5.10.61-stm32mp1-r2-PHY-USB.patch
├── 0016-ARM-5.10.61-stm32mp1-r2-PINCTRL-REGULATOR-SPI.patch
├── 0017-ARM-5.10.61-stm32mp1-r2-RESET-RTC-WATCHDOG.patch
├── 0018-ARM-5.10.61-stm32mp1-r2-SCMI.patch
├── 0019-ARM-5.10.61-stm32mp1-r2-SOUND.patch
├── 0020-ARM-5.10.61-stm32mp1-r2-MISC.patch
├── 0021-ARM-5.10.61-stm32mp1-r2-CPUIDLE-POWER.patch
├── 0022-ARM-5.10.61-stm32mp1-r2-DEVICETREE.patch
├── 0023-ARM-5.10.61-stm32mp1-r2-CONFIG.patch     ---> linux内核的补丁文件
├── fragment-03-systemd.config  ---> 碎片化的配置文件
├── fragment-04-modules.config  ---> 碎片化的配置文件
├── fragment-05-signature.config ---> 碎片化的配置文件
├── linux-5.10.61.tar.xz  ---> linux内核源码的压缩包
├── README.HOW_TO.txt ----> 帮助文件
└── series   ---> 补丁文件列表信息

4> 分析README.HOW_TO.txt文件

1. 配置交叉编译器
	 CROSS_COMPILE=arm-ostl-linux-gnueabi-

2. 准备内核源码
	对内恶化源码进行解压缩
     	 $> tar xfJ linux-5.10.61.tar.xz
	进入内核源码目录下
 	     $> cd linux-5.10.61
  	对内核源码进行打补丁
 	     $> for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

3. 配置内核源码
	方式1:
	配置内核源码时将配置过程生成的中间文件指定到内核源码同一级的目录build目录下,
	通过make时给O=参数赋值来指定中间文件的存放路径
	
	     $ cd <directory to kernel source code>
	     $> mkdir -p ../build
	     $> make ARCH=arm O="$PWD/../build" multi_v7_defconfig fragment*.config
	将碎片配置文件写到.config配置文件中  
	     $ scripts/kconfig/merge_config.sh -m -r -O $PWD/../build $PWD/../build/.config ../fragment-01-xxx.config
	     $ scripts/kconfig/merge_config.sh -m -r -O $PWD/../build $PWD/../build/.config ../fragment-02-xxx.config
	     ...
	     $ yes '' | make ARCH=arm oldconfig O="$PWD/../build"
	     
		或者使用for循环的方式将碎片的配置文件信息写到.config文件中
	    $> for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r -O $PWD/../build $PWD/../build/.config $f; done
	    $> yes '' | make ARCH=arm oldconfig O="$PWD/../build"
	
	方式2:
	将配置过程生成的中间文件,放到内核源码目录下:
	$ cd <directory to kernel source code>
    $ make ARCH=arm multi_v7_defconfig fragment*.config
                            
    将碎片配置文件写到.config配置文件中  
    $ scripts/kconfig/merge_config.sh -m -r .config ../fragment-01-xxxx.config
    $ scripts/kconfig/merge_config.sh -m -r .config ../fragment-02-xxxx.config
    ...
    $ yes '' | make oldconfig
    
    或者使用for循环的方式将碎片的配置文件信息写到.config文件中
    $ for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
    $ yes '' | make ARCH=arm oldconfig

4. 编译内核源码
	方式1:
	将编译内核源码过程产生的中间文件,放到build指定的目录下,
	通过执行make时给O=参数指定一个编译的路径即可
    $ cd <directory to kernel source code>
    编译内核源码生成uImage和vmlinux和设备树文件
    $> make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040 O="$PWD/../build"
    模块化编译内核源码,对内核中模块化的驱动进行编译
    $> make ARCH=arm modules O="$PWD/../build"
    
    方式2:
    编译内核源码,将编译内核源码过程生成的中间文件放到内核源码目录下
    $ cd <directory to kernel source code>
    编译内核源码生成uImage和vmlinux和设备树文件
    $ make ARCH=arm uImage vmlinux dtbs LOADADDR=0xC2000040
    模块化编译内核源码,对内核中模块化的驱动进行编译
    $ make ARCH=arm modules   

3、正式开始对linux内核源码进行配置和编译

1> 拷贝linux-stm32mp-5.10.61-stm32mp-r2-r0文件夹到ubuntu中,并cd到linux-stm32mp-5.10.61-stm32mp-r2-r0文件中

	$ cd linux-stm32mp-5.10.61-stm32mp-r2-r0

2> 对linux内核源码压缩包进行解压缩,并进入内核源码目录下

	$ tar -vxf linux-5.10.61.tar.xz ^C
	$ cd linux-5.10.61/

3> 分析linux内核源码目录下的所有的文件

image-20221114141654143

image-20221114141708181

4> 执行make help获取make的帮助信息

1. 清除目标文件
	make clean
	make mrproper
	make distclean

2. 图形化界面配置内核
	make menuconfig
	
3. 配置内核
	make <board_name>_defconfig

4. 编译内核源码
	make uImage
	make vmlinux
	make dtbs
	make modules

5> 打开内核源码目录下的Makefile文件,配置交叉编译器

将以下内容:
	 370 ARCH        ?= $(SUBARCH)

修改为:
 	370 ARCH        ?= arm
 	371 CROSS_COMPILE ?= arm-linux-gnueabihf-


6> 对内核源码进行打补丁

	$  for p in `ls -1 ../*.patch`; do patch -p1 < $p; done

7> 配置内核源码生成.config的配置文件

	$ make multi_v7_defconfig fragment*.config
                            
    $ for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
    
    $ yes '' | make oldconfig

8> 根据DK1板子的设备树文件拷贝生成FSMP1A板子的设备树文件

1. 使用ls arch/arm/boot/dts/*stm32mp15* 查看DK1板子的设备树文件
    arch/arm/boot/dts/stm32mp157a-dk1.dts
    arch/arm/boot/dts/stm32mp15xx-dkx.dtsi

2. 根据DK1板子的设备树文件拷贝生成fsmp1a板子的设备树文件
	cd arch/arm/boot/dts/
	cp stm32mp157a-dk1.dts stm32mp157a-fsmp1a.dts
    cp stm32mp15xx-dkx.dtsi stm32mp15xx-fsmp1x.dtsi
	cd ../../../../
	
3. 修改arch/arm/boot/dts/目录下的stm32mp157a-fsmp1a.dts
	将以下内容:
	 13 #include "stm32mp15xx-dkx.dtsi"
     14     
     15 / {
     16     model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
     17     compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
	
	修改为:
	 13 #include "stm32mp15xx-fsmp1x.dtsi"
     14     
     15 / {
     16     model = "STMicroelectronics STM32MP157A-fsmp1a Discovery Board";
     17     compatible = "st,stm32mp157a-fsmp1a", "st,stm32mp157";

4. 修改arch/arm/boot/dts/目录下的Makefile文件,添加fsmp1a的设备树的编译的信息
	1096     stm32mp157a-dhcor-avenger96.dtb \
    1097     stm32mp157a-dk1.dtb \
    # 以下行是添加的关于fsmp1a设备树的编译的信息
    1098     stm32mp157a-fsmp1a.dtb \   

9> 编译linux内核源码

	make -j4 uImage vmlinux dtbs LOADADDR=0xC2000000
	
	或者是(要想生成uImage镜像文件必须先生成vmlinux文件)
	make -j4 uImage dtbs LOADADDR=0xC2000000
	
	或者
	make -j4 uImage LOADADDR=0xC2000000
	make dtbs

10> 内核源码编译成功之后生成uImage镜像文件,使用开发阶段启动方式测试uImage和内核的设备树文件

1. 编译linux内核成功之后,内核镜像文件和设备树文件的路径
	linux内核镜像文件uImage的路径为:arch/arm/boot/uImage
	stm32mp157a-fsmp1a.dtb的设备树文件路径为:arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb
	
2. 使用开发阶段系统的启动方式测试自己编译的内核及设备树文件

	2.1>拷贝uImage和stm32mp157a-fsmp1a.dtb文件到~/tftpboot目录下
	cp arch/arm/boot/uImage ~/tftpboot
	cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb ~/tftpboot

	2.2> 启动开发板设置u-boot的启动参数,bootcmd,和bootargs
		如果bootcmd和bootargs参数设置为开发阶段的启动参数可以忽略此步骤
	2.3> 启动开发板,分析linux内核是否可以启动成功。linux内核启动失败,如下图。
	

image-20221114154630657

4、解决linux内核启动不成功的错误

错误的原因:FSMP1A板子的设备树文件是基于DK1板子的设备树文件进行拷贝的,
	DK1板子采用的是电源管理单元,FSMP1A板子采用的是独立电源,部分硬件是由差异的,
	因此需要对FSMP1A板子的设备树文件进行修改,本次使用的设备树可以保证FSMP1A的板子
	启动,后续根据需要在对设备树中的信息进行添加即可。
	

1> 修改好的linux内核的设备树文件.7z 压缩包下载之后在window系统中进行解压缩

修改好的linux内核的设备树文件.7z 的压缩文件上传到有道云笔记。

2> 拷贝<修改好的linux内核的设备树文件>文件夹中设备树文件到linux内核源码的arch/arm/boot/dts目录下

	自行拷贝

3> 重新对设备树文件进行编译,不需要重新编译生成uImage镜像文件

删除原有生成的.dtb文件
	rm arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb 

在执行编译设备树的命令
	make dtbs

4> 拷贝和stm32mp157a-fsmp1a.dtb文件到~/tftpboot目录下

	cp arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb ~/tftpboot

​ 5> 启动开发板,linux内核可以启动成功,但是出现以下错误。

image-20221114155906748

5、解决hotplug的错误

1> 执行make menuconfig对内核源码进行配置

 Device Drivers  ---> 
	Generic Driver Options  ---> 
		 [*] Support for uevent helper     # 此选项配置为*
         (hotplug) path to uevent helper   # 回车进入输入界面,输入hotplug
         
 配置完成之后保存退出。

2> 编译linux内核源码

	make -j4 uImage LOADADDR=0xC2000000

3> 内核源码编译成功之后生成uImage镜像文件,拷贝文件到~/tftpboot目录下

	cp arch/arm/boot/uImage ~/tftpboot
	

4> 重启开发板进行测试,此时hotplug错误解决。

6、根据.config文件生成fsmp1a板子的默认配置文件

1. 根据.config文件拷贝生成fsmp1a板子的默认配置文件
	cp .config  arch/arm/configs/stm32mp15_fsmp1a_defconfig
	
2. 编写内核源码的使用的手册
	1> 拷贝linux内核源码压缩包到ubuntu中
	2> 对linux源码进行解压缩
	3> 进入linux内核源码目录下
	4> 配置交叉编译器
	5> 执行make distclean清除中间文件
	6> 执行make stm32mp15_fsmp1a_defconfig生成板子的配置文件.config
	7> 执行make menuconfig,对linux内核源码进行配置
	8> 编译linux内核源码生成uImage镜像文件:make -j4 uImage LOADADDR=0xc2000000
	9> 编译fsmp1a板子的设备树文件:make dtbs
	10> 拷贝uImage和stm32mp157a-fsmp1a.dtb文件到~/tftpboot目录下
	11> 使用开发板阶段开发启动方式或者产品阶段的启动方式,启动开发板。
		开发阶段开发板启动方式和产品阶段开发板启动方式具体的步骤,参考第二天的笔记

7、分析make <board_name>_defconfig执行过程详解


1. 打开linux内核源码目录下Makefile文件,搜索“%config”字符串,得到以下信息:
	%config: scripts_basic outputmakefile FORCE    
 	    $(Q)$(MAKE) $(build)=scripts/kconfig $@
	
	将$(Q),$(MAKE),$(build)变量的值使用echo命令打印:
	执行make stm32mp15_fsmp1a_defconfig,分析打印的结果,
	make -f ./scripts/Makefile.build obj=scripts/kconfig stm32mp15_fsmp1a_defconfig
	
	解析:
	make  : 执行的make命令
	-f ./scripts/Makefile.build  : -f后边的文件看出一个Makefile文件
	obj=scripts/kconfig  : 执行make命令时给obj变量赋值
	stm32mp15_fsmp1a_defconfig : make命令对应的目标
	
	最终实现的效果是:在scripts/kconfig目录下有一个Makefile文件,
	找Makefile文件中的目标为stm32mp15_fsmp1a_defconfig的规则下的命令执行。

2. 打开scripts/kconfig目录下Makefile文件,搜索“_defconfig”字符串,得到以下信息:
	%_defconfig: $(obj)/conf  
	    $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
	
	将命令前边的$(Q)去除,重新执行make stm32mp15_fsmp1a_defconfig,查看命令的结果:
	scripts/kconfig/conf  --defconfig=arch/../configs/stm32mp15_fsmp1a_defconfig Kconfig
	
	解析:
	scripts/kconfig/conf   -----> 使用file命令查看conf文件的属性可知
		conf文件是一个elf的可执行文件
	
	--defconfig=arch/arm/configs/stm32mp15_fsmp1a_defconfig  ---> 
				arch/arm/configs/目录下板子的默认的配置文件
				conf可执行程序的第一个参数
	Kconfig ----> linux内核源码目录下的Kconfig文件
				conf可执行程序的第二个参数
	
	conf程序解析arch/arm/configs/stm32mp15_fsmp1a_defconfig和
	linux内核源码目录下的Kconfig文件,
	最终在linux内核源码目录下生成.config文件。

3. 执行make <board_name>_defconfig命令会解析arch/arm/configs目录下的默认的配置文件,
	最终在linux内核源码目录下生成.config配置文件。
	.config文件给Makefile文件使用,Makefile文件根据.config文件中的配置信息,
	最终决定了linux内核源码哪些文件被编译,哪些文件不被编译。

8、分析make menuconfig执行过程详解

1. 打开linux内核源码目录下Makefile文件,搜索“%config”字符串,得到以下信息:
	%config: scripts_basic outputmakefile FORCE    
 	    $(Q)$(MAKE) $(build)=scripts/kconfig $@
	
	将$(Q)去除,重新执行make menuconfig命令,分析打印的结果,
	make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig
	
	解析:
	make  : 执行的make命令
	-f ./scripts/Makefile.build  : -f后边的文件看出一个Makefile文件
	obj=scripts/kconfig  : 执行make命令时给obj变量赋值
	menuconfig : make命令对应的目标
	
	最终实现的效果是:在scripts/kconfig目录下有一个Makefile文件,
	找Makefile文件中的目标为menuconfig的规则下的命令执行。
2. 打开scripts/kconfig目录下Makefile文件,搜索“menuconfig”字符串,得到以下信息:
	 menuconfig: $(obj)/mconf   
 	     $< $(silent) $(Kconfig)
	
	以上命令的解析的结果为:
	scripts/kconfig/mconf  Kconfig
	
	scripts/kconfig/mconf  ---> 使用file命令查看mconf程序可知,
				mconf是一个elf格式的可执行的程序。
	Kconfig ---> linux内核源码目录下的Kconfig文件,作为mconf程序的第一个参数
	
	最终的效果:mconf程序解析linux内核源码目录下的Kconfig文件,
	最终调用图形化界面的库(ncurses),生成基于菜单选项的图形化配置界面。

3. 打开linux内核源码目录下的Kconfig文件
	主菜单:主菜单可以包含子菜单和菜单选项,类似于windows窗口中菜单栏
	子菜单:可以包含子子菜单和菜单选项
	菜单选项:菜单选项为最后一级
	
	1> mainmenu关键字
		作用:修饰主菜单
		格式:mainmenu "主菜单的名字"
	
	2> menu关键字
		作用:修饰子菜单
		格式:
		menu "子菜单的名字"
		
		endmenu
	
	3> bool关键字
		作用:修饰菜单选项
		格式:
		bool "菜单选项的名字"
	
	4> default关键字
		作用:菜单选项的默认的状态
		格式:default y/n
	
	5> help关键字
		作用:菜单选项对应的帮助信息
		格斯:
			help
				帮助信息对应的描述字符串
	6> config关键字
		作用:修饰配置选项的
		格式:config  配置选项的名字
		注:配置选项的名字一般都大写,多个单词之间使用“_”分隔
		
		当config对应的菜单选项被配置为[*],配置选项对应的信息,
		"CONFIG_配置选项的名字=y"的信息被写到.config文件中。
		
		当config对应的菜单选项被配置为[],配置选项对应的信息,
		"# CONFIG_配置选项的名字 is not set"的信息被写到.config文件中。
		
		.config文件中定义的很多变量给Makefile文件使用,Makefile文件根据
		.config文件中变量的定义最终决定了那些.c文件被编译,哪些.c文件不被编译。
	
	7> source关键字
		作用:包含下一级目录下的Kconfig文件的
		格式:source "Kconfig文件及路径"

9、分析<boar_name>_defconfig,.config,Kconfig,Makefile文件的关系及作用。

9.1 4个文件的作用

<baord_name>_defconfig : 板子指定的默认的配置文件
.config : 板子配置文件,给Makefile使用
Kconfig : 生成基于菜单选项的图形化配置界面的文件
Makefile : 工程配置和管理编译的文件

9.2 4个文件之间的关系

image-20221114170305849

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

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

相关文章

优秀的PM如何轻松应对公司90%以上的沟通难题

项目经理和PMO工作中最多的事情往往是沟通&#xff0c;但是你在工作中会不会遇到很多沟通难题&#xff1f;如果其他环节的人处理不好还可以理解&#xff0c;但是咱们处理不好就说不过去了&#xff0c;并且还会让人感觉不专业&#xff0c;丧失很多机会&#xff0c;甚至失去领导的…

代码随想录Day49|121.买卖股票的最佳时期、122.买卖股票的最佳时期II

文章目录121.买卖股票的最佳时期、122.买卖股票的最佳时期II121.买卖股票的最佳时期、 文章讲解&#xff1a;代码随想录 (programmercarl.com) 题目链接&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给定一个数组 prices…

Metal每日分享,调整灰度系数gamma滤镜效果

本案例的目的是理解如何用Metal实现灰度系数效果滤镜&#xff0c;输入像素rgb进行次方运算获取到新的rgb&#xff1b; Demo HarbethDemo地址 实操代码 // 灰度系数滤镜 let filter C7Gamma.init(gamma: 3.0)// 方案1: ImageView.image try? BoxxIO(element: originImage,…

[附源码]Node.js计算机毕业设计儿童闲置物品交易网站Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

六、JavaScript——变量的内存结构

一、内存 定义&#xff1a;内存是用于存储数据的地方&#xff0c;程序要执行一段代码&#xff0c;要先从硬盘加载到内存当中&#xff0c;再由内存发送给CPU,CUP才能对代码进行执行。 注&#xff1a;变量并不存储任何值&#xff0c;而是存储值的内存地址 JS定义一个变量 <s…

Telerik模拟生成规则的新设置

Telerik模拟生成规则的新设置 添加了对Microsoft.NET 7官方版本的支持。 添加了控制模拟生成规则的设置。 Telerik JustLock是一个易于使用的模拟工具&#xff0c;它将帮助您以前所未有的速度、更高的质量编写单元测试。JustLock允许您轻松地将测试场景与难以配置的依赖关系(如…

5G现场网的数字孪生体系架构

现场网面向钢铁生产和统一管理的场景&#xff0c;实现现场设备与数据采集器和控制器的网络连接和数据互通&#xff0c;现场网的ZigBee、蓝牙等短距离技术以及窄带物联网&#xff08; narrowbandinternetofthings,NB-IoT&#xff09;、超远距离&#xff08;longrange,LoRa&#…

病历开发SDK:TX Text Control ActiveX 31.x Crack

Visual Basic 6 应用程序的文档处功能齐全的文档编辑器 TX Text Control ActiveX是一种完全可编程的 Rich Edit 控件&#xff0c;它在专为 Visual Studio 设计的可重用组件中为开发人员提供了广泛的文字处理功能。它提供全面的文本格式、强大的邮件合并功能和所有文字处理关键概…

算法训练四十八天 | LeetCode 198、213、337打家劫舍专题

LeetCode 198 打家劫舍 题目简析&#xff1a; 不能偷相邻的屋子&#xff0c;求能偷到的最大金额 思路分析&#xff1a; //由于是相邻的才偷&#xff0c;因此&#xff0c;我们对于最基础的三间 //dp[3] 应该是 Math.max(dp[2],dp[1]nums[3]) //如果第一间加偷第三间的价值大…

pytest + yaml 框架 -10.allure 生成报告

前言 本插件是基于pytest框架开发的&#xff0c;所以pytest 的插件都能使用&#xff0c;生成报告可以用到 allure 报告 pip 安装插件 pip install pytest-yaml-yoyoallure 报告功能在 v1.0.8 版本上实现 allure 命令行工具 allure 是一个命令行工具&#xff0c;需要去githu…

大话设计模式之设计原则

设计原则 参考链接&#xff1a;https://datawhalechina.github.io/sweetalk-design-pattern/#/content/design_principles/dependence_inversion_principle 主要介绍以下五个设计原则&#xff1a; 1、单一职责原则 顾名思义&#xff0c;一个类只有一个职责&#xff0c;只会…

React 16.8+生命周期(新)

React16之后有三个生命周期被废弃&#xff1a; componentWillMountcomponentWillReceivePropscomponentWillUpdate React 16.8的生命周期分为三个阶段&#xff0c;分别是挂载阶段、更新阶段、卸载阶段。 挂载阶段&#xff1a; constructor&#xff1a;构造函数&#xff0c;最…

【元胞自动机】基于元胞自动机模拟考虑心理策略的人员疏散附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

2022-12-13 工作记录--Vue/JS-音乐的播放与关闭

Vue/JS-音乐的播放与关闭 一、音频资源 音频资源的位置如下&#xff1a;&#x1f447;&#x1f3fb; 二、代码 App.vue 注意点&#xff1a; 1、若切换了音频资源&#xff0c;则需要在 播放音乐前 重新加载资源——见代码里的 myAuto?.load()&#xff1b;2、若切换了页面&…

论文学习——秦淮河水文水动力模型及实时校正

文章目录摘要0 引言1 模型构建1.1 流域概况及资料收集1.2 河道一维水流模拟1.3 边界条件处理1.3.1 流量上边界计算1.3.2 水文下边界处理1.4 节点堰闸流量计算2 实时校正方法2.1 KNN 法2.2 反馈法3 模拟及校正结果4 结论作者&#xff1a;孙文宇、姚成、刘志雨 期刊&#xff1a;《…

Allegro如何编辑过孔的封装参数操作指导

Allegro如何编辑过孔的封装参数操作指导 Allegro可以快捷的编辑过孔的封装,具体操作如下 以编辑这个via的封装为例 用Candence安装目录下面的pad_designer打开过孔的pad封装 打开后的效果如下图 如果需要改成钻孔8mil的孔,只需要在Drill diameter把10改成8即可 钻孔尺寸…

一比一手写迷你版vue,彻底搞懂vue运行机制

前言 现在前端面试Vue中都会问到响应式原理以及如何实现的&#xff0c;如果你还只是简单回答通过Object.defineProperty()来劫持属性可能已经不够了。 本篇文章通过学习文档及视频教程实现手写一个简易的Vue源码实现数据双向绑定&#xff0c;解析指令等。 几种实现双向绑定的…

好物安利:老照片修复软件哪个好?

大家都知道&#xff0c;老照片承载了很多的回忆&#xff0c;还有许多见证了城市的变迁及发展。甚至可以说&#xff0c;那些老照片&#xff0c;每一张都蕴藏着一个故事&#xff0c;能还原一段历史。但这些老照片&#xff0c;或多或少因为之前的设备、或储存不当等问题&#xff0…

【Docker】Docker安装Redis,并配置数据备份同步到宿主机

专栏精选文章 《Docker是什么&#xff1f;Docker从介绍到Linux安装图文详细教程》《30条Docker常用命令图文举例总结》《Docker如何构建自己的镜像&#xff1f;从镜像构建到推送远程镜像仓库图文教程》《Docker多个容器和宿主机之间如何进行数据同步和数据共享&#xff1f;容器…

Spring:Aop

目录 一、Aop简介 AOP相关术语 二、使用AOP 一、Aop简介 AOP(Aspect Oriented Programming)面向切面编程&#xff0c;一种编程范式&#xff0c;指导开发者如何组织程序结 构 原理&#xff1a;将复杂的需求分解出不同方面&#xff0c;将散布在系统中的公共功能集中解决 …