硬汉嵌入式论坛

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

整理了个适用于STM32F4的ThreadX FileX文件系统驱动

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115667
QQ
发表于 2021-2-23 08:21:42 | 显示全部楼层 |阅读模式

F4和H7都差不多。

  1. /**************************************************************************/
  2. /*                                                                        */
  3. /*       Partial Copyright (c) Microsoft Corporation. All rights reserved.*/
  4. /*                                                                        */
  5. /*       This software is licensed under the Microsoft Software License   */
  6. /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
  7. /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
  8. /*       and in the root directory of this software.                      */
  9. /*      Partial Copyright (c) STMicroelctronics 2020. All rights reserved */
  10. /**************************************************************************/

  11. /* Include necessary system files.  */
  12. #include "fx_stm32_sd_driver.h"
  13. #include "bsp.h"
  14. #include "tx_api.h"
  15. #include "fx_api.h"


  16. extern SD_HandleTypeDef uSdHandle;

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

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

  20. static TX_SEMAPHORE transfer_semaphore;

  21. static uint8_t is_initialized = 0;

  22. #define BSP_ERROR_NONE                    0
  23. #define BSP_ERROR_BUSY                   -3

  24. static int32_t check_sd_status()
  25. {
  26.     uint32_t start = tx_time_get();

  27.     while (tx_time_get() - start < DEFAULT_TIMEOUT)
  28.     {
  29.       if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
  30.       {
  31.         return BSP_ERROR_NONE;
  32.       }
  33.     }

  34.     return BSP_ERROR_BUSY;
  35. }

  36. /**
  37.   * @brief This function is the entry point to the STM32 SDIO disk driver.     */
  38. /*        It relies on the STM32 peripheral library from ST.
  39.   * @param None
  40.   * @retval None
  41.   */
  42. VOID  fx_stm32_sd_driver(FX_MEDIA *media_ptr)
  43. {
  44.     int32_t status;
  45.     ULONG       partition_start;
  46.     ULONG       partition_size;

  47. #if (FX_DRIVER_CALLS_BSP_SD_INIT == 0)
  48.     is_initialized = 1; /* the SD  was initialized by the application*/
  49. #endif
  50. //TX_INTERRUPT_SAVE_AREA
  51.    /* before performing any operation, check the status of the SDMMC */
  52.     if (is_initialized == 1)
  53.     {
  54.       if (check_sd_status() != BSP_ERROR_NONE)
  55.       {
  56.           media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  57.           return;
  58.       }
  59.     }

  60.     /* Process the driver request specified in the media control block.  */
  61.     switch(media_ptr->fx_media_driver_request)
  62.     {
  63.         case FX_DRIVER_INIT:
  64.         {
  65. #if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
  66.             /* Initialize the SD instance */
  67.             if (is_initialized == 0)
  68.             {
  69.                 status = BSP_SD_Init();

  70.                 if (status == BSP_ERROR_NONE)
  71.                 {
  72.                     is_initialized = 1;
  73. #endif
  74.                     /* create a binary semaphore to check the DMA transfer status */
  75.                     if (tx_semaphore_create(&transfer_semaphore, "sdmmc dma transfer semaphore", 0) != TX_SUCCESS)
  76.                     {
  77.                         media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  78.                     }
  79.                     else
  80.                     {
  81.                         media_ptr->fx_media_driver_status =  FX_SUCCESS;
  82.                     }
  83. #if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
  84.                 }
  85.                 else
  86.                 {
  87.                     media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  88.                 }
  89.             }
  90. #endif
  91.             break;
  92.         }

  93.         case FX_DRIVER_UNINIT:
  94.         {
  95.             tx_semaphore_delete(&transfer_semaphore);

  96. #if (FX_DRIVER_CALLS_BSP_SD_INIT == 1)
  97.             BSP_SD_DeInit();
  98.             is_initialized = 0;
  99. #endif
  100.             /* Successful driver request.  */
  101.            media_ptr->fx_media_driver_status = FX_SUCCESS;
  102.            break;
  103.         }

  104.         case FX_DRIVER_READ:
  105.         {
  106.             media_ptr->fx_media_driver_status = FX_IO_ERROR;
  107.             //TX_DISABLE /* disable interrupts */
  108.            if ((ULONG)(media_ptr->fx_media_driver_buffer) & 0x3)
  109.            {
  110.               if (sd_read_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
  111.                                 media_ptr->fx_media_driver_sectors, 1) == FX_SUCCESS)
  112.               {
  113.                   media_ptr->fx_media_driver_status = FX_SUCCESS;
  114.               }
  115.            }
  116.            else
  117.            {
  118.                if (sd_read_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
  119.                        media_ptr->fx_media_driver_sectors, 0) == FX_SUCCESS)
  120.                {
  121.                    media_ptr->fx_media_driver_status = FX_SUCCESS;
  122.                }
  123.            }
  124.            //TX_RESTORE /* restore interrupts */

  125.             break;
  126.         }

  127.         case FX_DRIVER_WRITE:
  128.         {
  129.             media_ptr->fx_media_driver_status = FX_IO_ERROR;
  130.             //TX_DISABLE /* disable interrupts */

  131.            if (sd_write_data(media_ptr, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
  132.                    media_ptr->fx_media_driver_sectors, 0) == FX_SUCCESS)
  133.            {
  134.                media_ptr->fx_media_driver_status = FX_SUCCESS;
  135.            }
  136.            
  137.            //TX_RESTORE /* restore interrupts */

  138.             break;
  139.         }

  140.         case FX_DRIVER_FLUSH:
  141.         {
  142.             /* Return driver success.  */
  143.            media_ptr->fx_media_driver_status =  FX_SUCCESS;
  144.             break;
  145.         }

  146.         case FX_DRIVER_ABORT:
  147.         {
  148.             /* Return driver success.  */
  149.            media_ptr->fx_media_driver_status =  FX_SUCCESS;
  150.             break;
  151.         }

  152.         case FX_DRIVER_BOOT_READ:
  153.         {

  154.             /* the boot sector is the sector 0 */
  155.             status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, 0, 1);

  156.             if (status != BSP_ERROR_NONE)
  157.             {
  158.                 media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  159.                 break;
  160.             }

  161.             if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) != TX_SUCCESS)
  162.             {
  163.                 media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  164.                 break;
  165.             }

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

  169.             partition_start =  0;

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

  172.             /* Check partition read error.  */
  173.             if (status)
  174.             {
  175.                 /* Unsuccessful driver request.  */
  176.                 media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
  177.                 return;
  178.             }

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

  182.                 if (check_sd_status() != BSP_ERROR_NONE)
  183.                 {
  184.                     media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  185.                     return;
  186.                 }

  187.                 /* Yes, now lets read the actual boot record.  */
  188.                 status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr -> fx_media_driver_buffer, partition_start , 1);

  189.                 /* Check status of SDIO Read.  */
  190.                 if (status != BSP_ERROR_NONE)
  191.                 {

  192.                     /* Unsuccessful driver request.  */
  193.                     media_ptr -> fx_media_driver_status =  FX_IO_ERROR;
  194.                     return;
  195.                 }

  196.                 /* Wait for Rx Transfer completion */
  197.                 if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) != TX_SUCCESS)
  198.                 {
  199.                     media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  200.                     break;
  201.                 }
  202.             }

  203.             /* Successful driver request.  */
  204.             media_ptr -> fx_media_driver_status =  FX_SUCCESS;
  205.             break;
  206.         }

  207.         case FX_DRIVER_BOOT_WRITE:
  208.         {
  209.             status = BSP_SD_WriteBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, 0, 1);
  210.             if (status == BSP_ERROR_NONE)
  211.             {
  212.                 if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
  213.                 {
  214.                     media_ptr->fx_media_driver_status =  FX_SUCCESS;
  215.                 }
  216.                 else
  217.                 {
  218.                     media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  219.                 }
  220.             }
  221.             break;
  222.         }

  223.         default:
  224.         {
  225.            media_ptr->fx_media_driver_status =  FX_IO_ERROR;
  226.             break;
  227.         }
  228.     }
  229. }

  230. /**
  231.   * @brief BSP Tx Transfer completed callbacks
  232.   * @param Instance the SD instance
  233.   * @retval None
  234.   */
  235. void BSP_SD_WriteCpltCallback()
  236. {
  237.     tx_semaphore_put(&transfer_semaphore);
  238. }

  239. /**
  240.   * @brief BSP Rx Transfer completed callbacks
  241.   * @param Instance the sd instance
  242.   * @retval None
  243.   */
  244. void BSP_SD_ReadCpltCallback()
  245. {
  246.     tx_semaphore_put(&transfer_semaphore);
  247. }

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

  256. static UINT sd_read_data(FX_MEDIA *media_ptr, ULONG start_sector, UINT num_sectors, UINT use_scratch_buffer)
  257. {
  258.     UINT status;
  259.    
  260.     status = BSP_SD_ReadBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, start_sector, num_sectors);

  261.     if (status == BSP_ERROR_NONE)
  262.     {
  263.         if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
  264.         {
  265.             status = FX_SUCCESS;
  266.         }
  267.         else
  268.         {
  269.             status =  FX_BUFFER_ERROR;
  270.         }
  271.     }

  272.     return status;
  273. }

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

  282. static UINT sd_write_data(FX_MEDIA *media_ptr, ULONG start_sector, UINT num_sectors, UINT use_scratch_buffer)
  283. {
  284.     UINT status;

  285.     status = BSP_SD_WriteBlocks_DMA((uint32_t*)media_ptr->fx_media_driver_buffer, start_sector, num_sectors);

  286.     if (status == BSP_ERROR_NONE)
  287.     {
  288.         if(tx_semaphore_get(&transfer_semaphore, DEFAULT_TIMEOUT) == TX_SUCCESS)
  289.         {
  290.             status = FX_SUCCESS;
  291.         }
  292.         else
  293.         {
  294.             status = FX_IO_ERROR;
  295.         }
  296.     }

  297.     return status;
  298. }

  299. void SDIO_IRQHandler(void)
  300. {
  301.         HAL_SD_IRQHandler(&uSdHandle);
  302. }

  303. void DMA2_Stream6_IRQHandler(void)
  304. {
  305.     HAL_DMA_IRQHandler(uSdHandle.hdmatx);
  306. }

  307. void DMA2_Stream3_IRQHandler(void)
  308. {
  309.     HAL_DMA_IRQHandler(uSdHandle.hdmarx);
  310. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-10 18:46 , Processed in 0.235217 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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