正点原子嵌入式linux驱动开发——TF-A使用

news2024/11/27 5:27:08

上一篇笔记STM32MP157芯片的开发环境,之后就直接简写为MP1。为了保证安全ARM推出了 Arm Trusted Firmware的可信固件,简称 TF-A。它是一个开源的软件,最早是用在Armv8-A,ST也在MP1里面使用到了TF-A。它的作用就是隔离硬件,为硬件提供一个安全环境并且提供安全服务

TF-A初步使用

智能设备的安全问题是一个物联网产品非常重要的环节, ARM为此提供了TrustZone解决方案TrustZone将CPU的工作状态分为了Secure World(安全世界)和Normal World(非安全世界),涉及到安全相关的内容运行在安全世界,比如指纹、密码等,其他的操作都在非安全世界运行,比如应用程序。TrustZone是一种硬件解决方案,只要学会使用就好了,不用过多探究,不是linux驱动开发的重点。

系统源码获取

与TrustZone对应的,我们需要一套软件来配合TrustZone,TF-A应运而生,TF-A全称是Arm Trusted Firmware,有些资料也叫做 ATF,一般中文资料叫做 ARM可信固件。 MP1内部集成了TrustZone,因此ST也提供了TF-A相关源码TF-A会先初始化DDR等外设,把Uboot从Flash(NAND、NOR FLASH、SD、MMC 等)拷贝到DDR中。我们不可能直接去官方网站下载TF-A的源码,这样的开发难度太大,半导体厂商都会从TF-A官网下载源码,然后修改适配自己
的芯片,把自家的芯片加进去
。在实际项目开发中直接使用半导体原厂给提供的TF-A即可。ST官方TF-A、uboot、 kernel等源码下载链接为: ST官方系统源码,打开以后如下图所示:
MP1系统源码下载
中的 STM32MP1Dev就是官方的源码包,里面包括 TF-A uboot kernel等源码,点击“ Get Software”下载整个系统源码。这里我们已经下载下来并放到了开发板光盘中,就是en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz

在Ubuntu中创建一个目录存放源码,然后将ST官方系统源码发送到Ubuntu中。这里我在前面创建的“linux”目录下新建一个名为“stm32mp1”的目录存放所有源码,命令如下:

cd linux/ //进入linux目录
mkdir stm32mp1 //创建stm32mp1目录

用FileZilla将ST官方源码压缩包en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz拷贝到“atk-mp1”目录下。解压压缩包,命令如下:

tar -xvf en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-06-24.tar.xz

解压完成以后会得到一个名为“stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24”的文件夹;进入stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi目录下,里面就是uboot、optee、tf-a、kernel源码,而这5个源码文件夹的含义如下图所示:
系统源码
上图中共有 5个源码,本教程就用到前三个u-boot-stm32mp-2020.01-r0、linux-stm32mp-5.4.31-r0和tf-a-stm32mp-2.2.r1-r0,也就是TF-A、Uboot和Linux Kernel传统的linux学习中不需要TF-A的,只需要uboot和Linux Kernel,但是MP1带有安全硬件,因此加入了TF-A。

首先TF-A并不是ST自己做的, ST只是将自己的MP1芯片移植到了TF-A上,上图中的tf-a-stm32mp-2.2.r1-r0就是ST自己修改后的TF-A源码,直接使用ST修改后的 TF-A源码即可,包括uboot、linux kernel都是这样的

tf-a-stm32mp-2.2.r1-r0支持ST所有的 MP1芯片,也支持各种启动方式,例如:EMMC、NAND、NOR FLASH等等。 tf-a-stm32mp-2.2.r1-r0里面包含了 ST自家所有的MP1评估板,正点原子的STM32MP157开发板参考了ST官方的STM32MP157C-EV1开发板,因此,后续的移植都是以STM32MP157C-EV1开发板为蓝本,在此基础上进行修改

tf-a-stm32mp-2.2.r1-r0目录文件一共有5个文件,这5个文件的含义如下图所示:
tf-a源码文件含义

TF-A源码打补丁

