linux 内核编译

目录

Linux操作系统框架

Linux内核的主要功能:

Linux的内核目录结构:

结构图: 

详细介绍: 

uname - a 补充

编译之前

UTC 时间补充

Linux内核编译流程:

方法一:  官方内核编译:

1. 运行 build.sh 脚本, 记得加 sudo 权限

2. 选择 Kernel package, 然后回车 

3. 然后会提示是否需要显示内核配置界面

4. 接着选择开发板的型号 

编译完成

5. 查看编译生成的内核相关的 deb 包 --  生成在这个 output/debs/  路径下

解压  linux-image 的deb包得到如下目录:

​编辑

6. 重复编译 kernel

7. 如果对内核做了修改 可以使用下面的方法来更新开发板 linux 系统的内核和内核模块

编译之后


编译 linux 内核:

Linux操作系统框架

Linux内核的主要功能:

进程管理、内存管理、驱动、系统调用

Linux的内核目录结构:

结构图: 

详细介绍: 


a. arch/:这个目录包含了不同架构处理器的代码,如x86,arm,mips等。每个架构都有自己的子目录,如arch/x86/,arch/arm/等。在每个架构的子目录中,又有一些子目录和文件,如boot/,lib/,mm/,include/等,分别包含了特定平台的启动代码,库函数,内存管理,头文件


b. block/:这个目录包含了块设备的代码,如硬盘,光驱等。block/目录中主要包含了块设备的基本框架和I/O调度算法,以及一些通用的块设备驱动

c. crypto/:这个目录包含了加密算法的代码,如AES,SHA1,MD5等


d. drivers/:这个目录包含了设备驱动程序的代码,如键盘,鼠标,网卡,声卡,摄像头等。drivers/目录中的代码按照设备的类别进行分类,如char/,block/,input/,i2c/,spi/,pci/,usb/等

e. fs/:这个目录包含了文件系统的代码,如ext4,fat,ntfs,nfs,cifs等。fs/目录中的代码按照文件系统的类型进行分类,如ext4/,fat/,ntfs/等。在fs/目录中,还有一些通用的文件和子目录,如mount.h,dentry.c,proc/,sysfs/等,它们用于实现文件系统的基本功能和接口


f. include/:这个目录包含了内核所需的头文件,如linux/,asm/,uapi/等。头文件是用于声明变量,函数,结构,宏,常量等的文件,它们可以被其他的源文件引用,以便共享和重用代码。include/目录中的头文件按照不同的层次和用途进行分类,如linux/目录中的头文件是与平台无关的,asm/目录中的头文件是与平台相关的,uapi/目录中的头文件是用于内核和用户空间的API的


g. init/:这个目录包含了内核初始化的代码,如main.c,version.c,do_mounts.c等。init/目录中的代码是内核的入口和核心,它们负责调用其他子系统和模块的初始化函数


• ipc/:这个目录包含了进程间通信的代码,如sem.c,msg.c,shm.c等。进程间通信是指在不同的进程之间传递数据和信号的方法,它们可以让进程之间实现协作和同步。ipc/目录中的代码实现了一些常用的进程间通信机制,如信号量,消息队列,共享内存等


• kernel/:这个目录包含了内核的核心代码,如sched/,irq/,time/,fork.c,exit.c,signal.c等。kernel/目录中的代码实现了一些内核的基本功能和服务,如进程调度,中断处理,时间管理,进程创建,进程终止,信号处理等


• lib/:这个目录包含了内核需要引用的一些库函数的代码,如string.c,vsprintf.c,crc32.c等


• mm/:这个目录包含了内存管理的代码


• net/:这个目录包含了网络协议的代码,和网卡驱动不相关代码、


• scripts/:这个目录包含了内核编译所需的一些脚本,如Makefile,Kconfig,checkpatch.pl等
• tools/:这个目录包含了一些和内核交互的工具,如perf/,ftrace/,cpupower/,objtool/等。工具是用于分析和调试内核的程序,它们可以让内核的性能和稳定性更加优化和提高

---------------------------------------------------------------------

uname - a 补充


uname -a 是一个在 Linux 和 Unix 系统上常用的命令,用于显示当前系统的信息

具体来说,-a 选项(代表 "all")用于显示尽可能多的系统信息。

输出通常包含以下几个部分(但可能会因不同的系统和版本而异):

