STM32+FatFS+FreeRTOS - потокобезопасная запись на Flash

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
AlexZavgorodniy
Родился
Сообщения: 10
Зарегистрирован: Пн июн 25, 2012 05:02:00

STM32+FatFS+FreeRTOS - потокобезопасная запись на Flash

Сообщение AlexZavgorodniy »

Доброго времени суток!

Требуется помощь знатоков) Пишу код для девайса под управлением FreeRTOS. На борту с СТМ32 присутсвует внешняя флеш-память, куда сохраняются настройки, пишется лог и т.д. Также поднят интерфейс mass storage.

Библиотеку FatFS от Cube выкорчевал с проекта и заменил свежей версией с сайта Chan'a

в одной задаче пытаюсь логировать данные, например так

Код: Выделить всё

void Task1 (void)
{
	...

	for (;;)
	{
		status  = f_open(&appFile, log_name, FA_OPEN_ALWAYS | FA_WRITE);
		status = f_write(&appFile, temp, strlen(temp), &bw);
		status = f_close(&appFile);
	}
	osDelay(1000);
}
В таком случае (почти всегда) данные на флешке становятся битыми. Есть предположение, что нормальной записи мешает использование Mass storage...

Попробовал файле "ffconf.h" включил реентерабельность для потокобезопасности

#define FF_FS_REENTRANT 1
#define FF_FS_TIMEOUT 1000
#define FF_SYNC_t osSemaphoreId_t

Дополнил файл "ffsystem.c":

Код: Выделить всё

/*------------------------------------------------------------------------*/
/* Sample Code of OS Dependent Functions for FatFs                        */
/* (C)ChaN, 2018                                                          */
/*------------------------------------------------------------------------*/


#include "ff.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"

#if FF_USE_LFN == 3	/* Dynamic memory allocation */

/*------------------------------------------------------------------------*/
/* Allocate a memory block                                                */
/*------------------------------------------------------------------------*/

void* ff_memalloc (	/* Returns pointer to the allocated memory block (null if not enough core) */
	UINT msize		/* Number of bytes to allocate */
)
{
	return 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 (nothing to do if null) */
)
{
	free(mblock);	/* Free the memory block with POSIX API */
}

#endif



#if FF_FS_REENTRANT	/* Mutal exclusion */

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

const osMutexDef_t Mutex[FF_VOLUMES];	/* Table of CMSIS-RTOS mutex */


int ff_cre_syncobj (	/* 1:Function succeeded, 0:Could not create the sync object */
	BYTE vol,			/* Corresponding volume (logical drive number) */
	FF_SYNC_t* sobj		/* Pointer to return the created sync object */
)
{
	/* CMSIS-RTOS */
//	*sobj = osMutexNew(&Mutex[vol]);
	*sobj = osSemaphoreNew(1, 1, NULL);
	return (int)(*sobj != NULL);
}


/*------------------------------------------------------------------------*/
/* 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 an error */
	FF_SYNC_t sobj		/* Sync object tied to the logical drive to be deleted */
)
{
	/* CMSIS-RTOS */
//	return (int)(osMutexDelete(sobj) == osOK);
	return (int)(osSemaphoreDelete (sobj)== osOK);
}


/*------------------------------------------------------------------------*/
/* 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 */
	FF_SYNC_t sobj	/* Sync object to wait */
)
{
	/* CMSIS-RTOS */
//	return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
	return (int)(osSemaphoreAcquire(sobj, FF_FS_TIMEOUT) == osOK);
}


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

void ff_rel_grant (
	FF_SYNC_t sobj	/* Sync object to be signaled */
)
{
	/* CMSIS-RTOS */
//	osMutexRelease(sobj);
	osSemaphoreRelease(sobj);
}

#endif

При таком способе отладчик отправляет далеко и надолго)
Безымянный.png
(41.45 КБ) 157 скачиваний
Как можно сделать так, чтобы данные на флэхе не страдали? Есть подсказки?
заранее спасибо за любой совет!
Реклама
AlexZavgorodniy
Родился
Сообщения: 10
Зарегистрирован: Пн июн 25, 2012 05:02:00

Re: STM32+FatFS+FreeRTOS - потокобезопасная запись на Flash

Сообщение AlexZavgorodniy »

Наконец-то победил. У меня изначально монтирование файловой системы выполнялось до инициализации и запуска планировщика ОС. Переместил функцию монтирования Fat именно в задачу (соостветсенно после запуска планировщика) и все встало на свои места.


проблема решена.
Реклама
Ответить

Вернуться в «ARM»