上图中的TF-A源码还不能直接使用,需要对其打补丁。ST也是在TF-A官方的源码上将自己的MP1系列芯片添加进去的,因此必然涉及到对官方TF-A源码的修改,修改的部分就是“补丁”,补丁文件后缀为.patch,之前图片中的0001-st-update-v2.2-r2.0.0.patch就是ST为TF-A官方源码做的补丁文件,补丁文件里面描述了修改源码中的哪些文件,应该添加或删除哪些代码或文件,打完补丁后的TF-A才是真正需要的。因此,打补
丁需要两个文件:

  1. 补丁文件,在此处就是0001-st-update-v2.2-r2.0.0.patch;
  2. 需要打补丁的源文件,在此处就是tf-a-stm32mp-2.2.r1-r0.tar.gz。

首先需要先解压tf-a-stm32mp-2.2.r1-r0.tar.gz,命令如下所示:

tar -vxf tf-a-stm32mp-2.2.r1-r0.tar.gz

解压完就会在当前目录下生成“tf-a-stm32mp-2.2.r1”目录;接下来就是给TF-A源码打补丁,在解压好的TF-A的目录下运行以下命令:

cd tf-a-stm32mp-2.2.r1 //进入TF-A源码
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done //打补丁

这条命令的意思是把上一层目录下的所有“ “.patch”后缀的文件都通过patch命令打补丁到TF-A的源码目录,在这里就是将001-st-update-v2.2-r2.0.0.patch这个补丁打入到TF-A源码里面,过程如下图所示:
TF-A源码打补丁
由于ST官方源码目录太长,为了方便调试,在stm32mp1目录下创建一个名为“tf-a”的子
目录,然后就打完补丁后的tf-a-stm32mp-2.2.r1-r0目录下的所有文件都拷贝到tf-a下
,命令如下:

cd tf-a-stm32mp-2.2.r1-r0/
cp * /home/zuozhongkai/linux/atk-mp1/tf-a/ -rf

以上命令的cp之后的具体目录看你自己是怎么创建的,更换一下就可以了,拷贝完成后tf-a目录应如下图所示:
tf-a目录

创建VSCode工程

为了方便阅读TF-A源码,可以创建一个VSCode工程,然后打开VSCode,点击:文件->打开文件夹,选中打完补丁后的tf-a-stm32mp-2.2.r1-r0文件夹,打开以后的VSCode如下图所示:
TF-A的VSCode工程
左侧的资源管理器就是TF-A的工程目录结构。最后我们保存一下工作区, 点击:文件 ->将工作区另存为…,打开保存工作区对话框,将工作区保存到TF-A 源码根目录下,设置文件名为“ tf-a”,如下图所示:
TF-A源码工作区创建
保存以后就会在TF-A源码根目录下多出一个名为“tf-a.code-workspace”的文件,这样一个完整的 VSCode工程就建立起来了

编译和烧录TF-A

通过上文得到的TF-A源码是ST提供的,这个TF-A肯定是不能直接在正点原子的STM32MP157开发板上运行的,需要移植和修改。但是在正式移植TF-A之前需要了解如何编译TF-A,并烧写到正点原子的STM32MP157开发板上,这里我们直接编译正点原子已经修改好的TF-A

stm32wrapper4dbg工具安装

编译TF-A或者Uboot的时候需要用到stm32wrapper4dbg这个工具,否则编译会报错。ST提供了这个工具的码,我们需要在Ubuntu下编译并安装这个源码,源码的下载地址为:stm32wrapper4dbg下载地址,这个正点原子是已经在开发光盘中提供了的,就是stm32wrapper4dbg-master.zip。 将源码压缩包拷贝到Ubuntu下,然后进行解压,命令如下:

unzip stm32wrapper4dbg-master.zip //解压

解压完成以后就会得到一个名为“stm32wrapper4dbg-master”的文件夹,进入到此文件夹里面,然后编译并安 装,命令如下:

cd stm32wrapper4dbg-master //进入到此文件夹
make //编译

编译完成以后就会得到一个名为“stm32wrapper4dbg”的工具;将编译出来的stm32wrapper4dbg工具拷贝到 Ubuntu的 /usr/bin目录下,命令如下:

sudo cp stm32wrapper4dbg /usr/bin

