Linux内核的源码目录结构和配置体系

news2024/10/6 2:34:24

1.linux内核源码目录结构1

1.1、源码从哪里来

(1)我们使用2.6.35.7版本的内核。这个版本的内核有三种:第一种是kernel.org上的官方版本,第二种是三星移植过的,第三种是九鼎X210的移植版本。这里使用第三个。

(2)进入源码目录下,make distclean清理然后再次打包传输到windows下去解压分析;

(3)解压后最终在windows下得到了一个kernel的源码目录树,这个源码目录就是九鼎以三星移植过的内核为原材料自己针对X210移植后的内核版本。

1.2、分析源码目录下的单个文件

.gitignore 用来管理linux内核版本的一种版本管理工具

.mailmap 记录维护这个linux内核的人的名字和邮箱

COPYING 版权

COPYING.txt 版权

CREDITS 鸣谢

initrd.img.cpio 和设备树传参有关

Kbuild,Kbuild是kernel build的意思,就是内核编译的意思。这个文件就是linux内核特有的内核编译体系需要用到的文件。

MAINTAINERS 内核维护者的一些记录

Makefile,这个是linux内核的总makefile,整个内核工程用这个Makefile来管理的。

mk,是九鼎在移植时自己添加的脚本,不是linux内核本身的东西。九鼎添加这个文件的作用是用这个文件来整体管理kernel目录的配置和编译。

README 内核说明书

REPORTING-BUGS 用来上报bug的

1.3、简单讲一下linux内核的配置体系。

(1)linux内核很庞大,里面模块很多,而且可配置性非常高。所以linux源代码的配置是一个很复杂的事情,必须要有一套很复杂的机制来保证linux内核可以被正确的配置。(对比一下uboot,uboot的配置项都是在xxx.h中,用宏定义来表示的。uboot的这种方式很依赖于人的水平,因为uboot的配置体系很简单。)

(2)linux内核本身配置项有上千个,光靠人眼睛去看脑袋去记根本不可能,所以内核发明了一种体系用来帮助人进行简单化的配置。这种体系就是我们本课程中重点要研究的东西。

(3)Kbuild、Kconfig等文件,都是和内核的配置体系有关的。

2.linux内核源码目录结构2

(1)arch。arch是architecture的缩写,意思是架构。arch目录下是好多个不同架构的CPU的子目录,譬如arm这种cpu的所有文件都在arch/arm目录下,X86的CPU的所有文件都在arch/x86目录下。

(2)block。英文是块的意思,在linux中block表示块设备(以块(多个字节组成的整体,类似于扇区)为单位来整体访问),譬如说SD卡、iNand、Nand、硬盘等都是块设备。你几乎可以认为块设备就是存储设备。block目录下放的是一些关于块设备管理的代码。

(3)crypto。英文意思是加密。这个目录下放了一些各种常见的加密算法的C语言代码实现。譬如crc32、md5、sha1等。

(4)Documentation。里面放了一些文档。

(5)drivers。驱动目录,里面分门别类的列出了linux内核支持的所有硬件设备的驱动源代码。

(6)firmware。固件。什么是固件?固件其实是软件,不过这个软件是固化到IC里面运行的叫固件。就像S5PV210里的iROM代码。

(7)fs。fs就是file system,文件系统,里面列出了linux支持的各种文件系统的实现。

(8)include。头文件目录,公共的(各种CPU架构共用的)头文件都在这里。每种CPU架构特有的一些头文件在arch/arm/include目录及其子目录下。

(9)init。init是初始化的意思,这个目录下的代码就是linux内核启动时初始化内核的代码。

(10)ipc。ipc就是inter process commuication,进程间通信,里面都是linux支持的IPC的代码实现。

(11)kernel。kernel就是内核,就是linux内核,所以这个文件夹下放的就是内核本身需要的一些代码文件。

