Zachary唷 发表于 2023-4-22 10:39:49

FreeRTOS+FatFs读写SD卡移植时需要做互斥吗

使用FreeRTOS系统+FatFS读写SD卡,需不需要做互斥啊?就像移植lwip的时候,有个接口文件sys_arch.c,FatFS有相关文件吗?

没有的话,两个线程同时操作SD卡,应该会出错吧。

eric2013 发表于 2023-4-23 14:48:11

FatFS有个专门的重入接口文件供使用。

Hzzz 发表于 2023-4-23 15:40:44

fatfs我记得有个文件,可以定义是否支持OS,然后里面可以添加平台相关的互斥机制呢。

Zachary唷 发表于 2023-4-25 10:59:33

哈,是哪个文件呀,我看了一圈没找到,大佬们,能告知一下吗?

eric2013 发表于 2023-4-25 15:15:54

Zachary唷 发表于 2023-4-25 10:59
哈,是哪个文件呀,我看了一圈没找到,大佬们,能告知一下吗?
syscall.c

/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs                         */
/* (C)ChaN, 2014                                                          */
/*   Portions COPYRIGHT 2017 STMicroelectronics                           */
/*   Portions Copyright (C) 2014, ChaN, all right reserved                */
/*------------------------------------------------------------------------*/

/**
******************************************************************************
*
* <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of other
*    contributors to this software may be used to endorse or promote products
*    derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
*    software, must execute solely and exclusively on microcontroller or
*    microprocessor devices manufactured by or for STMicroelectronics.
* 5. Redistribution and use of this software other than as permitted under
*    this license is void and will automatically terminate your rights under
*    this license.
*
* THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/



#include "../ff.h"


#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object                                        */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/synchronization object, such as semaphore and mutex. When a 0 is returned,
/the f_mount() function fails with FR_INT_ERR.
*/

int ff_cre_syncobj (        /* 1:Function succeeded, 0:Could not create the sync object */
        BYTE vol,                        /* Corresponding volume (logical drive number) */
        _SYNC_t *sobj                /* Pointer to return the created sync object */
)
{

    int ret;

    osSemaphoreDef(SEM);
    *sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
    ret = (*sobj != NULL);

    return ret;
}



/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object                                        */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/object that created with ff_cre_syncobj() function. When a 0 is returned,
/the f_mount() function fails with FR_INT_ERR.
*/

int ff_del_syncobj (        /* 1:Function succeeded, 0:Could not delete due to any error */
        _SYNC_t sobj                /* Sync object tied to the logical drive to be deleted */
)
{
    osSemaphoreDelete (sobj);
    return 1;
}



/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume                                     */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/When a 0 is returned, the file function fails with FR_TIMEOUT.
*/

int ff_req_grant (        /* 1:Got a grant to access the volume, 0:Could not get a grant */
        _SYNC_t sobj        /* Sync object to wait */
)
{
int ret = 0;

if(osSemaphoreWait(sobj, _FS_TIMEOUT) == osOK)
{
    ret = 1;
}

return ret;
}



/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume                                     */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/

void ff_rel_grant (
        _SYNC_t sobj        /* Sync object to be signaled */
)
{
osSemaphoreRelease(sobj);
}

#endif




#if _USE_LFN == 3        /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block                                                */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/

void* ff_memalloc (        /* Returns pointer to the allocated memory block */
        UINT msize                /* Number of bytes to allocate */
)
{
        return ff_malloc(msize);        /* Allocate a new memory block with POSIX API */
}


/*------------------------------------------------------------------------*/
/* Free a memory block                                                    */
/*------------------------------------------------------------------------*/

void ff_memfree (
        void* mblock        /* Pointer to the memory block to free */
)
{
        ff_free(mblock);        /* Discard the memory block with POSIX API */
}

#endif

Zachary唷 发表于 2023-4-26 10:23:58

eric2013 发表于 2023-4-25 15:15
syscall.c

/*--------------------------------------------------------------- ...

感谢大佬~:lol

Zachary唷 发表于 2023-5-5 14:50:23

你好,硬汉。我添加syscall.c后,卡在这个地方configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition )
{
BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired;
TimeOut_t xTimeOut;
Queue_t * const pxQueue = xQueue;

        configASSERT( pxQueue );
        configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
        configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
        #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
        {
                configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
        }
        #endif


        /*lint -save -e904 This function relaxes the coding standard somewhat to
        allow return statements within the function itself.This is done in the
        interest of execution time efficiency. */
        for( ;; )
        {
                taskENTER_CRITICAL();

Zachary唷 发表于 2023-5-5 15:40:37

大佬,我发现当#define_MIN_SS512 #define _MAX_SS512这两个不一样大时,find_volume函数中会调用if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK || SS(fs) < _MIN_SS || SS(fs) > _MAX_SS) return FR_DISK_ERR;这个函数会引起&fs变化。这是我的disk_ioctl代码,帮忙看看有问题吗?
#if _USE_IOCTL
DRESULT disk_ioctl (
    BYTE pdrv,                /* 物理编号 */
    BYTE cmd,                  /* 控制指令 */
    void *buff                /* 写入或者读取数据地址指针 */
)
{
    DRESULT status = RES_PARERR;
    DRESULT res;
    switch ( pdrv ) {
    case ATA:        /* SD CARD */
      switch(cmd)
          {
                  case CTRL_SYNC:
                                res = RES_OK;
                        break;       
                  case GET_SECTOR_SIZE:
                                *(DWORD*)buff = 512;
                        res = RES_OK;
                        break;       
                  case GET_BLOCK_SIZE:
                                *(WORD*)buff = sd_cardinfo.card_blocksize;
                        res = RES_OK;
                        break;       
                  case GET_SECTOR_COUNT:
                        *(DWORD*)buff = sd_cardinfo.card_capacity / sd_cardinfo.card_blocksize;
                        res = RES_OK;
                        break;
                  default:
                        res = RES_PARERR;
                        break;
          }
      status = res;
      break;

    case SPI_FLASH:
      switch ( cmd ) {
      /* 扇区数量:1024 x 4KB = 4096KB*/
      case GET_SECTOR_COUNT:
            *( DWORD * )buff = 1024;
            break;
      /* 扇区大小 4096B */
      case GET_SECTOR_SIZE :
            *( WORD * )buff = 4096;
            break;
      /* 同时擦除扇区个数 */
      case GET_BLOCK_SIZE :
            *( DWORD * )buff = 1;
            break;
      }
      status = RES_OK;
      break;

    default:
      status = RES_PARERR;
    }
    return status;
}
#endif

eric2013 发表于 2023-5-6 12:17:14

Zachary唷 发表于 2023-5-5 15:40
大佬,我发现当#define_MIN_SS512 #define _MAX_SS512这两个不一样大时,find_volume函数中会调用if...

此贴有个SD+SPI Flash二合一的,我就是设置的不同大小。

基于V5板子的SPI Flash文件系统+SPI Flash虚拟U盘例子下载(2015-11-03新升级)
https://www.armbbs.cn/forum.php?mod=viewthread&tid=14894&fromuid=58
(出处: 硬汉嵌入式论坛)

Zachary唷 发表于 2023-5-9 08:04:10

收到,感谢大佬:lol
页: [1]
查看完整版本: FreeRTOS+FatFs读写SD卡移植时需要做互斥吗