当前位置: 首页 > news >正文

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

上节学习了FatFs文件系统的相关知识,这节内容继续学习在STM32上如何移植FatFs文件系统,并且实现文件的创建、读、写与删除等功能。各位看官觉得还行的话点点赞,收藏一下呗。

一、FatFs文件系统移植

移植还是在之前学习过程中一直之用的模板,一点点的在自建的工程上逐步完善整个STM32的板级支持包。

1、将ff11a版本的文件夹复制到工程文件夹的User目录下,里面的Doc文件夹是FatFs的说明文档,这里不需要,可以直接删除掉了。

在这里插入图片描述

2、将在工程文件中,新增FatFs文件组,并将ff.c、diskio.c、ccsbcs.c文件加入到目录下。(ccsbcs.c暂时可以不用添加,这个项目中暂时用不到,添加了编译也会报错)

在这里插入图片描述

3、将文件路径添加到工程中。

在这里插入图片描述

以上就完成了向工程中添加FatFs源码的步骤,下来我们对FatFs文件系统进行裁剪和修改。

二、FatFs文件系统源码裁剪和修改

1、添加设备的物理驱动器编号,这个跟Windows上基本上是一致的,大家可以在Windows中进入磁盘管理看一下,比如我的电脑是双硬盘,两个磁盘的物理编号就分别是0和1

在这里插入图片描述

在FatFs文件系统的源码中,已经存在了3个设备编号,分别是ATA、MMC和USB,对应编号为0-2,这里我们新增FLASH的编号为3(注意,这里如果直接宏定义为FLASH的话,会和说stm32f4xx.h中重定义,所以这里宏定义为SPI_FLASH)

/* Definitions of physical drive number for each drive */
#define ATA			0		/* Example: Map ATA harddisk to physical drive 0 */
#define MMC			1		/* Example: Map MMC/SD card to physical drive 1 */
#define USB			2		/* Example: Map USB MSD to physical drive 2 */
#define SPI_FLASH    3    	 /* Example: Map FLASH to physical drive 3 */
2、改写diskio.c中各个功能函数:

2.1 获取驱动器状态函数DSTATUS disk_status (BYTE pdrv)

/*** @brief 获取驱动器状态* @param 驱动器编号* @retval 驱动器状态*/
DSTATUS disk_status (BYTE pdrv)
{DSTATUS stat;switch (pdrv) {case ATA :return stat;case MMC :return stat;case USB :return stat;case SPI_FLASH :				/* 这里获取FLASH的状态信息,我们之前在实现SPI读写FLASH的时候,可以用检测ID号判断设备是否能正常读取来判断 */if(SPI_FLASH_ReadID() == sFLASH_ID){return 0;				/* 若设备能正常读取ID号,则返回0 */}else{return STA_NOINIT;		/* 若读不到ID号,则返回驱动器未初始化,及为0x01 */}}return STA_NOINIT;
}

2.2 设备初始化,这里实际上就是对SPI总线的配置,只需要调用我们之前实现的SPI配置函数即可。

/*** @brief 初始化设备* @param 驱动器编号* @retval 驱动器状态*/
DSTATUS disk_initialize (BYTE pdrv)
{DSTATUS stat ;u32 status  = STA_NOINIT;switch (pdrv) {case ATA :return stat;case MMC :return stat;case USB :return stat;case SPI_FLASH :SPI_GPIO_Config();						/* 这里直接调用我们对SPI总线的配置函数即可 */SPI_Flash_WakeUp();					 /* 为了防止在其他地方对SPI设置为掉电模式,这里直接增加一条强置唤醒 */status = SPI_FLASH_ReadID();			  /* 同样,这里以读取FLASH ID的方式判断设备是否上线 */if(status == sFLASH_ID){return 0;}else{return STA_NOINIT;}}return STA_NOINIT;
}

2.3 扇区读写

/*** @brief 读扇区* @param pdrv:驱动器编号buff:读取到的数据存储缓冲区sector:读取的目标扇区号count:读取扇区数量* @retval 驱动器状态*/
DRESULT disk_read (BYTE pdrv,BYTE *buff,DWORD sector,UINT count)
{DRESULT res;switch (pdrv) {case ATA :return res;case MMC :return res;case USB :return res;case SPI_FLASH :/* 这里因为我用的是野火的F429开发板,厂家在出场的时候在FLASH中已经存储了开机例程所需要的一些字库文件以及图片文件,因此根据厂家给出的扇区分布对我们可以使用的扇区进行了偏移,具体偏移量看下面的表格。*/sector += 1536;/* FatFs文件系统是以扇区读写内容,我们实现的Flash读写是以字节读取,因此这里将扇区转换为字节位置,数量转换为字节 */SPI_Flash_ReadDate(buff, sector * 4096, count * 4096);return RES_OK;}return RES_PARERR;
}

