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

news2024/9/28 11:14:18

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)
    {
    }
}

在这里插入图片描述

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

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

相关文章

uniapp 全局数据(globalData)的设置,获取,更改

globalData&#xff0c;这是一种简单的全局变量机制。这套机制在uni-app里也可以使用&#xff0c;并且全端通用 因为uniapp基本上都是将页面&#xff0c;或者页面中相同的部分&#xff0c;进行组件化&#xff0c;所以会存在父&#xff0c;子&#xff0c;&#xff08;子&#xf…

AI革命:揭开微软无与伦比的AI技术面纱

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 2023年7月25日&#xff0c;全球科技行业的领导者之一微软(MSFT)公布了其2023财年第四季度的财报。 除了举世闻名的Windows操作系统&#xff0c;微软还通过笔记本电脑、个人电脑和服务器等产品改变了世界&#xff0c;该公司…

ARM裸机-2

1、搞清楚各种版本号 1.1、ARM的型号命名问题 ARM7和ARMv7不是一回事。 Cortex-A9比Cortex-A7更先出来。 型号很乱&#xff0c;初学者容易分不清哪个是哪个&#xff0c;比较迷茫。 1.2、ARM的几种版本号 ARM内核版本号&#xff08;ARM卖给别人的核心版本号&#xff09; …

IntelliJ IDEA 2023.2 主要更新了什么?(图文版)

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

无敌的服务注册中心Spring CloudAlibaba Nacos不进来看一看吗?

1、Nacos概述 Nacos支持发现、配置和管理几乎所有类型的服务。其Key features&#xff1a;Service Discovery And Service Health Check、Dynamic configuration management、Dynamic DNS service、Service governance and metadata management 官网 2、Nacos安装运行 安装 …

LearnOpenGL_Day1

文章目录 前期准备下载GLFW下载GLAD 引入库文件生成窗口重要概念——双缓冲 &#xff08;double buffer&#xff09;代码实现 学习总结 前期准备 下载GLFW GLFW DOWNLOAD 解压后使用CMake编译至新创建的bulid文件夹下&#xff1a; 下载GLAD 引入库文件 创建好工程&#x…

git的ssh方式对接码云

一、环境准备&#xff1a; 1、git下载&#xff0c;360管家或是百度。 2、vs2022&#xff0c;百度下载。 二、配置git&#xff1a; 1、打开准备存放文件的文件夹&#xff0c;右键&#xff0c;选择“Git Bash here”&#xff0c;弹出命令窗口&#xff0c; 输入&#xff1a;ss…

平板光波导中传播常数β的matlab计算(验证了是对的)

参照的是导波光学_王建(清华大学)的公式(3-1-2、3-1-3)&#xff0c;算的参数是这本书的图3-3的。 function []PropagationConstantsMain() clear;clc;close all lambda01.55;%真空或空气中的入射波长&#xff0c;单位um k02*pi/lambda0; m3;%导模阶数(需要人为指定) n11.62;%芯…

入门redis你一定需要知道的命令

1、各种数据类型的特点 字符串(string)&#xff1a;普通字符串&#xff0c;Redis中最简单的数据类型 哈希(hash)&#xff1a;也叫散列&#xff0c;类似于Java中的HashMap结构 列表(list)&#xff1a;按照插入顺序排序&#xff0c;可以有重复元素&#xff0c;类似于Java中的Li…

回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测

回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-ELM鲸鱼算法优化极限学习机多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现WOA-ELM鲸鱼算法优化极限学习机多输入回归预测&#…

流数据湖平台Apache Paimon(二)集成 Flink 引擎

文章目录 第2章 集成 Flink 引擎2.1 环境准备2.1.1 安装 Flink2.1.2 上传 jar 包2.1.3 启动 Hadoop2.1.4 启动 sql-client 2.2 Catalog2.2.1 文件系统2.2.2 Hive Catalog2.2.3 sql 初始化文件 2.3 DDL2.3.1 建表2.3.2 修改表 2.4 DML2.4.1 插入数据2.4.2 覆盖数据2.4.3 更新数据…

idea插件开发-自定义语言4-Syntax Highlighter

SyntaxHighlighter用于指定应如何突出显示特定范围的文本&#xff0c;ColorSettingPage可以定义颜色。 一、Syntax Highter 1、文本属性键&#xfeff; TextAttributesKey用于指定应如何突出显示特定范围的文本。不同类型的数据比如关键字、数字、字符串等如果要突出显示都需…

ReID网络(一):MGN网络

Start MGN 1. 序言 现代基于感知的信息中&#xff0c;视觉信息占了80~85%。基于视觉信息的处理和分析被应用到诸如安防、电力、汽车等领域。 以安防市场为例&#xff0c;早在2017年&#xff0c;行业咨询公司IHS Market&#xff0c;我国在公共和私人领域安装有摄像头约1.76亿…

《TCP IP网络编程》第十三章

第 13 章 多种 I/O 函数 13.1 send & recv 函数 Linux 中的 send & recv&#xff1a; send 函数定义&#xff1a; #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags); /* 成功时返回发送的字节数&#xff0c;失败…

36.悬浮板

悬浮板 html部分 <div class"container"><div class"square"></div> </div>css部分 *{margin: 0;padding: 0; } body{background-color: #111;height: 100vh;overflow: hidden;display: flex;justify-content: center;align-it…

layui框架学习(33:流加载模块)

Layui中的流加载模块flow主要支持信息流加载和图片懒加载两部分内容&#xff0c;前者是指动态加载后续内容&#xff0c;示例的话可以参考csdn个人博客主页&#xff0c;鼠标移动到页面底部时自动加载更多内容&#xff0c;而后者是指页面显示图片时才会延迟加载图片信息。   fl…

苍穹外卖-day08

苍穹外卖-day08 本项目学自黑马程序员的《苍穹外卖》项目&#xff0c;是瑞吉外卖的Plus版本 功能更多&#xff0c;更加丰富。 结合资料&#xff0c;和自己对学习过程中的一些看法和问题解决情况上传课件笔记 视频&#xff1a;https://www.bilibili.com/video/BV1TP411v7v6/?sp…

第17节 R语言分析:生物统计数据集 R 编码分析和绘图

生物统计数据集 R 编码分析和绘图 生物统计学,用于对给定文件 data.csv 中的医疗数据应用 R 编码,该文件是患者人口统计数据集,包含有关来自各种祖先谱系的个体的标准信息。 数据集特征解释 脚本 output= file("Output.txt") # File name of output log sink(o…

[数据集][目标检测]城市道路井盖破损丢失目标检测1377张

数据集制作单位&#xff1a;未来自主研究中心(FIRC) 数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1377 标注数量(xml文件个数)&#xff1a;1377 标注类别数&a…

Spring源码(五)— 解析XML配置文件(二) 定制化标签解析流程

上一篇以bean标签为例&#xff0c;介绍了属于defaultNamesapce标签的解析流程&#xff0c;但是defaultNamespace中默认的标签只有bean、beans、alias、import这四个&#xff0c;而我们平时在xml中配置的标签有很多。那其余的标签是如何解析&#xff1f; 在这篇文章会详细介绍定…