拷贝完成以后就可以直接在终端中使用stm32wrapper4dbg这个工具了,输入如下命令查看
帮助信息:

stm32wrapper4dbg -s

如果输出下图所示内容就说明stm32wrapper4dbg工具安装成功:
stm32wrapper4dbg帮助信息

编译正点原子官方TF-A

准备正点原子出厂TF-A源码

首先安装设备树编译相关命令,输入如下命令:

sudo apt-get install device-tree-compiler

在Ubuntu的stm32mp1目录下新建一个名为“alientek_tf-a”的子目录,然后把正点原子修改好的TF-A源码拷贝到alientek_tf-a这个目录下。正点原子修改好的TF-A源码已经放到了开发板光盘中,就是tf-a-stm32mp-2.2.r1-g463d4d8-v1.0.tar.bz2。 拷贝完成以后解压,输入如下命令:

tar -xvf tf-a-stm32mp-2.2.r1-g463d4d8-v1.0.tar.bz2

解压完成以后alientek_tf-a文件夹就会有tf-a-stm32mp-2.2.r1文件夹,这就是正点原子针对自己的STM32MP157开发板修改过的TF-A源码,Makefile.sdk是一会编译TF-A要用到的Makefile。

修改Makefile.sdk

首先,TF-A是有自己的Makefile文件的,而且真正编译的时候也是要用TF-A自己的Makefile。Makefile.sdk是ST自己编写的,也是我们一会编译TF-A的时候要用到的,Makefile.sdk里面主要定义了一些编译属性,比如要使用的交叉编译器、编译的一些选项等等,Makefile.sdk最终会调用 TF-A内部的 Makefile来编译TF-A。默认情况下Makefile.sdk里面使
用的是ST官方的交叉编译器 (arm-ostl-linux-gnueabi-gcc),但是正点原子的文档教程中用的是通用交叉编译器arm-none-linux-gnueabihf-gcc,因此我们需要修改Makefile.sdk,将交叉编译器改为我们目前所使
用的
。打开Makefile.sdk,然后找到CROSS_COMPILE,将其改为“arm-none-linux-gnueabihf-”

编译TF-A

准备工作都就绪以后就可以编译正点原子出厂TF-A了,进入到tf-a-stm32mp-2.2.r1目录里面,然后运行执行如下命令编译TF-A:

cd tf-a-stm32mp-2.2.r1/ //进入到正点原子出厂 TF-A的源码目录
make -f ../Makefile.sdk all //编译 TF-A

‘-f’的意思是重新指定Makefile,在这里就是指定Makefile.sdk,编译成功会出现下图所示:
TF-A编译成功
编译完成以后会在上一层目录,也就是alientek_tf-a下生成一个名为“build”的目录,进入build目录下,一共有三个子目录:optee、serialboot和trusted,如下图所示:
build子目录
我们只关注trusted目录下的文件,此目录下就保存了MP1所有型号的TF-A固件,包括正点原子开发板所使用的tf-a-stm32mp157d-atk-trusted.stm32,如下图所示:
编译得到的正点原子STM32MP157开发板的TF-A固件

TF-A烧录到EMMC

使用STM32CubeProgrammer将TF-A烧写到开发板里面,STM32CubeProgrammer支持通过UART、USB、STLINK来烧写系统,本教程全部采用USB烧写,也就是通过开发板上的USB_OTG口来烧写系统

准备烧写材料

在Windows下通过STM32CubeProgrammer来烧写TF-A,新建一个目录来存放烧写镜像文件,例如创建一个名为“images”的目录。然后将开发板光盘里面的这两个文件先拷贝到images目录下:tf-a-stm32mp157d-atk-serialboot.stm32, u-boot.stm32,全部都是正点原子官方写的。

最后就是前面编译出来,真正要烧写的 tf-a-stm32mp157d-atk-trusted.stm32,通过FileZilla将 Ubuntu里面的tf-a-stm32mp157d-atk-trusted.stm32发送到images目录下