厂家FLASH预留的FLASH存储设置,前1536个扇区已被使用,如果后面需要厂家预留的文件,只使用后面10M的空间就行,不需要的话可以全部擦除。

序号文件名/工程功能起始地址长度
1外部flash读写例程预留给裸机Flash测试04096 (BYTE)
2预留预留1*409659*4096 (BYTE)
3app.cXBF字库文件(emWin使用,新宋体25.xbf)60*4096649*4096(1.23MB)
4app.cXBF字库文件(emWin使用,新宋体19.xbf)710*4096529*4096(172KB)
4firecc936.c文件系统中文支持字库(emWin使用,UNIGBK.BIN)1240*409643*4096(172KB)
5EMW1062模块WIFI模块固件(BCM43362-5.90.230.12.bin)1284*409662*4096(248KB)
5.1EMW1062模块WIFI模块参数1(预留,不需要写文件)1347*40961*4096(4KB)
5.2EMW1062模块WIFI模块参数2(预留,不需要写文件)1348*40961*4096(4KB)
6裸机中文显示例程裸机中文字库(GB2312_H2424.FON)1360*4096144*4096(576KB)
7diskio.cFATFS文件系统(emWin使用)1536*40962560*4096(10MB)

2.4 数据写入,与读取基本相似,需要注意的是,该函数受到写保护限制,使用前需要先看一下_USE_WRITE是否为1。

/*** @brief 写扇区* @param pdrv:驱动器编号buff:写入的数据存储缓冲区sector:写入的目标扇区号count:写入扇区数量* @retval 驱动器状态*/
#if _USE_WRITE
DRESULT disk_write (BYTE pdrv,const BYTE *buff,	DWORD sector,UINT count)
{DRESULT res;switch (pdrv) {case ATA :return res;case MMC :return res;case USB :return res;case SPI_FLASH :/* 前6M空间存储出厂的一些数据文件,因此这里偏移一部分 */sector += 1536;SPI_Flash_Erase(sector * 4096);				/* 写入之前需要擦除数据 */SPI_FLASH_BufferWrite((u8 *)buff, sector * 4096, count * 4096);return RES_OK;}return RES_PARERR;
}
#endif

2.5 控制函数

/*** @brief 控制函数* @param pdrv:驱动器编号cmd:控制命令buff:指向缓冲区的指针,取决于命令代码,不使用时可以传个空指针进去* @retval 控制状态*/
#if _USE_IOCTL
DRESULT disk_ioctl (BYTE pdrv,BYTE cmd,void *buff)
{DRESULT res;switch (pdrv) {case ATA :return res;case MMC :return res;case USB :return res;case SPI_FLASH :switch(cmd){case CTRL_SYNC:					/* 是否使用缓存功能,这里我们不适用,所以留空 */break;case GET_SECTOR_COUNT:			/* 获取磁盘的可用扇区数 *//* 前6M空间存储出厂的一些数据文件,因此这里偏移一部分 */*(DWORD *)buff = 4096 - 1536;break;case GET_SECTOR_SIZE:			/* 返回磁盘的扇区大小,FLASH中一个扇区为4096个字节,所以这里直接返回4096即可 */*(WORD *)buff = 4096;break;case GET_BLOCK_SIZE:			/* 获取擦除块的大小,一般我们擦除的时候都是整个扇区擦除,此处直接返回1即可 */*(DWORD *)buff = 1;break;}return res;}return RES_PARERR;
}
#endif
3、对ffconf.h进行修改
1、设置设备数量

FatFs文件系统默认支持设备为1个,我们在上面增加了SPI_FLASH后,一共为4个,所以这里需要将支持设备数量改为4.

#define _VOLUMES	4				/* 将默认设备数量更改为4个 */
2、配置支持扇区的大小范围

FLASH的扇区大小为4096,这里直接改为4096即可。