(12)lib。lib是库的意思,这里面都是一些公用的有用的库函数,注意这里的库函数和C语言的库函数不一样的。在内核编程中是不能用C语言标准库函数,这里的lib目录下的库函数就是用来替代那些标准库函数的。譬如在内核中要把字符串转成数字用atoi,但是内核编程中只能用lib目录下的atoi函数,不能用标准C语言库中的atoi。譬如在内核中要打印信息时不能用printf,而要用printk,这个printk就是我们这个lib目录下的。

(13)mm。mm是memory management,内存管理,linux的内存管理代码都在这里。

(14)net。该目录下是网络相关的代码,譬如TCP/IP协议栈等都在这里。

(15)scripts。脚本,这个目录下全部是脚本文件,这些脚本文件不是linux内核工作时使用的,而是用来辅助对linux内核进行配置编译生产的。我们并不会详细进入分析这个目录下的脚本,而是通过外围来重点学会配置和编译linux内核即可。

(16)security。安全相关的代码。不用去管。

(17)sound。音频处理相关的。

(18)tools。linux中用到的一些有用工具

(19)usr。目录下是initramfs相关的,和linux内核的启动有关,暂时不用去管。

(20)virt。内核虚拟机相关的,暂时不用管。

总结:这么多目录跟我们关系很紧密的就是arch和drivers目录,然后其他有点相关的还有include、block、mm、net、lib等目录。

3.内核配置和编译体验

3.1、先确认Makefile

(1)主要是检查交叉编译工具链有没有设置对。CROSS_COMPILE ?= /usr/local/arm/arm-2009q3/bin/arm-none-linux-gnueabi-

(2)确认ARCH = arm。主要目的是为了编译时能找到arch/arm目录。

3.2、make x210ii_qt_defconfig

(1)最后只要出现:configuration written to .config这句话,就证明我们的操作是正确的。如果没有出现这句话,就有错误。

(1)可能出现的错误1:名字敲错了。名字是字符串匹配的,一定要正确。

注意:如果这一步配置没有得到.config文件,是不能进行到下一步的。实际测试时没有.config也可以make menuconfig,但是这样做出来的内核编译和烧写运行应该是有问题的。

3.3、make menuconfig

(1)可能出现的错误1:ncurses库没装

错误信息:

*** Unable to find the ncurses libraries or the

*** required header files.

*** 'make menuconfig' requires the ncurses libraries.


*** Install ncurses (ncurses-devel) and try again.

解决方案: apt-get install libncurses5-dev (参考了:Ubuntu 12.04 下安装ncurses-devel_Yao_Qinwei的博客-CSDN博客)

(2)可能出现的错误2:屏幕太小

错误信息:

Your display is too small to run Menuconfig!

It must be at least 19 lines by 80 columns.

解决方案:全屏,或者是把字体调小。

总结:我们这里使用的内核因为是九鼎已经移植过的,所以第二步配置是可以不做的,直接退出即可。

用键盘的向右方向键移动到EXIT,按回车退出。

3.4、make

(1)可能出现的错误1:莫名其妙的错误,可以试试先make distclean

(2)代码本身的错误:具体问题具体分析

(3)编译完成后得到的内核镜像不在源码树的根目录下,在arch/arm/boot这个目录下。得到的镜像名是zImage

4.内核的配置原理1

4.1、烧写测试

4.2、配置的关键是得到.config文件

(1).config以.开头,是一个隐藏文件,因此平时是看不到的,需要ls -a来看

(2)当我们make distclean后(也就是说默认情况下)是没有.config文件的,我们配置的两步过程就是为了得到内容合适的.config文件

(3).config文件是linux内核在编译过程中很重要的一个文件,其作用类似于uboot中的include/configs/x210_sd.h。linux内核在编译过程中就是读取.config文件中的配置项,并且用这些配置项去指导整个编译链接过程。

(4).config文件的格式类似于脚本文件,其中内容为类似于于:CONFIG_ARM=y的一个一个的配置项。这些配置项就类似于脚本文件中定义的一个一个变量,所以这一行可以被理解为定义了一个变量CONFIG_ARM,这个变量的值为y。