正点原子提供的这两个文件是干嘛的呢?正点原子的教程是这么说的,和STM32CubeProgrammer软件的设计以及烧写过程有关:tf-a-stm32mp157d-atk-serialboot.stm32中间有个“serialboot”,也就是串行BOOT,说明是和启动有关的;此固件用来初始化USB、DDR等外设,DDR初始化了以后就可以运行uboot了(uboot里面会初始化EMMC、NAND等外设,而且uboot会提供很强大的EMMC操作指令);也就是说,启动uboot的目的就是为了操作EMMC、NAND,这样就可以在uboot里面通过相关的命令将tf-a-stm32mp157d-atk-trusted.stm32写到EMMC或者NAND里面。

总结来说,正点原子的教程认为,需要tf-a-stm32mp157d-atk-serialboot.stm32和u-boot.stm32的原因,就是为了将tf-a-stm32mp157d-atk-trusted.stm32烧写到EMMC、NAND、SD卡里面。

准备FlashLayout

以上三个文件的烧写设置需要通过STM32CubeProgrammer脚本文件来定义,STM32CubeProgrammer脚本文件后缀为.tsvST官方也叫做FlashLayout。这里可以直接在正点原子提供的tsv文件基础上修改,将开源的开发光盘中的atk_emmc-stm32mp157d-atk-qt.tsv拷贝到前面的 images前目录下,然后将其重命名为“tf-a.tsv”,完成后 images目录如下图所示:
最终images目录
.tsv是文本格式的,很容易阅读,关于.tsv语法的详细讲解,请参考: tsv详解。用Notepad++软件打开tf-a.tsv,默认格式时看不出什么的,tsv对格式有要求,必须要设置一下 Notepad++软件,点击“视图->显示符号->显示空格与制表符”, 设置好以后的tf-a.tsv如下图所示:
tf-a.tsv内容
tf-a.tsv中,黄色箭头代表是TAB键,TAB键越多黄色箭头就越长,如果用空格键的话就会显示‘_’tsv语法要求只能用TAB键,不能用空格!以‘#’开头为注释,所以上图第一行为注释 。

修改tf-a.tsv文件内容如下图所示:
修改后的tf-a.tsv文件
上图中一共有5行,第1行为注释,一共7列,这7列的含义如下图所示:
tf-a.tsv的配置解析
接下来详细介绍一下这7个配置:

1.Opt域
Opt是第一个项,此选项通过‘-’、‘P’、‘D’和‘E’这四个字符定义操作方法,首选的是‘-’和‘P’。

  • ‘-’:none,也就是空选项,分区或者设备无需修改,如果Device域为none,那么Opt强制为‘ ‘-’;
  • ‘P’:向分区或者设备烧写固件。

STM32CubeProgrammer本质是通过uboot来烧写系统的,也就是先把uboot加载到板子的DDR里面并运行,然后使用uboot来烧写系统。uboot会请求需要烧写的二进制文件,然后将其烧写到指定的分区或者Falsh设备里面。

针对‘P’,还可以搭配一下两个参数:

  • ‘E’:空分区或设备,表示对应的分区或设备不更新,相关的Id项会被跳过;
  • ‘D’:删除分区或设备。

允许的组合如下:

  • ‘-’:空选型;
  • ‘P’:更新分区或设备,也就是向分区或设备烧写固件;
  • ‘PE’:不更新,也就是指定某个分区或者设备不需要烧写固件,这样我们就可以单独只更新tf-a,uboot,kernel或rootfs;
  • ‘PD’:删除并更新,也可以写作‘DP’;
  • ‘PDE’:删除并且保持为空,也可写作‘PED/DPE/DEP/EPD/EDP’。

2.Id域

STM32CubeProgrammer通过Id域来确定烧写方法,会通过Id域来识别下一个要烧写到设备里面的二进制文件:

  • ROM或FSBL:二进制文件要加载到RAM;
  • SSBL(uboot):二进制文件要烧写到Flash中。

FlashLayout支持的Id范围如下图所示:
FlashLayout支持的Id范围
其中0X01和0X03这两个Id是给FSBL和SSBL留着的,它们会被加载到RAM中。一些默认的Id含义如下图所示:
默认Id含义
3.Name域

Name域为一段字符串,也就是目标内存段的名字

4.Type域

