硬汉嵌入式论坛

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

[ThreadX全家桶] Fliex使用标准库修改硬汉哥综合模板驱动,fx_media_open时提示FX_MEDIA_INVALID (0x02)

[复制链接]

5

主题

39

回帖

54

积分

初级会员

积分
54
发表于 2023-3-19 00:08:56 | 显示全部楼层 |阅读模式
芯片使用F405RGT6,Freertos可以正常读取sd卡,使用filex移植时不成功,找来硬汉哥例程,使用标准库sd卡驱动修改后,fx_media_open打开媒体时返回0x02,微软官方服务说明是“FX_MEDIA_INVALID (0x02) 指定媒体的启动扇区已损坏或无效。 此外,此返回代码用于指示逻辑扇区缓存大小或 FAT 条目大小不是 2 的幂。”
实在是头大,代码粘贴如下:

[C] 纯文本查看 复制代码
/**************************************************************************/
/*                                                                        */
/*       Partial Copyright (c) Microsoft Corporation. All rights reserved.*/
/*                                                                        */
/*       This software is licensed under the Microsoft Software License   */
/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
/*       found in the LICENSE file at [url]https://aka.ms/AzureRTOS_EULA[/url]       */
/*       and in the root directory of this software.                      */
/*      Partial Copyright (c) STMicroelctronics 2020. All rights reserved */
/**************************************************************************/

/* Include necessary system files.  */
#include "fx_stm32_sd_driver.h"
#include "fx_api.h"
#include "sdio_sd.h"
#include "usart.h"

UINT  _fx_partition_offset_calculate(void  *partition_sector, UINT partition, ULONG *partition_start, ULONG *partition_size);

static UINT sd_read_data(FX_MEDIA *media_ptr, ULONG sector, UINT num_sectors, UINT use_scratch_buffer);
static UINT sd_write_data(FX_MEDIA *media_ptr, ULONG sector, UINT num_sectors, UINT use_scratch_buffer);

static TX_SEMAPHORE transfer_semaphore;

static uint8_t is_initialized = 0;


static int32_t check_sd_status()
{
    uint32_t start = tx_time_get();

    while (tx_time_get() - start < DEFAULT_TIMEOUT)
    {
      if (SD_GetStatus() == SD_TRANSFER_OK)
      {
        return 0;
      }
    }

    return 1;
}

/**
  * @brief This function is the entry point to the STM32 SDIO disk driver.     */
 /*        It relies on the STM32 peripheral library from ST.
  * @param None
  * @retval None
  */