内核名称:例如 Linux
主机名:系统的主机名,这通常是你在 /etc/hostname 或使用 hostname 命令设置的名称。
内核版本号:当前运行的内核的版本。
内核发布日期:内核的发布或编译日期。
机器硬件名称:例如 x86_64 表示 64 位的 x86 架构。
处理器类型:例如 x86_64、i686 等。
操作系统:例如 GNU/Linux(但注意,这个信息并不总是显示)
例如,一个可能的输出是:

bash


Linux myhostname 5.4.0-7642-generic #38~1598903417~20.04~385a5d2-Ubuntu SMP PREEMPT Wed Sep 2 21:30:07 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux


在这个例子中:

内核名称是 Linux
主机名是 myhostname
内核版本是 5.4.0-7642-generic
内核发布日期(或编译日期)是 Wed Sep 2 21:30:07 UTC 2020
机器硬件名称和处理器类型都是 x86_64
操作系统是 GNU/Linux
这个命令在需要快速查看系统信息、诊断问题或编写与特定系统相关的脚本时非常有用。

编译之前

注意这里的时间是UTC 时间

后续我们会通过这个命令验证内核编译是否成功

------------------------------------------------------

UTC 时间补充


UTC  时间和北京时间相差 8h
UTC(协调世界时,Coordinated Universal Time)是一种全球标准的时间标准,用于协调世界各地的时间。以下是关于UTC时间的详细介绍:

定义:UTC是根据原子钟生成的时间,被认为是“最精确的时间”。它的时间间隔被称为“秒”,并且具有高度的精确性和稳定性,不受地理位置的影响。


历史:UTC的概念在1960年由国际无线电咨询委员会规范统一,并在次年投入实际使用。它的计时基准是国际原子时(TAI),并通过加入闰秒来与世界时(UT1)保持同步。


应用:UTC在科学、政府、商业、金融等领域被广泛应用,如GPS导航、航天和通信。许多计算机和通信系统都以其为基准进行时间同步,以确保全球各地的时间一致性和协调性。


与GMT的关系:在1972年之前,格林威治时间(GMT)一直是世界时间的标准。然而,由于GMT是基于地球自转速度的观测和计算,其精度受到自然现象(如潮汐和季节变化)的影响。而UTC则基于原子钟的时间测量,具有更高的精度和稳定性。


特点:UTC以24小时制表示时间,并使用时区来调整不同地区的时间差异。它的特点是具有高度的精确性和稳定性,能够确保全球各地的时间准确性和一致性。

DTS  设备树补充:

DTS(Device Tree Source)设备树是一种用于描述硬件设备和资源的数据结构,它在嵌入式系统开发中扮演着重要的角色。以下是关于DTS设备树的详细介绍:

基本概念:DTS设备树采用树形结构来描述硬件设备的层次关系,每个节点代表一个硬件设备或子系统。节点可以包含设备的名称、类型、地址、中断号等信息,还可以包含子节点来表示该设备所连接的其他设备。
作用:通过DTS设备树,操作系统可以在运行时动态地识别和配置硬件,而无需在代码中硬编码驱动程序。这大大简化了硬件驱动的编写和管理工作,提高了系统的可移植性和可扩展性。
文件格式:DTS文件通常使用文本格式编写,易于阅读和编辑。文件名通常以.dts为扩展名,而.dtsi文件则用于描述SOC级信息(如CPU数量、主频、外设控制器信息等),可以被多个DTS文件共享以提高可重用性。
工作流程:在嵌入式系统开发中,DTS文件首先被编译成DTB(Device Tree Blob)二进制文件。这个编译过程通常使用设备树编译器(DTC)来完成。然后,在boot loader运行时,DTB文件被传递给操作系统。操作系统通过解析DTB文件来获取系统中所有硬件设备的配置信息,并据此进行初始化和配置。
应用:DTS设备树在嵌入式系统中的应用非常广泛,尤其是在嵌入式Linux系统中。通过DTS设备树,Linux内核可以自动识别并配置各种硬件设备,如CPU、内存、网卡、串口等。此外,DTS还支持热插拔功能,即在系统运行时动态添加或删除硬件设备,这对于需要频繁更换硬件设备的场景非常有用。
优点:DTS设备树将硬件信息从内核代码中分离出来,使得硬件信息更加清晰、易于管理和维护。同时,它也提高了系统的可移植性和可扩展性,使得开发人员可以更加容易地将代码移植到不同的硬件平台上。
总之,DTS设备树是一种非常重要的数据结构,它简化了硬件驱动的编写和管理工作,提高了系统的可移植性和可扩展性。在嵌入式系统开发中,DTS设备树发挥着不可替代的作用。


