FreeRTOS+FatFs读写SD卡移植时需要做互斥吗
使用FreeRTOS系统+FatFS读写SD卡,需不需要做互斥啊?就像移植lwip的时候,有个接口文件sys_arch.c,FatFS有相关文件吗?没有的话,两个线程同时操作SD卡,应该会出错吧。
FatFS有个专门的重入接口文件供使用。 fatfs我记得有个文件,可以定义是否支持OS,然后里面可以添加平台相关的互斥机制呢。 哈,是哪个文件呀,我看了一圈没找到,大佬们,能告知一下吗? 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
eric2013 发表于 2023-4-25 15:15
syscall.c
/*--------------------------------------------------------------- ...
感谢大佬~:lol 你好,硬汉。我添加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(); 大佬,我发现当#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
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
(出处: 硬汉嵌入式论坛)
收到,感谢大佬:lol
页:
[1]