henji 发表于 2021-9-16 10:45:07

fx_media_open 失败

调用fx_media_open出错返回状态 0x03 FX_FAT_READ_ERROR,
独立使用FileX,磁盘驱动是sdio SD卡,SD裸驱在fatfs文件系统上能正常使用。
SD卡预先使用SD formatter 格式化工具格式了。不知道怎么解决了...


henji 发表于 2021-9-16 17:29:21

在 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;
      }

eric2013 发表于 2021-9-17 08:57:06

考虑换个卡试试,使用SD卡联盟那个小软件格式化。另外容量超过32GB要使能exfat
还是不行,那么底层移植确实有点问题了。

henji 发表于 2021-9-17 14:34:37

解决了,应该是格式化的问题。
一开始,Diskgenius、SD Association的格式化工具,我只使用了快速格式化功能。无法被FileX识别。
之后用FileX自带的格式化程序fx_media_format,简单的格了几十k的空间,再次fx_media_open挂上去了,程序也能正常执行。
估计用格式化工具可能要先使用全盘格式化后再建文件系统,就不会出问题。

eric2013 发表于 2021-9-19 09:55:05

henji 发表于 2021-9-17 14:34
解决了,应该是格式化的问题。
一开始,Diskgenius、SD Association的格式化工具,我只使用了快速格式化功 ...

谢谢告知最终原因。

alexyzhov 发表于 2021-9-20 04:07:12

一般是接口没适配好,注意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;
}

老鸟kkk 发表于 2021-10-10 10:29:53

eric2013 发表于 2021-9-17 08:57
考虑换个卡试试,使用SD卡联盟那个小软件格式化。另外容量超过32GB要使能exfat
还是不行,那么底层移植确 ...

硬汉大佬 有没有试过把sd卡格式化成ntfs或exfat,再通过fx_media_format()来格式化?我用stm32cubemx生成的stm32f407的filex代码必须要将卡格式化成fat32才能打开,格式化成其他文件系统再调用fx_media_format()来格式化将导致检测卡失败,而导致一直卡死在格式化

eric2013 发表于 2021-10-10 11:09:17

老鸟kkk 发表于 2021-10-10 10:29
硬汉大佬 有没有试过把sd卡格式化成ntfs或exfat,再通过fx_media_format()来格式化?我用stm32cubemx生成 ...

使用exfat要使能下,这个你使能了吧

老鸟kkk 发表于 2021-10-10 11:47:20

eric2013 发表于 2021-10-10 11:09
使用exfat要使能下,这个你使能了吧

是想把已经格式化成exfat或ntfs的卡,调用fx_media_format()格式化成fat32,通过调试发现在调用格式化函数中检测卡状态失败:dizzy:

exfat使能已经打开了
页: [1]
查看完整版本: fx_media_open 失败