硬汉嵌入式论坛

 找回密码
 立即注册
查看: 626|回复: 5
收起左侧

[FatFs] [FATFS]请问这个程序为什么文件可以创建成功,但是内容写不进去

[复制链接]

23

主题

58

回帖

127

积分

初级会员

积分
127
发表于 2023-7-30 18:33:37 | 显示全部楼层 |阅读模式


FATFS.
文件能创建成功,但是文件里的内容写不进去。
没搞明白。
参考博文博文

另外一个问题是


flash_spi_getid 调用不成功,头文件及源文件都有成功包含。其它的几个函数在diskio.c中都能正常调用。没明白是哪里的问题

回复

使用道具 举报

23

主题

58

回帖

127

积分

初级会员

积分
127
 楼主| 发表于 2023-7-30 22:43:54 | 显示全部楼层

到写的这一步出现 FR_OBJ
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2023-7-31 08:53:27 | 显示全部楼层
fopen的返回值也判断下。

FR_INVALID_OBJECT
The file/directory object is invalid or a null pointer is given. There are some reasons as follows:
It has been closed, or the structure has been collapsed.
It has been invalidated. Open objects on the volume are invalidated by voulme mount process.
Physical drive is not ready to work due to a media removal.
回复

使用道具 举报

23

主题

58

回帖

127

积分

初级会员

积分
127
 楼主| 发表于 2023-7-31 20:18:45 | 显示全部楼层
eric2013 发表于 2023-7-31 08:53
fopen的返回值也判断下。

FR_INVALID_OBJECT

fopen 是FR_OK的
回复

使用道具 举报

23

主题

58

回帖

127

积分

初级会员

积分
127
 楼主| 发表于 2023-7-31 21:06:34 | 显示全部楼层
eric2013 发表于 2023-7-31 08:53
fopen的返回值也判断下。

FR_INVALID_OBJECT

[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*	模块名称 : fatfs和sd卡,SPI Flash的接口文件
*	文件名称 : diskio.c
*	版    本 : V1.0
*	说    明 : 支持SD卡和SPI Flash
*
*	修改记录 :
*		版本号   日期         作者           说明
*       v1.0    2014-06-19   Eric2013        首发
*
*	Copyright (C), 2014-2015, 安富莱电子 [url]www.armfly.com[/url]
*
*********************************************************************************************************
*/
#include "diskio.h"		    /* FatFs lower layer API */
#include "bsp.h"


#define SECTOR_SIZE		512
/*-------------------------------------------------------------------------------------------*/
/* Inidialize a Drive                                                                        */
/*-------------------------------------------------------------------------------------------*/
DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber (0..) */
)
{
	DSTATUS stat = STA_NOINIT;

	switch (pdrv)
	{
		case FS_SD :		/* SD卡 */
			if (SD_Init() == SD_OK)
			{
				stat = RES_OK;
			}
			else
			{
				stat = STA_NODISK;
			}
			break;
			
		case FS_SPI_FLASH :
			bsp_InitSFlash();
			stat =  RES_OK;
			break;
		
		default :
			break;
	}

	return stat;
}

/*-------------------------------------------------------------------------------------------*/
/* Get Disk Status                                                                           */
/*-------------------------------------------------------------------------------------------*/
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber (0..) */
)
{
	DSTATUS stat = STA_NOINIT;

	switch (pdrv)
	{
		case FS_SD :
			stat = 0;
			break;
		
		case FS_SPI_FLASH :
			stat = 0;
			break;

		default:
			stat = 0;
			break;
	}
	return stat;
}

/*-------------------------------------------------------------------------------------------*/
/* Read Sector(s)                                                                            */
/*-------------------------------------------------------------------------------------------*/
DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	UINT count		/* Number of sectors to read (1..128) */
)
{
	DRESULT res = RES_ERROR;

	switch (pdrv)
	{
		case FS_SD :
		{
			SD_Error Status = SD_OK;

			if (count == 1)
			{
				Status = SD_ReadBlock(buff, sector << 9 , SECTOR_SIZE);
			}
			else
			{
				Status = SD_ReadMultiBlocks(buff, sector << 9 , SECTOR_SIZE, count);
			}
			
			if (Status != SD_OK)
			{
				res = RES_ERROR;
				break;
			}

		#ifdef SD_DMA_MODE
			/* SDIO工作在DMA模式,需要检查操作DMA传输是否完成 */
			Status = SD_WaitReadOperation();
			if (Status != SD_OK)
			{
				res = RES_ERROR;
				break;
			}

			while(SD_GetStatus() != SD_TRANSFER_OK);
		#endif

			res = RES_OK;
			break;
		}
		
		case FS_SPI_FLASH :
			sf_ReadBuffer(buff, sector << 12, count<<12);
			res =  RES_OK;
			break;
		
		default:
			res = RES_PARERR;
			break;
	}
	
	return res;
}