dtbs 可能是指Device Tree Blob Source的缩写,用于描述或存储设备树源文件的集合。Device Tree Blob(DTB)是设备树描述(Device Tree Description)的二进制表示,它描述了硬件的结构和配置,特别是在嵌入式系统中。

=====================================

Linux内核编译流程:

方法一:  官方内核编译:

//参考自官方的编译方式,详见(《OrangePi_Zero2_H616用户手册v4.0》 6.4 编译Linux内核)

1. 运行 build.sh 脚本, 记得加 sudo 权限


sudo ./build.sh

2. 选择 Kernel package, 然后回车 

3. 然后会提示是否需要显示内核配置界面

 如果不需要修改内核配置, 则选择第一个即可

 如果需要修改内核配置, 则选择第二个 

4. 接着选择开发板的型号 

因为我们使用的板子是 orangepi02 ,so我们选 orangepizero2

然后就进行编译了,注意这里编译耗时很长,我耗时一个半小时,可能其他条件因素,耗时几小时也是可能得。

编译完成
<h2 id="mySection">编译之前</h2>


5. 查看编译生成的内核相关的 deb 包 --  生成在这个 output/debs/  路径下


a. linux-dtb-next-sun50iw9_3.1.0_arm64.deb 包含有内核使用的 dtb 文件
b. linux-headers-next-sun50iw9_3.1.0_arm64.deb 包含内核头文件
c. linux-image-next-sun50iw9_3.0.1_arm64.deb 包含内核镜像和内核模块

如下图

我们需要的是镜像文件

解压  linux-image 的deb包得到如下目录:

其中 ./boot/下的:

config -- 是配置文件
vmlinuz 是我们需要的内核文件


6. 重复编译 kernel

 使用下面的命令无需通过图形界面选择, 可以直接开始编译kernel

sudo ./build.sh BOARD=orangepizero2 BRANCH=next BUILD_OPT=kernel KERNEL_CONFIGURE=no

7. 如果对内核做了修改 可以使用下面的方法来更新开发板 linux 系统的内核和内核模块


# 这里的ip 和用户名根据自身的修改
scp linux-image-next-sun50iw9_3.1.0_arm64.deb orangepi@192.168.1.11:/home/orangepi/

# 查看之前安装的内核:
dpkg -l | grep linux-image

# 卸载之前安装的内核
sudo apt purge -y linux-image-next-sun50iw9 # 也有可能是linux-image-next-sun50iw9

# 安装我们scp 过来的新内核, -i -->  install
sudo dpkg -i linux-image-next-sun50iw9_3.1.0_arm64.deb

# reboot  -- 重启,我们的内核才生效

编译之后

// 和之前  编译之前 的对比,发现我们的日期时间 已经修改为了今天的UTC,说明我们已经编译成功了

如果对dpkg不够了解的朋友请看这一篇:

一文带你了解 dpkg-CSDN博客


报错小插曲:

dpkg -i  下载的时候出现问题:dpkg-deb: error: paste subprocess was killed by signal


解决:

sudo dpkg -i --force-overwrite linux-image-next-sun50iw9_3.1.0_arm64.deb 

sudo apt-get -f install


可以尝试的方法:


我们这样解决,一次执行下面命令:
sudo apt-get clean
sudo apt-get update
sudo apt-get upgrade

sudo apt-get clean 是一个在Debian和Ubuntu等基于Debian的Linux发行版中常用的命令,它用于清理本地存储的已下载的.deb软件包文件。这些.deb文件通常在你使用apt-get命令安装、升级或删除软件包时被下载到/var/cache/apt/archives/目录中。

具体来说,sudo apt-get clean命令的作用如下:

清理下载的包:它删除/var/cache/apt/archives/目录下所有已下载的.deb软件包文件。这些文件在你成功安装软件包后通常是不再需要的,但它们会占用磁盘空间。
节省磁盘空间:如果你的系统经常进行软件包的安装、升级或删除操作,那么/var/cache/apt/archives/目录可能会积累大量的.deb文件,从而占用大量的磁盘空间。sudo apt-get clean命令可以帮助你释放这些空间。
不影响已安装的软件包:这个命令只会删除已下载的.deb文件,而不会影响已经安装在你的系统上的软件包。因此,你不需要担心运行这个命令会导致已安装的软件包被删除或损坏。
需要注意的是,虽然sudo apt-get clean命令可以释放磁盘空间,但如果你希望更深入地管理你的软件包缓存,你还可以考虑使用sudo apt-get autoclean命令。这个命令会删除过时的.deb文件(即那些在新版本的软件包管理器中不再需要的文件),而不仅仅是所有已下载的.deb文件。这样可以在保持一些可能在未来需要的.deb文件的同时,进一步节省磁盘空间。