(5).config文件中每一行都是一个配置项,从.config文件的规模可以看出linux内核的可配置项有两三千个。所以linux内核是高度可配置的,而且linux内核的所有配置项很难全部搞明白。因为linux内核的配置项太多太繁杂超出了人的大脑能够记忆和处理的数量级,因此linux内核不像uboot那样直接手工配置,而是发明了一个图形化的配置工具menuconfig。

4.3、make xx_defconfig和make menuconfig相配合

(1)我们为了对.config文件中的两三千个配置项做逐一合适的配置,专门发明了两步结合的配置方式。

(2)其实只要人的记忆足够好,大脑足够厉害,完全可以手工去书写/修改.config文件完成内核配置,最终只要.config中内容是正确的,就不影响编译过程。

(3)第一步:make xxx_defconfig解决的问题是大部分的配置项(这一步结束后99%的配置项就已经正确了),下来就是对个别不同的针对我们的开发板进行细节调整,细节调整就通过make menuconfig来完成。

(4)make xxx_defconfig这一步其实是参考别人已经做好的,这样做有很多好处:减少很多工作量,避开了很多自己不懂的配置项(譬如对内存管理的、调度系统的等模块的配置项),我们只用管自己需要管的。

(5)make menuconfig其实就是读取第一步得到的.config,然后给我们一个图形化的界面,让我们可以更加容易的找到自己想要修改的配置项,然后更改配置他。

4.4、make xx_defconfig到底做了什么?

(1)make x210ii_qt_defconfig其实相当于:cp arch/arm/configs/x210ii_qt_defconfig .config

检验方法:终端输入make x210_qt_defconfig,故意输错,会打印这个报错信息

(2)arch/arm/configs目录2下的这么多个xxx_defconfig哪里来的?其实这些文件都是别人手工配置好适合一定的开发板的.config文件后自己把.config文件保存过去的。譬如说我们用S5PV210这个SoC,针对这个SoC的开发板的最初配置肯定是三星的工程师去做的。

5.menuconfig的使用和演示

5.1、使用说明解释

(1)make ,menuconfig中本身自带的提示就有所有的用法,这里只要全部理解就可以了。

(2)menuconfig中间的选择区中有很多个选择项,每个选择项对应.config文件中的一个配置项,每一个选择项都可以被选择和配置操作,选择区中的每一项都是有子目录的,将光标放在选择项上按Enter键可以进入子目录(子目录可能还会有子目录)。选择区太短放不下所有的一个目录层级的选项,可以用箭头按键的向上箭头和向下箭头来上翻和下翻。

注:在menuconfig中操作相关的几个键盘按键,主要是;Enter、ESC、四个方向箭头按键。还有一些特殊字符按键,如/ ?

向上和向下箭头,主要用来在选择项菜单中目录浏览时上下翻

回车,主要作用是选中并且执行select/exit/help。

ESC,主要作用是返回上一层

向左和向右箭头,主要作用是在菜单选项(select、exit、help)间切换。

(3)用法翻译:

箭头按键导航整个菜单,回车按键选择子菜单(注意选项后面有 --->的选项才是有子菜单的,没有这个标识的没有子菜单),高亮的字母是热键(快捷键),键盘按键Y、N、M三个按键的作用分别是将选中模块编入、去除、模块化。双击ESC表示退出,按下?按键可以显示帮助信息,按下/按键可以输入搜索内容来全局搜索信息(类似于vi中的搜索),[]不可以模块化,<>的才可以模块化。

注:linux内核中一个功能模块有三种编译方法:一种是编入、一种去去除、一种是模块化。所谓编入就是将这个模块的代码直接编译连接到zImage中去,去除就是将这个模块不编译链接到zImage中,模块化是将这个模块仍然编译,但是不会将其链接到zImage中,会将这个模块单独链接成一个内核模块.ko文件,将来linux系统内核启动起来后可以动态的加载或卸载这个模块。