Type域仅仅用于uboot,用来选择需要更新的Flash区域

  • SD卡或者EMMC设备对应GPT分区;
  • 原始的Flash设备,如NAND、NOR等对应MTD分区。

SD/EMMC和NAND/NOR所支持的Type类型如下图所示:
Type域
正点原子STM32MP157开发板为EMMC类型,所以我们只需要知道EMMC下的Type域含义:

  • Binary:原始的二进制文件;
  • FileSystem:linux文件系统,为ext2/ext4/fat格式;
  • System:Linux内核。

5.Device域

Device域指定Uboot设备树定义的设备和索引 (从0开始),不同的设备其设备名字和索引不同:

  • mmc+索引 :如mmc0、mmc1、mmc2等,对应SD卡或EMMC;比如SD卡和EMMC分别接到MP1的SDMMC1和SDMMC2接口上,那么SD卡和EMMC分别为mmc0和mmc1;
  • nor+索引 :如nor0,对应NOR或者QUADSPI Flash;
  • nand+索引 :如nand0,对应连接到FMC总线上的并行NAND Flash;
  • spi-nand+索引 :如spi-nand0,对应连接到QSPI上的串行NAND Flash;
  • none:RAM,也就是将固件加载到RAM里面,仅允许启动阶段使用,而且Type域要为Binary,Offset域要为0,Opt域为‘-’;
  • ram+索引 :如ram0,烧写服务讲固件加载到RAM中运行。

6.Offset域

Offset就是偏移,支持的值如下:

  • boot1:EMMC的第一个启动区域分区;
  • boot2:EMMC的第二个启动区域分区;
  • 数字:具体的偏移值,单位为字节。

7.Binary域

STM32CubeProgrammer软件要使用的二进制文件

通过USB烧写TF-A

首先设置开发板拨码开关,设置为000,也就是从 USB启动,然后复位开发板!

首先通过USB Type-C线将开发板的USB_OTG和USB_TTL连接到电脑上,如下图所示:
USB串口与USB OTG连接
按照上图将板子的USB串口与USB OTG连接到电脑以后还要检查一下连接是否成功,打开电脑的设备管理器,查看CH340和DFU模式是否存在,如下图所示:
USB串口与USB OTG
连接没问题的话就可以使用STM32CubeProgrammer来烧写TF-A了,打开STM32CubeProgrammer,选择USB连接方式,Port选择 USB1,如下图所示:
USB连接设置
USB设置好以后点击右上角的“Connect”来连接开发板,连接成功以后左下角的log区域就会输出一些信息,右侧中间的数据区域也会显示开发板默认的分区情况,右下角会显示目标板信息,如下图所示:
软件连接信息
STM32CubeProgrammer要使用FlashLayout文件来烧写系统,也就是前面我们创建的tf-a.tsv。点击“Open File”,打开 tf-a.tsv,如下图所示:
加载tf-a.tsv文件
注意 ,如果没有看到的“Browse”和 Download”这两个按钮的话,把STM32CubeProgrammer界面放大一点,尤其是左右托大,因为软件默认界面会把这两个按钮挡住!

一切准备就绪以后就可以点击上图中的“Download”按钮开始下载,下方的log区域就会显示烧写过程,烧写完成以后就会有提示信息提示完成烧写。

TF-A运行

自己编译的TF-A已经烧写到了开发板中,接下来就是测试能不能运行打开MobaXterm软件,设置好与开发板连接的串口,波特率选择115200

设置开发板拨码开关为010,也就是从 EMMC启动,然后复位开发板!

注意,由于开发板默认已经烧写了整套Linux系统,所以直接启动的话会启动整个系统,包括我们刚刚烧写的自己编译的TF-A,原有的uboot、Linux系统等。TF-A是最先启动的,也就是最前的就是我们自己编译的 TF-A,如下图所示:
TF-A启动log信息
TF-A启动的时候会打印出编译时间,我们可以通过编译时间来判断是否为我们自己编译的TF-A。比如上图中 TF-A的编译时间为2020年11月11号10:53:02,这个时间是正点原子开发教程编译的时间,说明目前正在运行的 TF-A就是自行编译的正点原子出厂TF-A,也就是tf-a-stm32mp157d-atk-trusted.stm32。