---------------------------


=====================================================


 

方法二:

上述官方编译kernel的方法可以用以下步骤代替:


1. 清理旧配置文件及生成的文件

sudo apt-get install ccache #安装ccahe,用于编译加速

export PATH=$PATH:/home/mxjun/orangepi-build/toolchains/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin #给root用户导入交叉编译环境,需要先切换到root用户

// 注意这里不能使用 whoami --> 我们需要切换到 root  用户操作 , 得到的用户名是root 


make ARCH=arm64 distclean


2. 配置内核, 更新内核依赖属性和新属性, 生成.config:


cp ../../external/config/kernel/linux-5.16-sun50iw9-current.config .config #拷贝默认配置
make ARCH=arm64 CROSS_COMPILE="aarch64-none-linux-gnu-" olddefconfig #这里执行make menuconfig 然后exit也是可以的

a. make olddefconfig 的作用是根据已有的 .config 文件生成一个新的 .config 文件,同时更新内核的依赖属性和新属性。它会使用旧的 .config 文件中的参数作为默认参数,不会询问用户的选择。它会将新添加的内核选项设置为默认值,也不会提醒用户。它会将旧的 .config 文件重命名为 .config.old 文件,以备后用.
b. make olddefconfig 的作用和 make oldconfig 类似,但是 make oldconfig 会以交互方式询问用户对
新配置的选择,而 make olddefconfig 不会
c. make menuconfig 是基于 Ncurses 图形界面去配置 .config 文件,它可以让用户在一个菜单式的界面
中选择和修改内核的各种选项,也可以查看选项的帮助信息,它是一种比较方便和直观的配置方式


3. 编译内核:

make -j6 ARCH=arm64 'CROSS_COMPILE=ccache aarch64-none-linux-gnu-' LOCALVERSION=-sun50iw9 Image modules dtbs

// 以ccache 高速缓存去加速交叉编译,    modules-->编译模块  dtbs -->编译设备树


4. 安装 内核 和 驱动:

make modules_install INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$PWD/_install ARCH=arm64 'CROSS_COMPILE=ccache aarch64-none-linux-gnu-' #安装驱动
make install INSTALL_PATH=$PWD/_install/boot #安装内核


//  参数: INSTALL_MOD_STRIP=1 --> 删除调试信息 or 链接调试符,节省编译空间,对orangepi不太明显,对×86 内核会明显

--------------------

或者直接打包成deb包:


cp external/patch/misc/headers-debian-byteshift.patch /tmp

make -j6 bindeb-pkg KDEB_PKGVERSION=3.1.0 KDEB_COMPRESS=xz BRANCH=next \
LOCALVERSION=-sun50iw9 KBUILD_DEBARCH=arm64 ARCH=arm64 DEBFULLNAME="Orange Pi" \
CROSS_COMPILE="ccache aarch64-none-linux-gnu-”


解读:

a.bindeb-pkg 是指定 make 命令使用 Debian 的格式来打包内核,生成一个 .deb 文件,这样可以方便
地在 Debian 系的系统中安装内核 。
b. KDEB_PKGVERSION=3.1.0 是指定打包的内核的版本号为 3.1.0,这个版本号可以自定义,也可以使用
内核的默认版本号 。
c. KDEB_COMPRESS=xz 是指定打包的内核使用 xz 的压缩格式,这样可以减少打包文件的大小,也可以
使用其他的压缩格式,如 gzip, bzip2 等 。
d. BRANCH=next 是指定编译的内核的分支为 next
c. LOCALVERSION=-sun50iw9 是指定编译的内核的本地版本为 -sun50iw9
d. KBUILD_DEBARCH=arm64 是指定打包的内核的架构为 arm64,这个架构是用来表示 64 位的 ARM
处理器。
e. ARCH=arm64 是指定编译的内核的架构为 arm64 。
f. DEBFULLNAME=Orange Pi 是指定打包的姓名为 Orange Pi。


======================================================

 Linux根文件系统

根文件系统也叫roofs,Linux 根文件系统是指整个文件系统的最顶层,以 "/" 来表示。它是内核启动时所挂载的第一个文件系统,包含了系统运行所必需的目录和文件:


