fx_media_open 失败
调用fx_media_open出错返回状态 0x03 FX_FAT_READ_ERROR,独立使用FileX,磁盘驱动是sdio SD卡,SD裸驱在fatfs文件系统上能正常使用。
SD卡预先使用SD formatter 格式化工具格式了。不知道怎么解决了...
在 fx_media_open 定位了下, 问题好像出在这个地方,最后cluster_number 、FAT_entry都为0,导致出错,返回FX_FAT_READ_ERROR
SD卡的格式有什么特殊要求吗,单纯就用了官方的工具格式化了。
for (cluster_number = media_ptr -> fx_media_root_cluster_32;;)
{
status =_fx_utility_FAT_entry_read(media_ptr, cluster_number, &FAT_entry);
i++;
/* Determine if the read was successful.*/
if (status != FX_SUCCESS)
{
/* Build the "uninitialize" I/O driver request.*/
media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
media_ptr -> fx_media_driver_status = FX_IO_ERROR;
/* If trace is enabled, insert this event into the trace buffer.*/
FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Call the specified I/O driver with the uninitialize request.*/
(media_ptr -> fx_media_driver_entry) (media_ptr);
return(FX_FAT_READ_ERROR);
}
if ((cluster_number == FAT_entry) || (i > media_ptr -> fx_media_total_clusters))
{
/* Build the "uninitialize" I/O driver request.*/
media_ptr -> fx_media_driver_request = FX_DRIVER_UNINIT;
media_ptr -> fx_media_driver_status = FX_IO_ERROR;
/* If trace is enabled, insert this event into the trace buffer.*/
FX_TRACE_IN_LINE_INSERT(FX_TRACE_INTERNAL_IO_DRIVER_UNINIT, media_ptr, 0, 0, 0, FX_TRACE_INTERNAL_EVENTS, 0, 0)
/* Call the specified I/O driver with the uninitialize request.*/
(media_ptr -> fx_media_driver_entry) (media_ptr);
return(FX_FAT_READ_ERROR);
}
if (FAT_entry >= FX_RESERVED_1_32)
{
break;
}
cluster_number = FAT_entry;
}
考虑换个卡试试,使用SD卡联盟那个小软件格式化。另外容量超过32GB要使能exfat
还是不行,那么底层移植确实有点问题了。
解决了,应该是格式化的问题。
一开始,Diskgenius、SD Association的格式化工具,我只使用了快速格式化功能。无法被FileX识别。
之后用FileX自带的格式化程序fx_media_format,简单的格了几十k的空间,再次fx_media_open挂上去了,程序也能正常执行。
估计用格式化工具可能要先使用全盘格式化后再建文件系统,就不会出问题。 henji 发表于 2021-9-17 14:34
解决了,应该是格式化的问题。
一开始,Diskgenius、SD Association的格式化工具,我只使用了快速格式化功 ...
谢谢告知最终原因。 一般是接口没适配好,注意offet的计算。一些版本fileX代码里有bug,可能传一个无效的fx_media_driver_logical_sector参数到底层接口。这会导致IO问题。
给一段注释好的sample code (适配sdcard,我的框架里已经把sdcard抽象成了device):
/*
***********************************************************************
*Copyright (c) 2021 alex Yang
*
*@file fx_sdcard_driver.c
*@brief This file implements driver api needed by fileX
*@history
* Version Date Author Modification
* V1.0.0 Jul-4-2021 null.yang create file
*
*
***********************************************************************
*/
/**************************************************************************/
/**************************************************************************/
/** */
/** FileX Component */
/** */
/** SDCard Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files.*/
#include "sys_typedef.h"
#include "sys_errorno.h"
#include "sys_startup.h"
#include "sys_macro.h"
#include "time_base.h"
#include "device_core.h"
#include "fx_api.h"
/*
The SDCard driver relies on the fx_media_format call to be made prior to
the fx_media_open call. The following call will format the default
128MB SDCard drive, with a sector size of 512 bytes per sector.
fx_media_format(&sdcard_disk,
_fx_sdcard_driver, // Driver entry
sdcard_disk_memory, // SDCard disk memory pointer
media_memory, // Media buffer pointer
sizeof(media_memory), // Media buffer size
"MY_SDCARD", // Volume Name
1, // Number of FATs
128 * 1024, // Directory Entries
0, // Hidden sectors
256, // Total sectors
512, // Sector size
1, // Sectors per cluster
1, // Heads
1); // Sectors per track
*/
/* public api declearation */
VOID _fx_sdcard_driver(FX_MEDIA *media_ptr);
/* external api references */
UINT _fx_partition_offset_calculate(void *partition_sector, UINT partition, ULONG *partition_start, ULONG *partition_size);
/*
There are several useful/important pieces of information contained in
the media structure, some of which are supplied by FileX and others
are for the driver to setup. The following is a summary of the
necessary FX_MEDIA structure members:
FX_MEDIA Member Meaning
fx_media_driver_request FileX request type. Valid requests from
FileX are as follows:
FX_DRIVER_READ
FX_DRIVER_WRITE
FX_DRIVER_FLUSH
FX_DRIVER_ABORT
FX_DRIVER_INIT
FX_DRIVER_BOOT_READ
FX_DRIVER_RELEASE_SECTORS
FX_DRIVER_BOOT_WRITE
FX_DRIVER_UNINIT
fx_media_driver_status This value is RETURNED by the driver.
If the operation is successful, this
field should be set to FX_SUCCESS for
before returning. Otherwise, if an
error occurred, this field should be
set to FX_IO_ERROR.
fx_media_driver_buffer Pointer to buffer to read or write
sector data. This is supplied by
FileX.
fx_media_driver_logical_sector Logical sector FileX is requesting.
fx_media_driver_sectors Number of sectors FileX is requesting.
The following is a summary of the optional FX_MEDIA structure members:
FX_MEDIA Member Meaning
fx_media_driver_info Pointer to any additional information
or memory. This is optional for the
driver use and is setup from the
fx_media_open call. The RAM disk uses
this pointer for the RAM disk memory
itself.
fx_media_driver_write_protect The DRIVER sets this to FX_TRUE when
media is write protected. This is
typically done in initialization,
but can be done anytime.
fx_media_driver_free_sector_updateThe DRIVER sets this to FX_TRUE when
it needs to know when clusters are
released. This is important for FLASH
wear-leveling drivers.
fx_media_driver_system_write FileX sets this flag to FX_TRUE if the
sector being written is a system sector,
e.g., a boot, FAT, or directory sector.
The driver may choose to use this to
initiate error recovery logic for greater
fault tolerance.
fx_media_driver_data_sector_read FileX sets this flag to FX_TRUE if the
sector(s) being read are file data sectors,
i.e., NOT system sectors.
fx_media_driver_sector_type FileX sets this variable to the specific
type of sector being read or written. The
following sector types are identified:
FX_UNKNOWN_SECTOR
FX_BOOT_SECTOR
FX_FAT_SECTOR
FX_DIRECTORY_SECTOR
FX_DATA_SECTOR
*/
VOID _fx_sdcard_driver(FX_MEDIA *media_ptr)
{
device_t *sdcard = (device_t *)media_ptr->fx_media_driver_info;
/* check driver info */
if (NULL == sdcard)
{
media_ptr->fx_media_driver_status = FX_NOT_AVAILABLE;
return;
}
/* mapping logical sectors and the physical geometry of the media */
media_ptr->fx_media_driver_physical_sector = (media_ptr->fx_media_driver_logical_sector %
media_ptr->fx_media_sectors_per_track) + 1;
/* media request handler */
switch (media_ptr->fx_media_driver_request)
{
case FX_DRIVER_READ:
{
/* Read from sectors and return data to caller */
uint32_t sdcard_start_sector = (uint32_t)media_ptr->fx_media_driver_logical_sector +
(uint32_t)media_ptr->fx_media_hidden_sectors;
uint32_t sdcard_read_cnt = (uint32_t)media_ptr->fx_media_driver_sectors;
uint8_t *sdcard_read_buffer= (uint8_t *)media_ptr->fx_media_driver_buffer;
/* break with err if sector_cnt equals 0 */
if (0 == sdcard_read_cnt)
{
/* break directly to return failed driver request */
break;
}
/* block device uses sector index rather than data address as offset */
if (sdcard_read_cnt != device_read(sdcard, sdcard_start_sector, &sdcard_read_buffer, sdcard_read_cnt))
{
break;
}
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_WRITE:
{
/* Write data from caller to the sectors */
uint32_t sdcard_start_sector = (uint32_t)media_ptr->fx_media_driver_logical_sector +
(uint32_t)media_ptr->fx_media_hidden_sectors;
uint32_t sdcard_write_cnt = (uint32_t)media_ptr->fx_media_driver_sectors;
uint8_t *sdcard_write_buffer = (uint8_t *)media_ptr->fx_media_driver_buffer;
/* break with err if sector_cnt equals 0 */
if (0 == sdcard_write_cnt)
{
/* break directly to return failed driver request */
break;
}
/* block device uses sector index rather than data address as offset */
if (sdcard_write_cnt != device_write(sdcard, sdcard_start_sector, &sdcard_write_buffer, sdcard_write_cnt))
{
break;
}
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_FLUSH:
{
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_ABORT:
{
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_INIT:
{
/* FLASH drivers are responsible for setting several fields in the
media structure, as follows:
media_ptr -> fx_media_driver_free_sector_update
media_ptr -> fx_media_driver_write_protect
The fx_media_driver_free_sector_update flag is used to instruct
FileX to inform the driver whenever sectors are not being used.
This is especially useful for FLASH managers so they don't have
maintain mapping for sectors no longer in use.
The fx_media_driver_write_protect flag can be set anytime by the
driver to indicate the media is not writable.
Write attempts are made when this flag is set are returned as errors */
/* Perform basic initialization here since the boot record is going
to be read subsequently and again for volume name requests */
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_UNINIT:
{
/* There is nothing to do in this case for the RAM driver
For actual devices some shutdown processing may be necessary */
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_BOOT_READ:
{
/* MBR locates in sector */
uint32_t sdcard_start_sector = (uint32_t)0u;
uint32_t sdcard_read_cnt = (uint32_t)1u;
uint32_t sdcard_partition_start = (uint32_t)0u;
uint32_t sdcard_partition_size= (uint32_t)0u;
uint8_t *sdcard_read_buffer = (uint8_t *)media_ptr->fx_media_driver_buffer;
/* check sector_type */
if (FX_BOOT_SECTOR != media_ptr->fx_media_driver_sector_type)
{
/* break directly to return failed driver request */
break;
}
/* block device uses sector index rather than data address as offset */
if (sdcard_read_cnt != device_read(sdcard, sdcard_start_sector, &sdcard_read_buffer, sdcard_read_cnt))
{
break;
}
/* calculate and check if sector is the actual boot sector */
if (_fx_partition_offset_calculate(media_ptr->fx_media_driver_buffer, 0, &sdcard_partition_start, &sdcard_partition_size))
{
break;
}
if (sdcard_partition_start)
{
if (sdcard_read_cnt != device_read(sdcard, sdcard_partition_start, &sdcard_read_buffer, sdcard_read_cnt))
{
break;
}
}
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_BOOT_WRITE:
{
/* MBR locates in sector */
uint32_t sdcard_start_sector = (uint32_t)media_ptr->fx_media_hidden_sectors;
uint32_t sdcard_write_cnt = (uint32_t)1u;
uint8_t *sdcard_write_buffer = (uint8_t *)media_ptr->fx_media_driver_buffer;
/* check sector_type */
if (FX_BOOT_SECTOR != media_ptr->fx_media_driver_sector_type)
{
/* break directly to return failed driver request */
break;
}
/* block device uses sector index rather than data address as offset */
if (sdcard_write_cnt != device_write(sdcard, sdcard_start_sector, &sdcard_write_buffer, sdcard_write_cnt))
{
break;
}
/* Return successful driver request */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
default:
{
/* Return invalid driver request */
media_ptr->fx_media_driver_status = FX_IO_ERROR;
break;
}
}
return;
}
eric2013 发表于 2021-9-17 08:57
考虑换个卡试试,使用SD卡联盟那个小软件格式化。另外容量超过32GB要使能exfat
还是不行,那么底层移植确 ...
硬汉大佬 有没有试过把sd卡格式化成ntfs或exfat,再通过fx_media_format()来格式化?我用stm32cubemx生成的stm32f407的filex代码必须要将卡格式化成fat32才能打开,格式化成其他文件系统再调用fx_media_format()来格式化将导致检测卡失败,而导致一直卡死在格式化 老鸟kkk 发表于 2021-10-10 10:29
硬汉大佬 有没有试过把sd卡格式化成ntfs或exfat,再通过fx_media_format()来格式化?我用stm32cubemx生成 ...
使用exfat要使能下,这个你使能了吧 eric2013 发表于 2021-10-10 11:09
使用exfat要使能下,这个你使能了吧
是想把已经格式化成exfat或ntfs的卡,调用fx_media_format()格式化成fat32,通过调试发现在调用格式化函数中检测卡状态失败:dizzy:
exfat使能已经打开了
页:
[1]