裸机使用Fatfs时,没有任何问题,加入Free RTOS后就一直不能f_mount,返回值一直为1,百思不得其解,几经周转,最后重新配置了一次就正常使用了

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
六、增加测试代码
在main.c中添加fputc重定义一下printf

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
重定向fputc

/* USER CODE BEGIN 4 */

//重定向fputc函数printf 
int fputc(int ch,FILE *f){
            
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
} 
//重定向fgetc函数 scanf
int fgetc(FILE *f){
            
	uint8_t ch;
	HAL_UART_Receive(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}
/* USER CODE END 4 */

在freertos.c中添加测试代码
(Fatfs的初始化啥的都在任务中进行初始化)

#include "fatfs.h"
#include "sdmmc.h"
#include <stdio.h>

#define FF_MAX_SS		4096

//	函数:FatFs_FileTest
//	功能:进行文件写入和读取测试
//
uint8_t  FatFs_FileTest(void)	//文件创建和写入测试
{
            
	uint8_t i = 0;
	uint16_t BufferSize = 0;	
	FIL	MyFile;			// 文件对象
	UINT 	MyFile_Num;		//	数据长度
	BYTE 	MyFile_WriteBuffer[] = "STM32H7B0 SD卡 文件系统测试";	//要写入的数据
	BYTE 	MyFile_ReadBuffer[1024];	//要读出的数据
	uint8_t MyFile_Res;    /* Return value for SD */
	
	printf("-------------FatFs 文件创建和写入测试---------------\r\n");
	
	MyFile_Res = f_open(&MyFile,"0:FatFs Test.txt",FA_CREATE_ALWAYS | FA_WRITE);	//打开文件,若不存在则创建该文件
	if(MyFile_Res == FR_OK)
	{
            
		printf("文件打开/创建成功,准备写入数据...\r\n");
		
		MyFile_Res = f_write(&MyFile,MyFile_WriteBuffer,sizeof(MyFile_WriteBuffer),&MyFile_Num);	//向文件写入数据
		if (MyFile_Res == FR_OK)	
		{
            
			printf("写入成功,写入内容为:\r\n");
			printf("%s\r\n",MyFile_WriteBuffer);
		}
		else
		{
            
			printf("文件写入失败,请检查SD卡或重新格式化!\r\n");
			f_close(&MyFile);	  //关闭文件	
			return ERROR;			
		}
		f_close(&MyFile);	  //关闭文件			
	}
	else
	{
            
		printf("无法打开/创建文件,请检查SD卡或重新格式化!\r\n");
		f_close(&MyFile);	  //关闭文件	
		return ERROR;		
	}
	
	printf("-------------FatFs 文件读取测试---------------\r\n");	
	
	BufferSize = sizeof(MyFile_WriteBuffer)/sizeof(BYTE);									// 计算写入的数据长度
	MyFile_Res = f_open(&MyFile,"0:FatFs Test.txt",FA_OPEN_EXISTING | FA_READ);	//打开文件,若不存在则创建该文件
	MyFile_Res = f_read(&MyFile,MyFile_ReadBuffer,BufferSize,&MyFile_Num);			// 读取文件
	if(MyFile_Res == FR_OK)
	{
            
		printf("文件读取成功,正在校验数据...\r\n");
		
		for(i=0;i<BufferSize;i++)
		{
            
			if(MyFile_WriteBuffer[i] != MyFile_ReadBuffer[i])		// 校验数据
			{
            
				printf("校验失败,请检查SD卡或重新格式化!\r\n");
				f_close(&MyFile);	  //关闭文件	
				return ERROR;
			}
		}
		printf("校验成功,读出的数据为:\r\n");
		printf("%s\r\n",MyFile_ReadBuffer);
	}	
	else
	{
            
		printf("无法读取文件,请检查SD卡或重新格式化!\r\n");
		f_close(&MyFile);	  //关闭文件	
		return ERROR;		
	}	
	
	f_close(&MyFile);	  //关闭文件	
	return SUCCESS;
}
//	函数:FatFs_GetVolume
//	功能:计算设备的容量,包括总容量和剩余容量

void FatFs_GetVolume(void)	// 计算设备容量
{
            
	FATFS *fs;		//定义结构体指针
	uint32_t SD_CardCapacity = 0;		//SD卡的总容量
	uint32_t SD_FreeCapacity = 0;		//SD卡空闲容量
	DWORD fre_clust, fre_sect, tot_sect; 	//空闲簇,空闲扇区数,总扇区数

	f_getfree("0:",&fre_clust,&fs);			//获取SD卡剩余的簇

	tot_sect = (fs->n_fatent-2) * fs->csize;	//总扇区数量 = 总的簇 * 每个簇包含的扇区数
	fre_sect = fre_clust * fs->csize;			//计算剩余的可用扇区数	   

	SD_CardCapacity = tot_sect / 2048 ;	// SD卡总容量 = 总扇区数 * 512( 每扇区的字节数 ) / 1048576(换算成MB)
	SD_FreeCapacity = fre_sect / 2048 ;	//计算剩余的容量,单位为M
	printf("-------------------获取设备容量信息-----------------\r\n");		
	printf("SD容量:%dMB\r\n",SD_CardCapacity);	
	printf("SD剩余:%dMB\r\n",SD_FreeCapacity);
}

void FatFs_Check(void)	//判断FatFs是否挂载成功,若没有创建FatFs则格式化SD卡
{
            
	BYTE work[FF_MAX_SS]; 
	
	FATFS_LinkDriver(&SD_Driver, SDPath);		// 初始化驱动
	retSD = f_mount(&SDFatFS,"0:",1);	//	挂载SD卡
	
	if (retSD == FR_OK)	//判断是否挂载成功
	{
            
		printf("\r\nSD文件系统挂载成功\r\n");
		FatFs_GetVolume();
	}
	else		
	{
            
		if(retSD == 13)
		{
            
			printf("SD卡还未创建文件系统,即将格式化\r\n");
			
			retSD = f_mkfs("0:",FM_FAT32,0,work,sizeof work);		//格式化SD卡,FAT32,簇默认大小16K
			
			if (retSD == FR_OK)		//判断是否格式化成功
				printf("SD卡格式化成功!\r\n");
			else
				printf("格式化失败,请检查或更换SD卡!\r\n");
		}
		else
			printf("挂载失败:%d\r\n",retSD);
	}
}
void printf_sdcard_info(void)
{
            
	HAL_SD_CardInfoTypeDef  SDCardInfo;  
	uint64_t CardCap;      	//SD卡容量
	HAL_SD_CardCIDTypeDef SDCard_CID; 

	HAL_SD_GetCardCID(&hsd1,&SDCard_CID);	//获取CID
	HAL_SD_GetCardInfo(&hsd1,&SDCardInfo);                    //获取SD卡信息
	CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize);	//计算SD卡容量
	switch(SDCardInfo.CardType)
	{
            
		case CARD_SDSC:
		{
            
			if(SDCardInfo.CardVersion == CARD_V1_X)
				printf("Card Type:SDSC V1\r\n");
			else if(SDCardInfo.CardVersion == CARD_V2_X)
				printf("Card Type:SDSC V2\r\n");
		}
		break;
		case CARD_SDHC_SDXC:printf("Card Type:SDHC\r\n");break;
		default:break;
	}	
		
    printf("Card ManufacturerID: %d \r\n",SDCard_CID.ManufacturerID);				//制造商ID	
 	printf("CardVersion:         %d \r\n",(uint32_t)(SDCardInfo.CardVersion));		//卡版本号
	printf("Class:               %d \r\n",(uint32_t)(SDCardInfo.Class));		    //
 	printf("Card RCA(RelCardAdd):%d \r\n",SDCardInfo.RelCardAdd);					//卡相对地址
	printf("Card BlockNbr:       %d \r\n",SDCardInfo.BlockNbr);						//块数量
 	printf("Card BlockSize:      %d \r\n",SDCardInfo.BlockSize);					//块大小
	printf("LogBlockNbr:         %d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr));		//逻辑块数量
	printf("LogBlockSize:        %d \r\n",(uint32_t)(SDCardInfo.LogBlockSize));		//逻辑块大小
	printf("Card Capacity:       %d MB\r\n",(uint32_t)(CardCap>>20));				//卡容量
}

最后在任务中进行调用即可
示例:

/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
            
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
	
	FatFs_Check();
	printf_sdcard_info();
	FatFs_FileTest();
	
  for(;;)
  {
            
	HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
    osDelay(1000);
  }
  /* USER CODE END StartDefaultTask */
}

工程文件下载

https://wwbac.lanzoue.com/iqwyk3jcq8uj
Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