1. /bin目录下存放着系统需要的可执行文件比如ls、mv、cp等命令,现在新根文件系统的像ubuntu等
debian系的rootfs, 基本都是软链接到/usr/bin目录下
2. /dev目录下面存放着的文件都与设备有关,此目录下的文件都是设备文件。
3. /etc目录存放Linux下所必须的库文件
4. /mnt目录, 临时挂载目录,可以在从目录下创建空的子目录
5. /proc、sys 目录, Linux虚拟文件系统,由内核生成各类节点
6. /sbin 一般软链到/usr/sbin下,一般存放一些root权限才能执行的命令
7. /lib 软链接到/usr/lib目录,用于存放库文件
8. /usr/ 存放lib bin sbin目录, 另外的share目录里面存放的是共享、只读的程序和数据
9. /tmp/存放临时文件或目录
10. /root目录 系统管理员(root)的主文件夹,即是根用户的目录,与此对应,普通用户的目录
是/home下的某个子目录。
11. /var目录、与/usr目录相反,/var目录中存放可变的数据,比如log文件\临时文件等。
12. /home目录,系统默认的用户文件夹,它是可选的,对于每个普通用户,在/home目录下都有一个以用户名命名的子目录,里面存放用户相关的配置文件。
根文件系统的编译详见(《OrangePi_Zero2_H616用户手册v4.0》 6.5. 编译 rootfs )


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day 24 数据库管理及数据类型

数据库管理及数据类型 一&#xff1a;数据类型 1.数值类型 整数类型 ​ 整数类型&#xff1a;TINYINT SMALLINT MEDIUMINT INT BIGINT ​ 作用&#xff1a;用于存储用户的年龄、游戏的Level、经验值等 浮点数类型 ​ 浮点数类型&#xff1a;FLOAT DOUBLE ​ 作用&#xf…

linux或ubuntu环境下需要自行安装vivado USB Program下载程序驱动

如果在linux或ubuntu环境下&#xff0c;不安装驱动是无法下载FPGA程序的。在linux或ubuntu环境下安装程序不要自动安装。 johnjohn-wang:~/vitis2021.2/Vivado/2021.2/data/xicom/cable_drivers/lin64/install_script/install_drivers$ sudo ./install_drivers

1天搞定SpringBoot+Vue全栈开发 (7)Axios网络请求

1.Axios的使用 Axios中文文档 | Axios中文网Axios 是一个基于 promise 的网络请求库&#xff0c;可以用于浏览器和 node.jshttps://www.axios-http.cn/ 2.与vue整合 App.vue: <template><div id"app"><Moviev-for"movie in movies":key&qu…

一致性评价政策加速行业仿制药洗牌,惯爱为代表的新锐品牌崭露头角

从印度神油到以形补形&#xff0c;男人的问题&#xff0c;从古至今一直困扰着很多人&#xff0c;大多人都羞于启齿。然而&#xff0c;沉默的背后&#xff0c;隐藏着令人震惊的数据&#xff1a;据统计显示&#xff0c;ED&#xff08;勃起功能障碍&#xff09;是男性生殖系统发病…

9.Java内置锁的核心原理-Synchronized

文章目录 Java内置锁的核心原理-Synchronized1.线程安全问题1.1.自增运算分析1.2.临界区资源和临界区代码片段 2.synchronized关键字2.1.synchronized同步方法2.2.synchronized同步代码块2.3.synchronized同步方法和synchronized同步代码块区别2.4.静态的同步方法2.5.内置锁的释…

18、ESP32 ESP-NOW 点对点通信

ESP-NOW 是乐鑫自主研发的无连接通信协议&#xff0c;具有短数据包传输功能。该协议使多个设备能够以简单的方式相互通信。 ESP-NOW 功能 ESP-NOW 支持以下功能&#xff1a; 加密和未加密的单播通信;混合加密和未加密的对等设备;最多可携带 250 字节 的有效载荷;发送回调功能…

C#修改默认参数settings文件

右击项目在设置中进行修改&#xff1a; 千万不要在这里改。 如果要在自己的项目里添加这个文件&#xff0c;首先新建个文件夹&#xff0c;然后添加.setting文件&#xff0c;然后再像上面说的那样添加属性。

通过 Java 操作 redis -- String 基本命令