总结

这一章节的内容,就是初步介绍了TF-A,然后根据正点原子给的源代码,进行初步的TF-A代码编译以及移植,学习了如何编译并适配自己的MP1开发板,然后完成了通过STM32CubeProgrammer完成TF-A的烧写操作,并通过运行时的log信息判断TF-A是否烧写成功

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

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

相关文章

递推+模拟---想好如何存储?

递推模拟 输入输出问题CCF-CSP考试历年真题题型分类分组输入——可能有多组测试数据&#xff0c;对于每组数据 递推---从前面已知态--->后续未知态AcWing 3777. 砖块AcWing 1208. 翻硬币AcWing 1211. 蚂蚁感冒AcWing 3433. 吃糖果AcWing 821. 跳台阶 模拟202212-2-csp-训练计…

C语言--atoi函数详解及模拟实现

本篇概要 本篇博客主要讲述atoi函数的定义&#xff0c;用法及模拟实现。 文章目录 本篇概要1.atoi函数简介2.atoi函数的原型及参数3.atoi函数的使用举例4.atoi函数的模拟实现 1.atoi函数简介 atoi() 是 C语言的一个标准库函数&#xff0c;定义在<stdlib.h>头文件中。 at…

【RocketMQ】基本使用:Java操作RocketMQ(rocketmq-client)

【RocketMQ】基本使用&#xff1a;Java操作RocketMQ&#xff08;rocketmq-client&#xff09; 1.引入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.3.2</version>…

公司知识库搭建步骤,知识库建设与运营的四个步骤分享

在知识管理方面&#xff0c;团队中的每一员&#xff0c;都像是一名独行侠&#xff0c;自己的知识&#xff0c;满足自己的需要&#xff0c;这其中&#xff0c;就造成了很多无意义的精力消耗。 公司知识库搭建必要性 比如&#xff0c;一名员工撰写一QA文档&#xff0c;并没有将它…

CDH 6.3.2升级Flink到1.17.1版本

CDH&#xff1a;6.3.2 原来的Flink&#xff1a;1.12 要升级的Flink&#xff1a;1.17.1 操作系统&#xff1a;CentOS Linux 7 一、Flink1.17编译 build.sh文件&#xff1a; #!/bin/bash set -x set -e set -vFLINK_URLsed /^FLINK_URL/!d;s/.*// flink-parcel.properties FLI…

【模板语法+数据绑定+el与data的两种写法+MVVM模型】

模板语法数据绑定el与data的两种写法MVVM模型 1 模板语法1.1 插值语法1.2 指令语法 2 数据绑定2.1 单向数据绑定2.2 双向数据绑定 3 el与data的两种写法4 MVVM模型 1 模板语法 1.1 插值语法 双大括号表达式功能&#xff1a;用于解析标签体内容语法&#xff1a;{{xxx}}&#x…

Postman的高级用法—Runner的使用

1.首先在postman新建要批量运行的接口文件夹&#xff0c;新建一个接口&#xff0c;并设置好全局变量。 2.然后在Test里面设置好要断言的方法 如&#xff1a; tests["Status code is 200"] responseCode.code 200; tests["Response time is less than 10000…

分子相互作用的人工智能

8 分子相互作用的人工智能 正如在第 5、6 和 7 节中所描述的那样&#xff0c;人工智能已经彻底改变了分子学习、蛋白质科学和材料科学领域。尽管已经广泛研究了用于单个分子的人工智能&#xff0c;但分子的物理和生物功能通常是由它们与其他分子的相互作用驱动的。在本节中&am…

iPhone数据丢失怎么办?9 佳免费 iPhone 数据恢复软件可收藏

您是否知道有多种原因可能导致 iPhone 上存储的数据永久丢失&#xff1f;然而&#xff0c;使用一些最好的免费 iPhone 数据恢复软件&#xff0c;您仍然可以恢复它。 由于我们几乎总是保存手机上的所有内容&#xff08;从联系人到媒体文件&#xff09;&#xff0c;因此 iPhone …

MySQL学习笔记27