在menuconfig中选项前面的括号里,*表示编入,空白表示去除,M表示模块化

6.menuconfig的工作原理

6.1、menuconfig本身由一套软件支持

(1)linux为了实现图形化界面的配置,专门提供了一套配置工具menuconfig。

(2)ncurses库是linux中用来实现文字式的图形界面,linux内核中使用了ncurses库来提供menuconfig功能

(3)scripts\kconfig\lxdialog目录下的一些c文件就是用来提供menuconfig的那些程序源代码。

6.2、menuconfig读取Kconfig文件

(1)menuconfig本身的软件只负责提供menuconfig工作的这一套图形操作界面(譬如在menuconfig中通过上下左右箭头按键来调整光标,Enter ESC键等按键按下的响应),而并不负责提供内容(菜单里的项目)。

(2)menuconfig显示的菜单内容(一方面是菜单的目录结构,另一方面是每一个菜单项目的细节)是由内核源码树各个目录下的Kconfig文件来支持的。Kconfig文件中按照一定的格式包含了一个又一个的配置项,每一个配置项在make menuconfig中都会成为一个菜单项目。而且menuconfig中显示的菜单目录结构和源码目录中的Kconfig的目录结构是一样的。

(3)在相应的Kconfig文件中删除一个config项,则再次make menuconfig时这个项目已经看不到了。

6.3、menuconfig读取/写入.config文件

(1)刚才已经知道menuconfig的菜单内容来自于Kconfig文件,但是每一个菜单的选择结果(Y、N、M)却不是保存在Kconfig文件中的。Kconfig文件是不变的,Kconfig文件只是决定有没有这个菜单项,并不管这个菜单项是否被选中。

(2)menuconfig工作时在我们make menuconfig打开时,他会读取.config文件,并且用.config文件中的配置选择结果来初始化menuconfig中各个菜单项的选择值。

总结:菜单项的项目内容从Kconfig文件来,菜单项的选择值从.config文件来

(3)当我们每次退出make menuconfig时,menuconfig机制会首先检查我们有没有更改某些配置项的值,如果我们本次没有更改过任意一个配置项目的值那直接退出;如果我们有改动配置项的值则会提示我们是否保存。此时如果点保存,则会将我们更改过的配置重新写入.config文件中记录,下一次再次打开make menuconfig时会再次加载.config,最终去编译内核时编译连接程序会考虑.config中的配置值指导整个编译连接过程。

总结:理解menuconfig和Kconfig和.config的关系。

检验:

第一步:查看.config中DM9000网卡相关的变量的值

第二步:make menuconfig进入图形界面修改

第三步:再次查看.config中DM9000网卡相关的变量

7.Kconfig文件详解1

7.1、Kconfig的格式

(1)Kconfig按照一定的格式来书写,menuconfig程序可以识别这种格式,然后从中提取出有效信息组成menuconfig中的菜单项。

(2)将来在做驱动移植等工作时,有时需要自己添加Kconfig中的一个配置项来将某个设备驱动添加到内核的配置项目中,这时候就需要对Kconfig的配置项格式有所了解,否则就不会添加。

(3)#开头的行是注释行

(4)menuconfig表示菜单(本身属于一个菜单中的项目,但是他又有子菜单项目)、config表示菜单中的一个配置项。

(5)menuconfig或者config后面空格隔开的大写字母表示的类似于 NETDEVICES 的就是这个配置项的配置项名字,这个字符串前面添加CONFIG_后就构成了.config中的配置项名字。

(6)一个menuconfig后面跟着的所有config项就是这个menuconfig的子菜单。这就是Kconfig中表示的目录关系。

(7)内核源码目录树中每一个Kconfig都会source引入其所有子目录下的Kconfig,从而保证了所有的Kconfig项目都被包含进menuconfig中。这个也告诉我们:如果你自己在linux内核中添加了一个文件夹,一定要在这个文件夹下创建一个Kconfig文件,然后在这个文件夹的上一层目录的Kconfig中source引入这个文件夹下的Kconfig文件。