/*-------------------------------------------------------------------------------------------*/
/* Write Sector(s)                                                                           */
/*-------------------------------------------------------------------------------------------*/
#if _USE_WRITE
DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	UINT count			/* Number of sectors to write (1..128) */
)
{
	DRESULT res = RES_ERROR;

	switch (pdrv)
	{
		case FS_SD :
		{
			SD_Error Status = SD_OK;

			if (count == 1)
			{
				Status = SD_WriteBlock((uint8_t *)buff, sector << 9 ,SECTOR_SIZE);
			}
			else
			{
				/* 此处存在疑问: 扇区个数如果写 count ,将导致最后1个block无法写入 */
				//Status = SD_WriteMultiBlocks((uint8_t *)buff, sector << 9 ,SECTOR_SIZE, count);
				Status = SD_WriteMultiBlocks((uint8_t *)buff, sector << 9 ,SECTOR_SIZE, count + 1);
			}
			
			if (Status != SD_OK)
			{
				res = RES_ERROR;
				break;
			}

		#ifdef SD_DMA_MODE
			/* SDIO工作在DMA模式,需要检查操作DMA传输是否完成 */
			Status = SD_WaitReadOperation();
			if (Status != SD_OK)
			{
				res = RES_ERROR;
				break;
			}
			while(SD_GetStatus() != SD_TRANSFER_OK);
		#endif
			
			res = RES_OK;
			break;
		}
		
		case FS_SPI_FLASH :
		{
			#if 0
				uint8_t i;
				BYTE *p;
				
				p = (BYTE *)buff;
				for(i = 0; i < count; i++)
				{
					sf_WriteBuffer((uint8_t *)p, (sector+i) << 12, 4096);
					p += 4096;					
				}
			#else
				sf_WriteBuffer((uint8_t *)buff, sector << 12, count<<12);
			#endif
			res =  RES_OK;
			break;
		}

		default:
			res = RES_PARERR;
			break;
	}
	return res;
}
#endif


/*-------------------------------------------------------------------------------------------*/
/* Miscellaneous Functions                                                                   */
/*-------------------------------------------------------------------------------------------*/
#if _USE_IOCTL
DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res = RES_PARERR;

	switch (pdrv) {
	case FS_SD :
		switch (cmd)
		{
			/* SD卡磁盘容量: SDCardInfo.CardCapacity */
			case CTRL_SYNC :		/* Wait for end of internal write process of the drive */
				res = RES_OK;
				break;

			case GET_SECTOR_COUNT :	/* Get drive capacity in unit of sector (DWORD) */
				*(DWORD*)buff = SDCardInfo.CardCapacity / 512;
				res = RES_OK;
				break;

			case GET_BLOCK_SIZE :	/* Get erase block size in unit of sector (DWORD) */
				*(WORD*)buff = 512;
				res = RES_OK;
				break;

			case CTRL_ERASE_SECTOR: /* Erase a block of sectors (used when _USE_ERASE == 1) */
			default:
				res = RES_PARERR;
				break;
		}
		break;
		
	case FS_SPI_FLASH :
		res = RES_ERROR;
		switch(cmd)
		{
			/* SPI Flash不需要同步 */
			case CTRL_SYNC :  
				res =  RES_OK;
				break;
			
			/* 返回SPI Flash扇区大小 */
			case GET_SECTOR_SIZE:
				*((WORD *)buff) = 4096;  
				res =  RES_OK;
				break;
			
			/* 返回SPI Flash扇区数 */
			case GET_SECTOR_COUNT:
				*((DWORD *)buff) = 2048;    
				res =  RES_OK;
				break;
			
			/* 下面这两项暂时未用 */
			case GET_BLOCK_SIZE:   
				res =  RES_OK;
				break;
			
			case CTRL_ERASE_SECTOR:
				res =  RES_OK;  
				break;
			
			default:
				res = RES_PARERR;
				break;			
		}
	    break;

	default:
		res = RES_PARERR;
		break;
	}
	return res;
}
#endif

/*
*********************************************************************************************************
*	函 数 名: get_fattime
*	功能说明: 获得系统时间,用于改写文件的创建和修改时间。
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
DWORD get_fattime (void)
{
	/* 如果有全局时钟,可按下面的格式进行时钟转换. 这个例子是2013-01-01 00:00:00 */

	return	  ((DWORD)(2013 - 1980) << 25)	/* Year = 2013 */
			| ((DWORD)1 << 21)				/* Month = 1 */
			| ((DWORD)1 << 16)				/* Day_m = 1*/
			| ((DWORD)0 << 11)				/* Hour = 0 */
			| ((DWORD)0 << 5)				/* Min = 0 */
			| ((DWORD)0 >> 1);				/* Sec = 0 */
}


[C] 纯文本查看 复制代码
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module SKELETON for FatFs     (C)ChaN, 2019        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/