MySQL主从复制的核心思路&#xff1a; 1、slave必须安装相同版本的mysql数据库软件。 2、master端必须开启二进制日志&#xff0c;slave端必须开启relay log 日志。 3、master主服务器和slave从服务器的server-id号不能一致。 4、slave端配置向master端来同步数据。 master…

【Java 进阶篇】MySQL 数据控制语言(DCL):管理用户权限

MySQL 是一个强大的关系型数据库管理系统&#xff0c;提供了丰富的功能和选项来管理数据库和用户。数据库管理员&#xff08;DBA&#xff09;通常使用数据控制语言&#xff08;Data Control Language&#xff0c;简称 DCL&#xff09;来管理用户的权限和访问。 本文将详细介绍…

基于php+MySql实现简易留言板(超级详细!)

基于phpMySql实现简易留言板&#xff08;超级详细&#xff01;&#xff09; 这篇文章是基于PHP和MySQL实现的一个简易留言板。该留言板具有用户注册、登录、发表留言以及查看留言等功能。首先&#xff0c;用户可以通过注册功能创建自己的账号&#xff0c;然后使用该账号进行登…

WPF 实现点击按钮跳转页面功能

方法1. 配置环境 首先添加prism依赖项&#xff0c;配置好所有文件。需要配置的有两个文件&#xff1a;App.xaml.cs和App.xaml App.xaml.cs using System.Data; using System.Linq; using System.Threading.Tasks; using System.Windows;namespace PrismDemo {/// <summa…

Linux 集锦 之 最常用的几个命令

Linux最常用的几个命令 ​ Linux系统中的命令那是相当地丰富&#xff0c;不同的版本可能还有不同的命令&#xff0c;不过Linux核心自带的命令大概有几百个&#xff0c;这个不管是什么发行版一般都是共用的。 ​ 如果希望探索Linux的所有命令&#xff0c;可能不太实际&#xf…

【Unity Build-In管线的SurfaceShader剖析_PBS光照函数】

Unity Build-In管线的SurfaceShader剖析 在Unity Build-In 管线&#xff08;Universal Render Pipeline&#xff09;新建一个Standard Surface Shader文件里的代码如下&#xff1a;选中"MyPBR.Shader"&#xff0c;在Inspector面板&#xff0c;打开"Show generat…

力扣刷题-哈希表-求两个数组的交集

349 求两个数组的交集 题意&#xff1a;给定两个数组&#xff0c;编写一个函数来计算它们的交集。注意&#xff1a;输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 提示&#xff1a; 1 < nums1.length, nums2.length < 1000 0 < nums1[i], …

TensorFlow-Federated简介与安装

1、简介 TensorFlow Federated&#xff08;TFF&#xff09;是一个用于机器学习和其他分布式数据计算的开源框架。TFF 的开发旨在促进联邦学习 &#xff08;FL&#xff09;的开放研究和实验。联邦学习是一种机器学习方法&#xff0c;其中一个共享的全局模型在许多参与的客户之间…

集线器与交换机有什么区别?一文带你了解

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 梦想从未散场&#xff0c;传奇永不落幕&#xff0c;博主会持续更新优质网络知识、Python知识、Linux知识以及各种小技巧&#xff0c;愿你我共同在CSDN进步 目录 一、集线器 1. 集线器是什么&#xff1f; 2. …

高并发时代到底是Go还是Java?

作为一名用过Java和Go开发过微服务架构程序的在校学生的角度思考&#xff0c;本文将从以下几个方便来讲述Go和Java的区别。 前言 小明&#xff1a;听说Go在天然情况下支持并发 小红&#xff1a;我不管Java就是最好的语言 小明&#xff1a;不行&#xff0c;我要学以下神秘的Go…

vue3 element-ui-plus Carousel 跑马灯 的使用 及 踩坑记录

vue3 element-ui-plus Carousel 跑马灯 的踩坑记录 Carousel 跑马灯首页跑马灯demo Carousel 跑马灯 首先&#xff0c;打开其官网-跑马灯案例 跑马灯代码&#xff1a; <el-carousel :interval"5000" arrow"always"><el-carousel-item v-for"…