7.2、tristate和bool的含义

(1)tristate意思是三态(3种状态,对应Y、N、M三种选择方式),bool是要么真要么假(对应Y和N)。所以tristate的意思就是这个配置项可以有三种选择,bool的意思是这个配置项只能有2种选择。凡是tristate的都是<>,凡是bool的都是[]

8.Kconfig文件详解2

8.1、depends的含义

(1)depends中文意思是“取决于”或者“依赖于”,所以depends在这里的意思是:本配置项依赖于另一个配置项。如果那个依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的哪个配置项本身被设置为N,则本配置项根本没有意义。

(2)depends项目会导致make menuconfig的时候找不到一些配置项。所以你在menuconfig中如果找不到一个选项,但是这个选项在Kconfig中却是有的,则可能的原因就是这个配置项依赖的一个配置项是不成立的。

(3)depends并不要求依赖的配置项一定是一个,可以是多个,而且还可以有逻辑运算。这种时候只要依赖项目运算式子的逻辑结果为真则依赖就成立。

8.2、help

(1)帮助信息,告诉我们这个配置项的含义,以及如何去配置他。

8.3、Kconfig和.config文件和Makefile三者的关联

(1)menuconfig中的配置项被配置成Y、N、M会影响.config文件中的CONFIG_XXX变量的配置值。

(2)这个.config中的配置值(=y、=m、没有)会影响最终的编译链接过程。如果=y则会被编入(built-in)zImage中,如果=m会被单独连接成一个ko模块,如果没有则对应的代码不会被编译。那么这么是怎么实现的?都是通过makefile实现的。

(3)obj-$(CONFIG_DM9000) += dm9000.o

如果CONFIG_DM9000变量值为y,则obj += dm9000.o,因此dm9000.c会被编译;

如果CONFIG_DM9000变量未定义,则dm9000.c不会被编译。

如果CONFIG_DM9000变量的值为m则会被连接成ko模块(这个是在linux内核的Makefile中定义的规则)

总结:把menuconfig中的菜单项、Kconfig中的配置项、.config中的一行、 Makefile中的一行,这4个东西结合起来理解,则整个linux内核的配置体系就明了了。

9.menuconfig的实验学习思路

9.1、验证menuconfig和.config的关系

(1)make menuconfig时,会读取.config中的配置值来初始化menuconfig中的配置项。

验证:如果理论正确的,那么我自己手工修改了.config的配置后,再次make menuconfig时看到的初始值就应该是我手工修改的。

(2)menuconfig中修改了(按Y、N、M)配置项的值,然后退出时保存,则这个保存结果会修改.config文件中的相应行。

验证:如果结论是正确的,那么在menucofig中修改了配置后保存退出,再次去手工打开.config文件则可以看到相应配置的一行内容被修改了。

9.2、验证menuconfig和Kconfig的关系

(1)menuconfig读取Kconfig的内容作为菜单项目内容。

验证1:在Kconfig中删除一个config项,则再次make menuconfig时就看不到这个项目了。(上课时已经验证过了)

验证2:在Kconfig中自己添加创建一个config项,则再次make menuconfig时就能看到多了一个项目。

9.3、验证menuconfig和Makefile的关系

(1)我找一个模块,把他配制成y,然后去make编译连接,最后得到的zImage中这个模块就应该被编译连接进去到zImage中了。

验证:

方法一:去这个模块对应的源代码目录看一下这个源码有没有被编译

方法二:去zImage对应的elf格式的vmlinux中查看符号

方法三:将vmlinux反编译(objdump)后得到的文件中找模块对应的符号

方法四:将zImage下载到开发板中启动,启动后看你的模块能不能工作

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

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

相关文章

《QT+PCL》点云配准进阶——GROR配准

《QT+PCL》点云配准进阶——GROR配准 一、展示效果二、ui设计三、代码3.1添加代码一、展示效果 根据之前的文章GROR复现,今天将其集成到QT软件中 二、ui设计 三、代码 3.1添加代码 qt的头文件、源文件依旧添加相关代码 其中,如果有函数冲突,改成内联函数,添加inline<…