VOID  fx_stm32_sd_driver(FX_MEDIA *media_ptr)
{
    int32_t status;
    ULONG       partition_start;
    ULONG       partition_size;

#if (FX_DRIVER_CALLS_BSP_SD_INIT == 0)
    is_initialized = 1; /* the SD  was initialized by the application*/
#endif
//TX_INTERRUPT_SAVE_AREA
   /* before performing any operation, check the status of the SDMMC */
    if (is_initialized == 1)
    {
      if (check_sd_status() != 0)
      {
          media_ptr->fx_media_driver_status =  FX_IO_ERROR;
          return;
      }
    }

    /* Process the driver request specified in the media control block.  */
    switch(media_ptr->fx_media_driver_request)
    {
        case FX_DRIVER_INIT:
        {
#if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
            /* Initialize the SD instance */
            if (is_initialized == 0)
            {
                status = SD_Init();

                if (status == 0)
                {
                    is_initialized = 1;
#endif
                    /* create a binary semaphore to check the DMA transfer status */
                    if (tx_semaphore_create(&transfer_semaphore, "sdmmc dma transfer semaphore", 0) != TX_SUCCESS)
                    {
                        media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                    }
                    else
                    {
                        media_ptr->fx_media_driver_status =  FX_SUCCESS;
                    }
#if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
                }
                else
                {
                    media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                }
            }
#endif
            break;
        }

        case FX_DRIVER_UNINIT:
        {
            tx_semaphore_delete(&transfer_semaphore);

#if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
            SD_DeInit();
            is_initialized = 0;
#endif
            /* Successful driver request.  */
           media_ptr->fx_media_driver_status = FX_SUCCESS;
           break;
        }

        case FX_DRIVER_READ:
        {
            media_ptr->fx_media_driver_status = FX_IO_ERROR;
            //TX_DISABLE /* disable interrupts */
           if ((ULONG)(media_ptr->fx_media_driver_buffer) & 0x3)
           {
              if (sd_read_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
                                media_ptr->fx_media_driver_sectors, 1) == FX_SUCCESS)
              {
                  media_ptr->fx_media_driver_status = FX_SUCCESS;
              }
           }
           else
           {
               if (sd_read_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
                       media_ptr->fx_media_driver_sectors, 0) == FX_SUCCESS)
               {
                   media_ptr->fx_media_driver_status = FX_SUCCESS;
               }
           }
           //TX_RESTORE /* restore interrupts */

            break;
        }

        case FX_DRIVER_WRITE:
        {
            media_ptr->fx_media_driver_status = FX_IO_ERROR;
            //TX_DISABLE /* disable interrupts */

           if (sd_write_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
                   media_ptr->fx_media_driver_sectors, 0) == FX_SUCCESS)
           {
               media_ptr->fx_media_driver_status = FX_SUCCESS;
           }
           
           //TX_RESTORE /* restore interrupts */

            break;
        }

        case FX_DRIVER_FLUSH:
        {
            /* Return driver success.  */
           media_ptr->fx_media_driver_status =  FX_SUCCESS;
            break;
        }

        case FX_DRIVER_ABORT:
        {
            /* Return driver success.  */
           media_ptr->fx_media_driver_status =  FX_SUCCESS;
            break;
        }

        case FX_DRIVER_BOOT_READ:
        {

            /* the boot sector is the sector 0 */
//            status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, 0, 1);
            
            status = SD_ReadMultiBlocks((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 512, 1);
//            status = SD_ReadBlock((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 1);
            status = SD_WaitReadOperation();
             while(SD_GetStatus() != SD_TRANSFER_OK);
            
            tx_semaphore_put(&transfer_semaphore);

            if (status != 0)
            {
                media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                break;
            }

            if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) != TX_SUCCESS)
            {
                media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                break;
            }

            /* Check if the sector 0 is the actual boot sector, otherwise calculate the offset into it.
            Please note that this should belong to higher level of MW to do this check and it is here
            as a temporary work solution */

            partition_start =  0;

            status =  _fx_partition_offset_calculate(media_ptr -> fx_media_driver_buffer, 0,
                                                                &partition_start, &partition_size);

            /* Check partition read error.  */
            if (status)
            {
                /* Unsuccessful driver request.  */
                media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
                return;
            }

            /* Now determine if there is a partition...   */
            if (partition_start)
            {

                if (check_sd_status() != 0)
                {
                    media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                    return;
                }

                /* Yes, now lets read the actual boot record.  */
//                status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr -> fx_media_driver_buffer, partition_start , 1);
                
                  status = SD_ReadMultiBlocks((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 512, 1);
//            status = SD_ReadBlock((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 1);
                status = SD_WaitReadOperation();
                    while(SD_GetStatus() != SD_TRANSFER_OK);
                
                tx_semaphore_put(&transfer_semaphore);

                /* Check status of SDIO Read.  */
                if (status != 0)
                {

                    /* Unsuccessful driver request.  */
                    media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
                    return;
                }

                /* Wait for Rx Transfer completion */
                if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) != TX_SUCCESS)
                {
                    media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                    break;
                }
            }

            /* Successful driver request.  */
            media_ptr -> fx_media_driver_status =  FX_SUCCESS;
            break;
        }

        case FX_DRIVER_BOOT_WRITE:
        {
//            status = BSP_SD_WriteBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, 0, 1);
            status = SD_WriteMultiBlocks((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 512, 1);
//            status = SD_WriteBlock((uint8_t *)media_ptr->fx_media_driver_buffer, 0, 1);
            status = SD_WaitReadOperation();
            while(SD_GetStatus() != SD_TRANSFER_OK);
            
            tx_semaphore_put(&transfer_semaphore);
            
            if (status == 0)
            {
                if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
                {
                    media_ptr->fx_media_driver_status =  FX_SUCCESS;
                }
                else
                {
                    media_ptr->fx_media_driver_status =  FX_IO_ERROR;
                }
            }
            break;
        }

        default:
        {
           media_ptr->fx_media_driver_status =  FX_IO_ERROR;
            break;
        }
    }
}