关于 redis String 类型的相关命令推荐看 Redis - String 字符串 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Java 操作 redis -- 连接 redis 本博客只介绍了一小部分常用的命令&#xff0c;其他的命令根据上面推荐的博客也能很简单…

Penpad再获 Presto Labs 投资,Scroll 生态持续扩张

​Penpad 是 Scroll 生态的 LaunchPad 平台&#xff0c;其整计划像收益聚合器以及 RWA 等功能于一体的综合性 Web3 平台拓展&#xff0c;该平台在近期频获资本市场关注&#xff0c;并获得了多个知名投资者/投资机构的支持。 截止到本文发布前&#xff0c;Penpad 已经获得了包括…

【免费】虚拟同步发电机(VSG)惯量阻尼自适应控制仿真模型【simulink】

目录 主要内容 仿真模型要点 2.1 整体仿真模型 2.2 电压电流双闭环模块 2.3 SVPWM调制策略 2.4 无功电压模块 2.5 自适应控制策略及算法 部分结果 下载链接 主要内容 该模型为simulink仿真模型&#xff0c;主要实现的内容如下&#xff1a; 随着风力发电、光…

4.请求体

什么是请求体(Request Body) 请求体是客户端发送到API的数据。 响应体是API发送给客户端的数据 API几乎总是必须发送一个响应体&#xff0c;但是客户端并不需要一直发送请求体 定义请求体&#xff0c;需要使用 Pydantic 模型 不能通过GET请求发送请求体发送请求体数据&…

ISIS的工作原理

1.邻居关系建立 &#xff08;1&#xff09;IS-IS领接关系建立原则 1、通过将以太网接口模拟成点到点接口&#xff0c;可以建立点到点链路邻接关系。 2、当链路两端IS-IS接口的地址不在同一网段时&#xff0c;如果配置接口对接收的Hello报文不作IP地址检查&#xff0c;也可以建…

基于Springboot的教学辅助系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的教学辅助系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

FreeBSD安装Miniconda,python启动core dumped的问题

综述&#xff1a; 学会在FreeBSD安装Miniconda后&#xff0c;在一台服务器上安装却碰到问题&#xff0c;安装好后&#xff0c;执行python报错&#xff1a;Segmentation fault (core dumped) 。 以前成功的是在FreeBSD13版本&#xff0c;报错的这个是FreeBSD14版本&#xff0c…

基于FPGA的多路彩灯控制器VHDL代码Quartus仿真

名称&#xff1a;基于FPGA的多路彩灯控制器VHDL代码Quartus仿真&#xff08;文末获取&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 多路彩灯控制器 综合训练内容要求 设计一台基于FPGA的多路彩灯控制器的设计。要求如下 1.彩灯从左…

SpringBoot中HandlerInterceptor拦截器的构建详细教程

作用范围&#xff1a;拦截器主要作用于Spring MVC的DispatcherServlet处理流程中&#xff0c;针对进入Controller层的请求进行拦截处理。它基于Java的反射机制&#xff0c;通过AOP&#xff08;面向切面编程&#xff09;的思想实现&#xff0c;因此它能够访问Spring容器中的Bean…

C语言栈的含义与栈数据操作代码详解!

引言&#xff1a;在本篇博客中&#xff0c;我们将学到数据结构——栈&#xff0c;讲到栈的含义与关于栈的数据操作代码。栈可以在顺序表、双向链表以及单链表的基础上实现&#xff0c;而于本篇博客中&#xff0c;我们选择在顺序表的基础上实现栈。 更多有关C语言和数据结构知识…

2024 AI中转计费平台系统源码

简介&#xff1a; 2024 AI中转计费平台系统源码 文件下载https://www.skpan.cn/CNZjzyC4txX 图片&#xff1a;

vue-img-cutter 图片裁剪详解

前言&#xff1a;vue-img-cutter 文档&#xff0c;本文档主要讲解插件在 vue3 中使用。 一&#xff1a;安装依赖 npm install vue-img-cutter # or yarn add vue-img-cutter # or pnpm add vue-img-cutter 二&#xff1a;构建 components/ImgCutter.vue 组件 <script se…

什么是多模态大模型,有了大模型,为什么还要多模态大模型?

随着人工智能技术的愈演愈烈&#xff0c;其技术可以说是日新月异&#xff0c;每隔一段时间就会有新的技术和理念被创造出来&#xff1b;而多模态大模型也是其中之一。 什么是多模态 想弄明白什么是多模态大模型&#xff0c;那么首先就要弄明白什么是多模态。 简单来说&#x…
最新文章