【系统移植】开发板的启动过程

目录 1、开发板启动相关部件 2、开发板启动过程&#xff08;以 EMMC 启动为例&#xff09; (1) 运行 BL0&#xff08;初始化&#xff09; (2) 加载 uboot 引导程序 (3) 加载 linux 镜像、设备树、根文件系统 3、SD卡的存储结构 1、开发板启动相关部件 下面是一个简单的开…

非常有用的Linux网络诊断命令:traceroute

简介 traceroute 是一个网络诊断工具&#xff0c;用于检测数据包从本机到目标主机经过的路由路径。它可以帮助我们分析出网络连接的瓶颈&#xff0c;定位网络问题&#xff0c;并帮助我们优化网络连接。在 Linux 系统中&#xff0c;traceroute 命令是一个非常常用的工具。 安装…

java语法(二)线程并发、Juit单元测试、注解、反射机制、JVM

文章目录 线程并发多线程多线程的创建Thread常用API 线程同步与通信线程同步&#xff1a;单例模式的三种写法同步代码块同步方法Lock锁 线程通信 线程池获取线程池对象ThreadPoolExecutor线程池处理runnable任务线程池处理callable任务 Executors定时器Timer调度可重复执行任务…

【连续介质力学】张量的谱表示和Cayley-Hamilton定理

张量的谱表示 基于特征多项式&#xff1a; 如果 T T T 是对称二阶张量&#xff0c;那么有三个实数特征值&#xff1a; T 1 , T 2 , T 3 T_1, T_2, T_3 T1​,T2​,T3​, 对应有特征向量&#xff1a; 主空间由特征向量构成的正交基 n ^ ( 1 ) , n ^ ( 2 ) , n ^ ( 3 ) \hat n^…

【自然语言处理】【大模型】BLOOM模型结构源码解析(单机版)

BLOOM模型结构源码解析(单机版) ​ 本文基于transformers中BLOOM模型代码来解析BLOOM的原理及实现。 相关博客 【自然语言处理】【大模型】BLOOM模型结构源码解析(单机版) 【自然语言处理】【大模型】极低资源微调大模型方法LoRA以及BLOOM-LORA实现代码 【深度学习】【分布式训…

Win32程序入口识别,定位回调函数,具体事件处理的定位,ESP寻址方式,压栈方式复习

本专栏上一篇文章带领大家编写了第一个Windows程序&#xff0c;并且带领大家了解了Windows消息机制&#xff0c;如果大家还是不了解的话&#xff0c;可以到我的另一篇专栏中深入学习一下windows消息&#xff0c;Windows消息循环的原理&#xff0c;点击这里就可以查看啦。 我们在…

Gateway网关详解及实践---SpringCloud组件(五)

Gateway网关详解及实践 一 简介1.1介绍1.2.GateWay核⼼概念1.3.GateWay核心功能 二Gateway入门案例2.1 gateway依赖2.2 gateway配置2.3 gateway测试 三Gateway面向服务的路由3.1.门案例问题3.2.gateway-server结合eureka步骤3.2.1.添加Eureka客户端依赖3.2.2.添加Eureka配置3.2…

MySQL进阶-MySQL体系结构和常见存储引擎的比较

本文介绍MySQL体系结构以及存储引擎&#xff08;InnoDB、MyISAM、Memory&#xff09;的比较 文章目录 MySQL 体系结构连接层服务层连接池系统管理和控制工具SQL接口解析器查询优化器缓存 引擎层存储层 存储引擎InnoDBMyISAMMemory区别 MySQL 体系结构 连接层 最上层是一些客户…

Rust 正式发布八周年纪念日 2023.5.15