#include "ff.h"			/* Obtains integer types */
#include "diskio.h"		/* Declarations of disk functions */

/* Definitions of physical drive number for each drive */
#define DEV_RAM		0	/* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC		1	/* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB		2	/* Example: Map USB MSD to physical drive 2 */


/*-----------------------------------------------------------------------*/
/* Get Drive Status                                                      */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
	BYTE pdrv		/* Physical drive nmuber to identify the drive */
)
{
	DSTATUS stat;
	int result;

	switch (pdrv) {
	case DEV_RAM :
		//result = RAM_disk_status();
		//stat=flash_spi_getid();
		// translate the reslut code here
		//flash_spi_getid();
		stat=0;
		return stat;

	case DEV_MMC :
		//result = MMC_disk_status();

		// translate the reslut code here

		return stat;

	case DEV_USB :
		//result = USB_disk_status();

		// translate the reslut code here

		return stat;
	}
	return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
	DSTATUS stat;
	int result;

	switch (pdrv) {
	case DEV_RAM :
		//result = RAM_disk_initialize();

		// translate the reslut code here
		flash_spi_init();
		return stat;

	case DEV_MMC :
		//result = MMC_disk_initialize();

		// translate the reslut code here

		return stat;

	case DEV_USB :
		//result = USB_disk_initialize();

		// translate the reslut code here

		return stat;
	}
	return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/

DRESULT disk_read (
	BYTE pdrv,		/* Physical drive nmuber to identify the drive */
	BYTE *buff,		/* Data buffer to store read data */
	LBA_t sector,	/* Start sector in LBA */
	UINT count		/* Number of sectors to read */
)
{
	DRESULT res;
	int result;

	switch (pdrv) {
	case DEV_RAM :
		// translate the arguments here

		//result = RAM_disk_read(buff, sector, count);

		// translate the reslut code here
		flash_spi_read((uint8_t *)buff,sector*4096,count*4096);//count*4096
		return res;

	case DEV_MMC :
		// translate the arguments here

		//result = MMC_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;

	case DEV_USB :
		// translate the arguments here

		//result = USB_disk_read(buff, sector, count);

		// translate the reslut code here

		return res;
	}

	return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/

#if FF_FS_READONLY == 0

DRESULT disk_write (
	BYTE pdrv,			/* Physical drive nmuber to identify the drive */
	const BYTE *buff,	/* Data to be written */
	LBA_t sector,		/* Start sector in LBA */
	UINT count			/* Number of sectors to write */
)
{
	DRESULT res;
	int result;

	switch (pdrv) {
	case DEV_RAM :
		// translate the arguments here

		//result = RAM_disk_write(buff, sector, count);

		// translate the reslut code here
		flash_spi_write((uint8_t *)buff,sector*4096, (count)*4096);//count*4096
		return res;

	case DEV_MMC :
		// translate the arguments here

		//result = MMC_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;

	case DEV_USB :
		// translate the arguments here

		//result = USB_disk_write(buff, sector, count);

		// translate the reslut code here

		return res;
	}

	return RES_PARERR;
}

#endif


/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/

DRESULT disk_ioctl (
	BYTE pdrv,		/* Physical drive nmuber (0..) */
	BYTE cmd,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
	DRESULT res;
	int result;

	switch (pdrv) {
	case DEV_RAM :
		switch(cmd)
        {
		// Process of the command for the RAM drive
		case GET_SECTOR_COUNT:      // 多少个扇区
                // buff是void*类型指针(空指针),根据官网的disk_ioctl函数参数转换不同返回指针
                *(DWORD*)buff = 2048;   // SPI_FLASH有8M字节,每个扇区有4096个字节,即有2048个扇区
                break; 
             
            case GET_SECTOR_SIZE:       // 每个扇区大小
                *(WORD*)buff = 4096;    // 每个扇区有4096个字节
                break;
             
            case GET_BLOCK_SIZE:        // 块大小
                *(DWORD*)buff = 1;      // 设置为1,表示每次擦除1个扇区
                break;
			default:break;
		}
		res = RES_OK;
		return res;

	case DEV_MMC :

		// Process of the command for the MMC/SD card

		return res;

	case DEV_USB :

		// Process of the command the USB drive

		return res;
	}

	return RES_PARERR;
}
DWORD get_fattime (void)
{
    return 0;
}



第一段代码是从SPI FLASH+文件系统的例程中摘录出来,第二段是目前有问题的工程中的代码。看了一下 就ioctl里有些不一样,其它的基本上是一样的。(主要有个疑问就是文件能创建成功,那理论上内容也能写进去呀,f_open返回的是OK,f_write返回的是 invaild_object。实在没搞懂,应该和heap size没关系吧?)
回复

使用道具 举报

23

主题

58

回帖

127

积分

初级会员

积分
127
 楼主| 发表于 2023-7-31 21:28:30 | 显示全部楼层


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-28 06:43 , Processed in 0.306305 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表