/**
  * @brief BSP Tx Transfer completed callbacks
  * @param Instance the SD instance
  * @retval None
  */
//void BSP_SD_WriteCpltCallback()
//{
//    tx_semaphore_put(&transfer_semaphore);
//}

///**
//  * @brief BSP Rx Transfer completed callbacks
//  * @param Instance the sd instance
//  * @retval None
//  */
//void BSP_SD_ReadCpltCallback()
//{
//    tx_semaphore_put(&transfer_semaphore);
//}

/**
  * @brief Read buffer using BSP SD API taking into account the scratch buffer
  * @param FX_MEDIA *media_ptr a pointer the main FileX structure
  * @param ULONG start_sector first sector to start reading from
  * @param UINT num_sectors number of sectors to be read
  * @param UINT use_scratch_buffer to enable scratch buffer usage or not.
  * @retval FX_SUCCESS on success FX_BUFFER_ERROR otherwise
  */

static UINT sd_read_data(FX_MEDIA *media_ptr, ULONG start_sector, UINT num_sectors, UINT use_scratch_buffer)
{
    UINT status;
   
    //status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, start_sector, num_sectors);

    status = SD_ReadMultiBlocks((uint8_t *)media_ptr->fx_media_driver_buffer, start_sector, 512, num_sectors);
    status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
    
    if (status == 0)
    {
        if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
        {
            status = FX_SUCCESS;
        }
        else
        {
            status =  FX_BUFFER_ERROR;
        }
    }
    
    tx_semaphore_put(&transfer_semaphore);
    return status;
}

/**
  * @brief write buffer using BSP SD API taking into account the scratch buffer
  * @param FX_MEDIA *media_ptr a pointer the main FileX structure
  * @param ULONG start_sector first sector to start writing from
  * @param UINT num_sectors number of sectors to be written
  * @param UINT use_scratch_buffer to enable scratch buffer usage or not.
  * @retval FX_SUCCESS on success FX_BUFFER_ERROR otherwise
  */

static UINT sd_write_data(FX_MEDIA *media_ptr, ULONG start_sector, UINT num_sectors, UINT use_scratch_buffer)
{
    UINT status;
    //BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
//    BSP_SD_WriteBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, start_sector, num_sectors);
    
    status = SD_WriteMultiBlocks((uint8_t *)media_ptr->fx_media_driver_buffer, start_sector, 512, num_sectors);
    status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);

    if (status == 0)
    {
        if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
        {
            status = FX_SUCCESS;
        }
        else
        {
            status = FX_IO_ERROR;
        }
    }
    tx_semaphore_put(&transfer_semaphore);

    return status;
}


回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115878
QQ
发表于 2023-3-19 10:49:40 | 显示全部楼层
调试下,这个函数status = SD_Init();正确进入没用
回复

使用道具 举报

5

主题

39

回帖

54

积分

初级会员

积分
54
 楼主| 发表于 2023-3-19 11:07:49 | 显示全部楼层
eric2013 发表于 2023-3-19 10:49
调试下,这个函数status = SD_Init();正确进入没用

进入了。也试过在外设初始化的时候SD_Init(),一样不行
回复

使用道具 举报

5

主题

39

回帖

54

积分

初级会员

积分
54
 楼主| 发表于 2023-3-19 11:25:12 | 显示全部楼层
本帖最后由 哲学家 于 2023-3-19 15:35 编辑
eric2013 发表于 2023-3-19 10:49
调试下,这个函数status = SD_Init();正确进入没用

我把工程传上来,硬汉哥抽空能帮看看嘛

ThreadX_F405RGT6+-+报错0x02.7z

2.29 MB, 下载次数: 2

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115878
QQ
发表于 2023-3-20 00:42:48 | 显示全部楼层
哲学家 发表于 2023-3-19 11:25
我把工程传上来,硬汉哥抽空能帮看看嘛

好的,今天有时间了我看下。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-24 21:05 , Processed in 0.254032 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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