#define	_MIN_SS		4096		//这里默认为512,在学习野火的教程时,我看火哥对此项没有更改,但是后面测试的时候会有问题,更改为4096后正常了
#define	_MAX_SS		4096

到此文件系统的一直基本完成,需要主义的是,我们在上面对diskio.c文件的修改,使用到了之前我们实现的SPI读写FLASH部分函数,因此需要在diskio.c中也包含#include "bsp_spi_flash.h"头文件,并且源文件中还有usbdisk.hatadrive.hsdcard.h的文件我们用不到,这里需要删掉。

另外,在编译的过程中会出现一个错误:

Error: L6218E: Undefined symbol get_fattime (referred from ff.o).

我们暂时用不到获取文件时间的功能,所以这里就自己写一个get_fattime函数来骗过编译器,等到后面深度学习文件系统的时候再考虑实现。

DWORD get_fattime(void)
{return 0;
}

三、测试

OK,到这里文件系统的移植和裁剪已经初步完成,我们来测试一下。

1、挂载(注册)设备

文件系统使用时,首先需要再系统中注册设备,这里就是用到了f_mount,与Windows系统一样,我们再挂载设备的时候,需要知道设备的盘符,比如:C:\Windows\1.txt,这里的C就是设备的盘符,我们在diskio.c中将SPI_FLASH宏定义为3,那这里对应的SPI_FLASH的盘符就是3。

FATFS flash_fs;
int main(void)
{DEBUG_USART1_Config();printf("\r\n这是一个文件系统移植例程实验\r\n");res = f_mount(&flash_fs,"3:",1);printf("\r\nf_mount res = %d\r\n",res);if(FR_OK == res){printf("\r\n文件系统挂载成功!\r\n");}else{printf("\r\n设备挂载失败,失败代码:error = %d\r\n",res);}while(1){}
}

f_mount的返回值如下:

返回值说明
FR_OK0:成功
FR_DISK_ERR1:磁盘I/O层中发生硬错误
FR_INT_ERR2:断言失败
FR_NOT_READY3:物理驱动器无法工作
FR_NO_FILE,4:找不到文件
FR_NO_PATH5:找不到路径
FR_INVALID_NAME6:路径格式无效
FR_DENIED7:禁止访问或目录已满,访问被拒绝
FR_EXIST8:禁止访问,访问被拒绝
FR_INVALID_OBJECT9:文件/目录对象无效
FR_WRITE_PROTECTED10:物理驱动器写保护
FR_INVALID_DRIVE11:逻辑驱动器号无效
FR_NOT_ENABLED12:卷没有工作区域
FR_NO_FILESYSTEM13:没有有效的FAT卷
FR_MKFS_ABORTED14:f_mkfs()由于任何参数错误而中止
FR_TIMEOUT15:无法在定义的时间段内获得访问卷的授权
FR_LOCKED16:根据文件共享策略,该操作被拒绝
FR_NOT_ENOUGH_CORE17:无法分配LFN工作缓冲区
FR_TOO_MANY_OPEN_FILES18:打开的文件数>_FS_LOCK
FR_INVALID_PARAMETER19:给定的参数无效

回到上面关于扇区大小的设置里面看一下,我刚开始在测试的时候,只修改了_MAX_SS为4096,没有修改_MIN_SS,导致返回值为1(FR_DISK_ERR),后来尝试修改_MIN_SS为4096后正常了,到现在也没搞明白具体是因为什么,只有等到后面将FatFs文件系统全部搞清楚后,才能知道,这里先留做一个疑点吧。

在这里插入图片描述

2、打开/关闭文件

设备挂载成功后,就打开文件了。这里使用到的函数主要有:

FRESULT f_open (FIL* fp,           /* [OUT] 指向文件对象的指针 */const TCHAR* path, /* [IN] 文件名 */BYTE mode          /* [IN] 模式 */
);

关于文件指针的相关知识点,各位在学习C语言的时候应该有涉及到,这里就不详细讲了。

在FatFs文件系统中,文件名与DOS/Windows下基本是一致的,这里指的文件名不只是单一文件的名称,而是包含文件的绝对路径地址,其文件名格式如下:

[drive#:][/]directory/file

比如我们在这里Flash的卷标为3,在根目录下存在一个1.txt,那么文件名就应该为:3:1.txt,官方在这里给出了一些文件名的写法,大家可以参考一下:

Path nameFF_FS_RPATH == 0(绝对路径)FF_FS_RPATH >= 1(相对路径)
file.txt驱动器0个目录中的file.txt文件当前所在驱动器的当前所在目录下的file.txt文件
/file.txt驱动器0个目录中的file.txt文件当前所在驱动器的根目录下的file.txt文件
驱动器0的根目录当前所在驱动器的当前目录
/驱动器0的根目录当前所在驱动器的根目录
2:驱动器2的根目录驱动器2的当前所在目录
2:/驱动器2的根目录驱动器2的根目录
2:file.txt驱动器2根目录中的file.txt文件驱动器2的当前所在目录下的file.txt文件
…/file.txt无效路径/文件名父目录的file.txt文件,即上级目录中的file.txt文件
.无效路径/文件名本目录
无效路径/文件名当前目录的父目录(上级目录)
dir1/…无效路径/文件名当前目录
/…无效路径/文件名根目录

文件打开的模式,这里跟C语言的文件操作模式基本类似,这里也列出来各位学习一下。

FlagsMeaning
FA_READ指定对文件的读取访问权限。可以从文件中读取数据。
FA_WRITE指定对文件的写入访问权限。数据可以写入文件。与“FA_READ”组合用于读写访问。
FA_OPEN_EXISTING打开一个文件。如果文件不存在,函数将返回失败。(默认)
FA_CREATE_NEW创建一个新文件。如果文件存在,则返回FR_EXIST失败信息。
FA_CREATE_ALWAYS创建新的文件,如果文件已经存在,则会覆盖原文件
FA_OPEN_ALWAYS打开文件,若文件不存在,则创建该文件
FA_OPEN_APPEND与“FA_OPEN_ALWAYS”相同,文件打开后,读/写指针设置定位在文件末尾。

官方的说明文件中,还针对文件的打开方式仿照我们在PC上编程时做了个对照表。

POSIXFatFs说明
“r”FA_READ只读
“r+”FA_READ | FA_WRITE读写
“w”FA_CREATE_ALWAYS | FA_WRITE覆盖创建,只写
“w+”FA_CREATE_ALWAYS | FA_WRITE | FA_READ覆盖创建,读写
“a”FA_OPEN_APPEND | FA_WRITE打开文件,将读写指针定位到末尾,只写
“a+”FA_OPEN_APPEND | FA_WRITE | FA_READ打开文件,将读写指针定位到末尾,读写
“wx”FA_CREATE_NEW | FA_WRITE创建新文件,只写
“w+x”FA_CREATE_NEW | FA_WRITE | FA_READ创建新文件,读写

函数的返回值有:FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY, FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED, FR_EXIST, FR_INVALID_OBJECT, FR_WRITE_PROTECTED, FR_INVALID_DRIVE, FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_TIMEOUT, FR_LOCKED, FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES,具体的含义各位可以看一下f_mount那里的表格说明。

文件操作完成后,需要将文件关闭,这个就比较简单了。

FRESULT f_close (FIL* fp     /* [IN] 指向文件对象的指针 */
);

函数的返回值有:FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_INVALID_OBJECT, FR_TIMEOUT具体的含义各位可以看一下f_mount那里的表格说明。

3、文件读写

文件的读写主要使用到两个函数:f_readf_write,关于这两个函数的使用与PC上的用法基本是一致的,这里将函数大致说明一下,等会在程序中我们做测试即可。

先看一下f_read函数:

FRESULT f_read (FIL* fp,     /* [IN] 指向文件对象的指针 */void* buff,  /* [OUT] 读取数据缓冲区 */UINT btr,    /* [IN] 需要读取的字节数 */UINT* br     /* [OUT] 实际读取到的字节数 */
);

函数的返回值有:FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

f_write函数

FRESULT f_write (FIL* fp,          /* [IN] 指向文件对象的指针 */const void* buff, /* [IN] 指向写入数据缓冲区的地址 */UINT btw,         /* [IN] 写入的字节数 */UINT* bw          /* [OUT] 指向写入数据数量的指针 */
);

函数的返回值有:FR_OK, FR_DISK_ERR, FR_INT_ERR, FR_DENIED, FR_INVALID_OBJECT, FR_TIMEOUT

4、测试

#include "stm32f4xx.h"
#include "bsp_led.h"
#include "bsp_usart_dma.h"
#include "bsp_spi_flash.h"
#include "ff.h"
#include <stdio.h>
#include <string.h>FATFS flash_fs;				//声明文件系统对象
FIL fp;					   //创建文件
UINT fnum;				   //接收读/写返回的数量
FRESULT res;			   //获取返回值
BYTE writeBuffer[] = "\r\n瀛洲学士风流远,中叶唐惭贞观唐。\r灵武拾遗晚羁旅,开元供奉老佯狂。\r戏苕翡翠非伦拟,撼树蚍蜉不揣量。\r赖有元和韩十八,骑麟被发共翱翔。\r\n";
BYTE readBuffer[1024] = {0};
int main(void)
{DEBUG_USART1_Config();printf("\r\n这是一个文件系统移植例程实验\r\n");res = f_mount(&flash_fs,"3:",1);				//挂载FLASH,注意卷号应该和diskio.c中宏定义的一致if(FR_OK == res)							   //若挂载成功{printf("\r\n文件系统挂载成功!\r\n");f_unlink("3:1.txt");						//删除卷3下的1.txt文件res = f_open(&fp,"3:1.txt",FA_CREATE_ALWAYS | FA_WRITE );//以只写方式打开卷3下的1.txt文件,这里如果改为FA_CREATE_NEW,就不需要删除了if(res == FR_OK)										//若打开成功{printf("\r\n文件打开成功,准备写入数据!\r\n");res = f_write(&fp,writeBuffer,sizeof(writeBuffer),&fnum);		//写入数据if (res==FR_OK) 											//若写入成功{printf("》文件写入成功,写入字节数据: %d\n",fnum);		   //写入成功,输出写入的数据量printf("》向文件写入的数据为: \r\n%s\r\n",writeBuffer);} else {printf("!!文件写入失败: (%d)\n",res);}f_close(&fp);												//关闭文件}else{printf("\r\n文件打开失败,失败代码 = %d\r\n",res);				//输出打开失败代码}res = f_open(&fp,"3:1.txt",FA_OPEN_EXISTING | FA_READ );			//以只读方式打开文件if(res == FR_OK)												//若文件打开成功{printf("\r\n文件打开成功,准备读取数据!\r\n");res = f_read(&fp,readBuffer,sizeof(readBuffer),&fnum);			//读取文件中的内容if(res==FR_OK)												//若读取成功{printf("》文件读取成功,读到字节数据:%d\r\n",fnum);			//输出读取到的数据量printf("》读取得的文件数据为:\r\n%s \r\n", readBuffer);	   //输出读取到的内容}else{printf("!!文件读取失败:(%d)\n",res);}	f_close(&fp);        										//关闭文件}else{printf("\r\n文件打开失败,失败代码 = %d\r\n",res);				//输出打开失败代码}}else{printf("\r\n设备挂载失败,失败代码:error = %d\r\n",res);			//设备挂载失败,输出失败代码}while(1){}
}

在这里插入图片描述

相关文章:

020 - STM32学习笔记 - Fatfs文件系统(二) - 移植与测试

020 - STM32学习笔记 - Fatfs文件系统&#xff08;二&#xff09; - 移植与测试 上节学习了FatFs文件系统的相关知识&#xff0c;这节内容继续学习在STM32上如何移植FatFs文件系统&#xff0c;并且实现文件的创建、读、写与删除等功能。各位看官觉得还行的话点点赞&#xff0c…...

flask用DBUtils实现数据库连接池

flask用DBUtils实现数据库连接池 在 Flask 中&#xff0c;DBUtils 是一种实现数据库连接池的方案。DBUtils 提供了持久性&#xff08;persistent&#xff09;和透明的&#xff08;transient&#xff09;两种连接池类型。 首先你需要安装 DBUtils 和你需要的数据库驱动。例如&…...

SQL注入之布尔盲注

SQL注入之布尔盲注 一、布尔盲注介绍二、布尔盲注的特性三、布尔盲注流程3.1、确定注入点3.2、判断数据库的版本3.3、判断数据库的长度3.4、猜解当前数据库名称&#xff08;本步骤需要重复&#xff09;3.5、猜解数据表的数量3.6、猜解第一个数据表名称的长度3.7、猜解第一个数据…...

微服务入门---SpringCloud(一)

微服务入门---SpringCloud&#xff08;一&#xff09; 1.认识微服务1.0.学习目标1.1.单体架构1.2.分布式架构1.3.微服务1.4.SpringCloud1.5.总结 2.服务拆分和远程调用2.1.服务拆分原则2.2.服务拆分示例2.2.1.导入Sql语句2.2.2.导入demo工程 2.3.实现远程调用案例2.3.1.案例需求…...

Rust vs Go:常用语法对比(九)

题图来自 Golang vs Rust - The Race to Better and Ultimate Programming Language 161. Multiply all the elements of a list Multiply all the elements of the list elements by a constant c 将list中的每个元素都乘以一个数 package mainimport ( "fmt")func …...

Typescript 第五章 类和接口(多态,混入,装饰器,模拟final,设计模式)

第五章 类和接口 类是组织和规划代码的方式&#xff0c;是封装的基本单位。 typescript类大量借用了C#的相关理论&#xff0c;支持可见性修饰符&#xff0c;属性初始化语句&#xff0c;多态&#xff0c;装饰器和接口。 不过&#xff0c;由于Typescript将类编译成常规的JavaScri…...

IFNULL()COALESCE()

在 MySQL 中&#xff0c;IFNULL() 函数是可用的&#xff0c;但是请注意它不能直接用于聚合函数的结果。要在聚合函数结果可能为 NULL 的情况下返回特定值&#xff0c;应该使用 COALESCE() 函数而不是 IFNULL() 函数。 以下是代码示例&#xff1a; COALESCE(SUM(pc.CONTRACT_T…...

WPF实战学习笔记23-首页添加功能

首页添加功能 实现ITodoService、IMemoService接口&#xff0c;并在构造函数中初始化。新建ObservableCollection<ToDoDto>、 ObservableCollection<MemoDto>类型的属性&#xff0c;并将其绑定到UI中修改Addtodo、Addmemo函数&#xff0c;将添加功能添加 添加添加…...

OpenCV-Python常用函数汇总

OpenCV Python OpenCV简述显示窗口waitKey()&#xff1a;等待按键输入namedWindow()&#xff1a;创建窗口destroyWindow() &#xff1a;注销指定窗口destroyAllWindows() 注销全部窗口resizeWindow() 调整窗口尺寸 图像操作imread()&#xff1a;读取图像imwrite()&#xff1a;保…...

Vue-router多级路由

目录 直接通过案例的形式来演示多级路由的用法 文件结构 Banner.vue <template><div class"col-xs-offset-2 col-xs-8"><div class"page-header"><h2>Vue Router Demo</h2></div></div> </template><…...

前端学习--vue2--2--vue指令基础

写在前面&#xff1a; 前置内容 - vue配置 文章目录 插值表达式v-html条件渲染v-show和v-ifv-ifv-if的扩展标签复用组件 v-show v-on /事件v-bind /&#xff1a;属性v-modelv-for 循环元素v-slotv-prev-cloak vue指令只的是带有v-前缀的特殊标签属性 插值表达式 插值表达式{…...

【Python机器学习】实验03 logstic回归

文章目录 简单分类模型 - 逻辑回归1.1 准备数据1.2 定义假设函数Sigmoid 函数 1.3 定义代价函数1.4 定义梯度下降算法gradient descent(梯度下降) 1.5 绘制决策边界1.6 计算准确率1.7 试试用Sklearn来解决2.1 准备数据(试试第二个例子)2.2 假设函数与前h相同2.3 代价函数与前相…...

面试-杨辉三角python递归实现,二进制转换

杨辉三角 def yang_hui(x,y):xint(x)yint(y)assert x>y,列数不应该大于行数# x 表示行&#xff0c;y表示列if y1 or yx:return 1else:return yang_hui(x-1,y-1)yang_hui(x-1,y)xinput(输入第几行) yinput(输入第几列) resultyang_hui(int(x),int(y)) print(result) #inclu…...

SPEC CPU 2017 x86_64 Ubuntu 22.04 LTS LLVM 16.0.6 编译 intrate intspeed

源码编译llvm 下载源码 yeqiangyeqiang-MS-7B23:~/Downloads/src$ git clone --depth1 -b 7cbf1a2 https://github.com/llvm/llvm-project 正克隆到 llvm-project... warning: 不能发现要克隆的远程分支 7cbf1a2。 fatal: 远程分支 7cbf1a2 在上游 origin 未发现 yeqiangyeqi…...

java备忘录模式

在Java中&#xff0c;备忘录模式&#xff08;Memento Design Pattern&#xff09;用于捕获一个对象的内部状态并在该对象之外保存这个状态。备忘录模式允许在后续需要时将对象恢复到之前保存的状态&#xff0c;而不会暴露其内部结构。 备忘录模式包含以下主要角色&#xff1a;…...

iOS--runtime

什么是Runtime runtime是由C和C、汇编实现的一套API&#xff0c;为OC语言加入了面向对象、运行时的功能运行时&#xff08;runtime&#xff09;将数据类型的确定由编译时推迟到了运行时平时编写的OC代码&#xff0c;在程序运行过程中&#xff0c;最终会转换成runtime的C语言代…...

06. 管理Docker容器数据

目录 1、前言 2、Docker实现数据管理的方式 2.1、数据卷&#xff08;Data Volumes&#xff09; 2.2、数据卷容器&#xff08;Data Volume Containers&#xff09; 3、简单示例 3.1、数据卷示例 3.2、数据卷容器示例 1、前言 在生产环境中使用 Docker&#xff0c;一方面…...

计算机视觉常用数据集介绍

1 MINIST MINIST 数据集应该算是CV里面最早流行的数据了&#xff0c;相当于CV领域的Hello World。该数据包含70000张手写数字图像&#xff0c;其中60000张用于train&#xff0c; 10000张用于test&#xff0c; 并且都有相应的label。图像的尺寸比较小&#xff0c; 为28x28。 数…...

Arcgis画等高线

目录 数据准备绘制等高线3D等高线今天我们将学习如何在ArcGIS中绘制等高线地图。等高线地图是地理信息系统中常见的数据表现形式,它通过等高线将地形起伏展现得一目了然,不仅美观,还能提供重要的地形信息。 数据准备 在开始之前,确保已经准备好了高程数据,它通常以栅格数…...

abp vnext4.3版本托管到iis同时支持http和https协议

在项目上本来一直使用的是http协议,后来因为安全和一些其他原因需要上https协议&#xff0c;如果发布项目之后想同时兼容http和https协议需要更改一下配置信息&#xff0c;下面一起看一下&#xff1a; 1.安装服务器证书 首先你需要先申请一张服务器证书&#xff0c;申请后将证…...

2023年全网电视盒子无线ADB修改桌面(无需ROOT)

前言 1.主要是为了解决电视盒子等安卓设备无法卸载或者停用原始桌面导致无法选用第三方桌面。 解决方案 1.首先自行下载我提供的网盘APK 2.点击打开中国移动云盘 3.不管你是通过U盘还是局域网共享能够让你的电视安装第三方应用&#xff0c;毕竟每个品牌的安装方法不尽相同…...

什么是Java中的Maven?

Java中的Maven&#xff0c;可以简单理解为“一个神奇的工具”&#xff0c;它可以自动帮你管理Java项目的依赖关系&#xff0c;让你不再为手动下载、配置各种库而烦恼。想象一下&#xff0c;你正在写一个Java项目&#xff0c;突然发现需要引入一个名为"第三方库"的模块…...

【C++】总结7

文章目录 函数指针C中类成员的访问权限和继承权限问题定义和声明的区别C中类的静态成员与普通成员的区别是什么&#xff1f;虚函数为什么不能重载为内联函数&#xff1f;对ifdef endif的理解如何在不使用额外空间的情况下&#xff0c;交换两个数&#xff1f; 函数指针 什么是函…...

【前端知识】React 基础巩固(四十二)——React Hooks的介绍

React 基础巩固(四十二)——React Hooks的介绍 一、为什么需要Hook? Hook 是 React 16.8 的新增特性&#xff0c;它可以让我们在不编写class的情况下使用state以及其他的React特性&#xff08;比如生命周期&#xff09;。 class组件 VS 函数式组件&#xff1a; class的优势…...

adb命令丨adb push命令大全_adb操控手机和指令

【ADB命令】adb push命令总结 adb push命令大全操控手机和指令 运行在 Android 设备上的adb后台进程 执行 adb shell ps | grep adbd &#xff0c;可以找到该后台进程&#xff0c;windows 请使用 findstr 替代 grep [xuxu:~]$ adb shell ps | grep adbd root 23227 1 6672 8…...

【腾讯云 Cloud Studio 实战训练营】沉浸式体验编写一个博客系统

文章目录 前言项目中技术栈新建工作空间登录(注册)Cloud Studio 账号&#xff1a;进入 Cloud Studio 控制台&#xff1a;配置工作空间参数&#xff1a;确认并创建工作空间&#xff1a;项目搭建 配置nuxt 脚手架运行项目报错信息解决错误脚手架运行预览问题 开启博客代码配置lay…...

手机视频聊天分享

在人际互动的手机APP中&#xff0c;增加语音视频聊天功能是一个常见的需求。而现在&#xff0c;更进一步&#xff0c;在某些场景下&#xff0c;我们需要能将自己的手机屏幕分享给他人&#xff0c;或者是观看他人的手机屏幕。那么&#xff0c;这些常见的功能是如何实现的了&…...

神经网络小记-优化器

优化器是深度学习中用于优化神经网络模型的一类算法&#xff0c;其主要作用是根据模型的损失函数来调整模型的参数&#xff0c;使得模型能够更好地拟合训练数据&#xff0c;提高模型的性能和泛化能力。优化器在训练过程中通过不断更新模型的参数&#xff0c;使模型逐步接近最优…...

200+行代码写一个简易的Qt界面贪吃蛇

照例先演示一下&#xff1a; 一个简单的Qt贪吃蛇&#xff0c;所有的图片都是我自己画的&#xff08;得意&#xff09;。 大致的运行逻辑和之前那个200行写一个C小黑窗贪吃蛇差不多&#xff0c;因此在写这个项目的时候&#xff0c;大多情况是在想怎么通过Qt给展现出来。 背景图…...

redis中使用bloomfilter的白名单功能解决缓存穿透问题

一 缓存预热 1.1 缓存预热 将需要的数据提前缓存到缓存redis中&#xff0c;可以在服务启动时候&#xff0c;或者在使用前一天完成数据的同步等操作。保证后续能够正常使用。 1.2 缓存穿透 在redis中&#xff0c;查询redis缓存数据没有内容&#xff0c;接着查询mysql数据库&…...

设计师找图网站/网站推广怎么推广

“天哪&#xff01;这么多&#xff0c;这真的一年估计都吃不完” 尽管早有心理准备&#xff0c;但当王宏旻面对农村淘宝送的整整1200斤大米时&#xff0c;仍不禁感叹。 农村淘宝推出共享丰收喜悦“随手拍丰收”活动。一周时间内全国32个省市区上万名网友参与&#xff0c;随手拍…...

贵阳地铁建设网站/seo是什么工作内容

2019独角兽企业重金招聘Python工程师标准>>> [toc] 网络协议&#xff08;networking protocol&#xff09; 网络协议即为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议是由三个要素组成&#xff1a;语义、语法、时序&#xff0c;人们形象地把这…...

网站后台管理开发/qianhu微建站

1.请阅读并运行AboutException.java示例&#xff0c;然后通过后面的几页PPT了解Java中实现异常处理的基础知识。 &#xff08;1&#xff09;import javax.swing.*; class AboutException { public static void main(String[] a) { int i1, j0, k; ki/j; try { …...

苹果电脑用什么软件做网站/网络推广网上营销

分类简介: 阅读他人的代码&#xff0c;可以学到很多东西&#xff0c;从思路&#xff0c;到方案&#xff0c;一系列都可以在项目代码中体现&#xff0c;所以&#xff0c;此分类专门用于记录阅读过的项目代码&#xff0c;并在上面给出自己的理解和注释 在此&#xff0c;感谢原作者…...

免费社区建站系统/刷移动端seo软件

GameFi是以传统游戏模型为基础&#xff0c;进一步引入通证经济模型且构建在区块链上&#xff0c;并以Play-to-earn为特性的新事物。其将传统互联网游戏的意识形态深度的颠覆&#xff0c;玩家在贡献注意力价值、时间的同时还能够赚取收益。 甚至在全球新冠大流行的背景下&#x…...

找人做网赌网站需要多少钱/seowhy培训

先简单看一下主过程&#xff1a; int MAXFLOW() {hights();prepare();while (!Q.empty()) {u Q.get;for each e in G (from u) push(e);if (!fixed(u)) reCalc(u);} }接下来介绍算法 预流推进算法给每一个顶点一个标号h(v)&#xff0c;表示该点到t的最短路&#xff08;在残量…...