图源&#xff1a;维基百科 目录 Rust 1. Rust的特点 1.1 安全性 1.2 并发性 1.3 性能 1.4 代码可读性 2. 使用场景 2.1 系统编程 2.2 Web开发 2.3 游戏开发 3. 与其他语言的对比 4. 代码示例 1. Hello, World! 2. 简单的函数 3. 变量绑定和变量类型推断 4. 结…

dayday60-120

目录 60 申论强化361 申论强化462 模考大赛错题63 言语真题164 言语真题65 言语真题366 判断真题1676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 60 申论强化3 1.公文题的格式不允许丢…

Vector - CAPL - CAN消息自动化设置

目录 canGetDataLength -- 获取CAN消息有效负载长度 代码示例 canOutputErrorFrame -- 模拟发送错误帧消息 代码示例 isStdId & isExtId -- 判断报文是标准帧&扩展帧 代码示例 mkExtId -- 将标准帧转换为扩展帧 代码示例 valOfId -- CAN消息的长值标识符 代…

基于SpringBoot的原创歌曲平台的设计与实现

背景 原创歌曲分享平台&#xff0c;为了随时随地查看原创歌曲分享信息提供了便捷的方法&#xff0c;更重要的是大大的简化了管理员管理原创歌曲分享信息的方式方法&#xff0c;更提供了其他想要了解原创歌曲分享信息及运作情况以及挑选方便快捷的可靠渠道。相比于传统原创歌曲…

六级备考33天|CET-SET6|六级口语|备考手册|考试样题|热门话题

目录 样题 1 The benefits of college athletics 2 The adverse impact of cheating on examinations 3 My view on working part-time during ones college years 4 Should students take part in extracurricular activities 5 If you choose overseas studies 6 The…

基于stm32物联网开发板(3)--SYN6288语音模块

基于stm32物联网开发板(3)–SYN6288语音模块 1.SYN6288语音模块展示示例 SYN6288语音模块 2.概述 SYN6288-A语音合成模块是一款性价比更高&#xff0c;效果更自然的一款中高端语音合技术 。 SYN6288-A通过异步串口接收待合成的文本&#xff0c;实现文本到声音&#xff08;TTS&…

SPL即将取代SQL?

先来看看两者的定义。 SQL&#xff1a;结构化查询语言。 SPL&#xff1a;结构化数据计算语言。 既然是比较文章&#xff0c;那必然是要突出一方的优势。 以下是SQL的痛点以及SPL的优点&#xff1a; 1.SQL缺乏离散性&#xff0c;集合化不彻底&#xff1b;SPL离散与集合充分结…

如何删除 Docker 镜像、容器和卷?

Docker 是一款常用的容器化平台&#xff0c;通过 Docker 可以将应用程序打包成一个独立的容器&#xff0c;方便地在不同的环境中运行。随着 Docker 的广泛使用&#xff0c;删除 Docker 镜像、容器和卷的操作也变得非常重要。在本文中&#xff0c;我们将介绍如何删除 Docker 镜像…

Python消费Kafka与优化

一.背景与问题 之前使用kafka-python库进行消费数据处理业务逻辑&#xff0c;但是没有深入里面的一些细节&#xff0c;导致会遇到一些坑。正常普通我们常见的一个消费者代码:(假设topic的分区数是20个) from kafka import KafkaConsumerbootstrap_servers [localhost:9092] g…

vim命令大全,非常详细,强烈建议收藏!

Vim是一款常用的文本编辑器&#xff0c;具有强大的功能和高度的可定制性。在本文中&#xff0c;我们将详细介绍Vim的常用命令&#xff0c;并提供相关的示例。如果您是初学者或已经熟练使用Vim&#xff0c;这篇文章都能为您提供帮助。 基本命令 以下是一些基本的Vim命令&#x…

一文足矣:Unity行为树

目录 前言 unity行为树简介 一个简单的敌人AI 正文 个人对行为树的理解 有限状态机与行为树 基本框架 BTNode DataBase 行为树入口 行为树的事件GraphEvent 发送事件 监听事件 脚本发送事件 行为树的管理&操作 一、操作单颗树 二、管理所有树 自定义Task任务 …