mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-31 07:28:37 -04:00
Add the Labs projects provided in the V10.2.1_191129 zip file.
This commit is contained in:
parent
46e5937529
commit
e5708b38e9
801 changed files with 356576 additions and 0 deletions
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* FreeRTOS+FAT build 191128 - Note: FreeRTOS+FAT is still in the lab!
|
||||
* Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Authors include James Walmsley, Hein Tibosch and Richard Barry
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* https://www.FreeRTOS.org
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Scheduler include files. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "ff_headers.h"
|
||||
#include "event_groups.h"
|
||||
|
||||
|
||||
/* Scheduler include files. */
|
||||
#ifdef __WIN32__
|
||||
#include "MyMalloc.h"
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "tcpLogging.h"
|
||||
#endif
|
||||
|
||||
#include "logbuf.h"
|
||||
#include <string.h>
|
||||
#include "bitops.h"
|
||||
#if USE_SOFT_WDT
|
||||
#include "softWdt.h"
|
||||
#endif
|
||||
|
||||
#include "thread_mutex.h"
|
||||
|
||||
#include "event_groups.h"
|
||||
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
#include "eventLogging.h"
|
||||
#endif
|
||||
|
||||
/* There are two areas which are protected with a semaphore:
|
||||
Directories and the FAT area.
|
||||
The masks below are used when calling Group Event functions. */
|
||||
#define FF_FAT_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_FAT_LOCK )
|
||||
#define FF_DIR_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_DIR_LOCK )
|
||||
|
||||
/* This is not a real lock: it is a bit (or semaphore) will will be given
|
||||
each time when a sector buffer is released. */
|
||||
#define FF_BUF_LOCK_EVENT_BITS ( ( const EventBits_t ) FF_BUF_LOCK )
|
||||
|
||||
extern void myTaskDelay (unsigned aTime);
|
||||
|
||||
static char cMutexWasCreated = 0;
|
||||
static pthread_mutex_t xFATMutex;
|
||||
|
||||
static void vCreateFATMutex ()
|
||||
{
|
||||
cMutexWasCreated = 1;
|
||||
pthread_mutex_init ("FreeRTOS+FAT", &xFATMutex, 0);
|
||||
}
|
||||
|
||||
BaseType_t FF_HasSemaphore (void *pxSemaphore)
|
||||
{
|
||||
// Return pdTRUE if the calling task owns the semaphore
|
||||
if (!cMutexWasCreated) vCreateFATMutex ();
|
||||
return pthread_has_mutex (&xFATMutex);
|
||||
}
|
||||
|
||||
|
||||
BaseType_t FF_SemaphoreTaken (void *pxSemaphore)
|
||||
{
|
||||
// Return pdTRUE if the calling task owns the semaphore
|
||||
if (!cMutexWasCreated) vCreateFATMutex ();
|
||||
return pthread_mutex_islocked (&xFATMutex);
|
||||
}
|
||||
|
||||
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
static char mutex_owner[32];
|
||||
#endif
|
||||
|
||||
BaseType_t FF_TrySemaphore( void *pxSemaphore, uint32_t ulTime_ms)
|
||||
{
|
||||
BaseType_t rc;
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
{
|
||||
eventLogAdd("Pend_%s\n", pcName);
|
||||
}
|
||||
#endif /* FF_DO_TRACE_SEMAPHORE */
|
||||
if (!cMutexWasCreated) vCreateFATMutex ();
|
||||
rc = pthread_mutex_lock (&xFATMutex, ulTime_ms);
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
if (rc > 0) {
|
||||
if(mutex_owner[0] != 0) {
|
||||
logPrintf("Pend Try: %s overruled\n", mutex_owner);
|
||||
}
|
||||
snprintf(mutex_owner, sizeof mutex_owner, pcName);
|
||||
}
|
||||
#endif /* FF_DO_TRACE_SEMAPHORE */
|
||||
return rc;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_PendSemaphore( void *pxSemaphore )
|
||||
{
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
{
|
||||
eventLogAdd("Pend_%s\n", pcName);
|
||||
}
|
||||
#endif /* FF_DO_TRACE_SEMAPHORE */
|
||||
|
||||
if (!cMutexWasCreated) vCreateFATMutex ();
|
||||
pthread_mutex_lock (&xFATMutex, 120000);
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
{
|
||||
if(mutex_owner[0] != 0) {
|
||||
logPrintf("Pend Enter: %s overruled by %s\n", mutex_owner, pcName);
|
||||
}
|
||||
snprintf(mutex_owner, sizeof mutex_owner, pcName);
|
||||
}
|
||||
#endif /* FF_DO_TRACE_SEMAPHORE */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_ReleaseSemaphore( void *pxSemaphore )
|
||||
{
|
||||
#if( FF_DO_TRACE_SEMAPHORE != 0 )
|
||||
{
|
||||
if(strcmp (pcName, mutex_owner) != 0) {
|
||||
// FF_GetBuffer2 != FF_GetBuffer
|
||||
logPrintf("Pend Exit: %s owned by %s\n", pcName, mutex_owner);
|
||||
}
|
||||
eventLogAdd("Exit_%s\n", pcName);
|
||||
mutex_owner[0] = '\0';
|
||||
}
|
||||
#endif /* FF_DO_TRACE_SEMAPHORE */
|
||||
|
||||
if (cMutexWasCreated) {
|
||||
pthread_mutex_unlock (&xFATMutex);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_Sleep( uint32_t ulTime_ms )
|
||||
{
|
||||
myTaskDelay (ulTime_ms);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t FF_CreateEvents( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
BaseType_t xResult;
|
||||
|
||||
pxIOManager->xEventGroup = xEventGroupCreate();
|
||||
if( pxIOManager->xEventGroup != NULL )
|
||||
{
|
||||
xEventGroupSetBits( pxIOManager->xEventGroup,
|
||||
FF_FAT_LOCK_EVENT_BITS | FF_DIR_LOCK_EVENT_BITS | FF_BUF_LOCK_EVENT_BITS );
|
||||
xResult = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xResult = pdFALSE;
|
||||
}
|
||||
|
||||
return xResult;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_LockDirectory( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
EventBits_t xBits;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Called when a task want to make changes to a directory.
|
||||
First it waits for the desired bit to come high. */
|
||||
xEventGroupWaitBits( pxIOManager->xEventGroup,
|
||||
FF_DIR_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
|
||||
( EventBits_t )0, /* xClearOnExit */
|
||||
pdFALSE, /* xWaitForAllBits n.a. */
|
||||
pdMS_TO_TICKS( 10000UL ) );
|
||||
|
||||
/* The next operation will only succeed for 1 task at a time,
|
||||
because it is an atomary test & set operation: */
|
||||
xBits = xEventGroupClearBits( pxIOManager->xEventGroup, FF_DIR_LOCK_EVENT_BITS );
|
||||
|
||||
if( ( xBits & FF_DIR_LOCK_EVENT_BITS ) != 0 )
|
||||
{
|
||||
/* This task has cleared the desired bit.
|
||||
It now 'owns' the resource. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_UnlockDirectory( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
configASSERT( ( xEventGroupGetBits( pxIOManager->xEventGroup ) & FF_DIR_LOCK_EVENT_BITS ) == 0 );
|
||||
xEventGroupSetBits( pxIOManager->xEventGroup, FF_DIR_LOCK_EVENT_BITS );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
int FF_Has_Lock( FF_IOManager_t *pxIOManager, uint32_t aBits )
|
||||
{
|
||||
int iReturn;
|
||||
|
||||
void *handle = xTaskGetCurrentTaskHandle();
|
||||
if( ( aBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
|
||||
{
|
||||
if( ( pxIOManager->pvFATLockHandle != NULL ) && ( pxIOManager->pvFATLockHandle == handle ) )
|
||||
{
|
||||
iReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
iReturn = pdFALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iReturn = pdFALSE;
|
||||
}
|
||||
return iReturn;
|
||||
}
|
||||
|
||||
void FF_Assert_Lock( FF_IOManager_t *pxIOManager, uint32_t aBits )
|
||||
{
|
||||
void *handle = xTaskGetCurrentTaskHandle();
|
||||
|
||||
if( ( aBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
|
||||
{
|
||||
configASSERT( pxIOManager->pvFATLockHandle != NULL && pxIOManager->pvFATLockHandle == handle );
|
||||
|
||||
/* In case configASSERT() is not defined. */
|
||||
( void ) pxIOManager;
|
||||
( void ) handle;
|
||||
}
|
||||
}
|
||||
|
||||
void FF_LockFAT( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
EventBits_t xBits;
|
||||
|
||||
configASSERT( FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE );
|
||||
if (FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) != pdFALSE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Called when a task want to make changes to the FAT area.
|
||||
First it waits for the desired bit to come high. */
|
||||
xEventGroupWaitBits( pxIOManager->xEventGroup,
|
||||
FF_FAT_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
|
||||
( EventBits_t )0, /* xClearOnExit */
|
||||
pdFALSE, /* xWaitForAllBits n.a. */
|
||||
pdMS_TO_TICKS( 10000UL ) );
|
||||
|
||||
/* The next operation will only succeed for 1 task at a time,
|
||||
because it is an atomary test & set operation: */
|
||||
xBits = xEventGroupClearBits( pxIOManager->xEventGroup, FF_FAT_LOCK_EVENT_BITS );
|
||||
|
||||
if( ( xBits & FF_FAT_LOCK_EVENT_BITS ) != 0 )
|
||||
{
|
||||
/* This task has cleared the desired bit.
|
||||
It now 'owns' the resource. */
|
||||
pxIOManager->pvFATLockHandle = xTaskGetCurrentTaskHandle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_UnlockFAT( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
configASSERT( ( xEventGroupGetBits( pxIOManager->xEventGroup ) & FF_FAT_LOCK_EVENT_BITS ) == 0 );
|
||||
if (FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) != pdFALSE )
|
||||
{
|
||||
pxIOManager->pvFATLockHandle = NULL;
|
||||
xEventGroupSetBits( pxIOManager->xEventGroup, FF_FAT_LOCK_EVENT_BITS );
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_PRINTF("FF_UnlockFAT: wasn't locked by me\n");
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t FF_BufferWait( FF_IOManager_t *pxIOManager, uint32_t xWaitMS )
|
||||
{
|
||||
EventBits_t xBits;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* This function is called when a task is waiting for a sector buffer
|
||||
to become available. */
|
||||
xBits = xEventGroupWaitBits( pxIOManager->xEventGroup,
|
||||
FF_BUF_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
|
||||
FF_BUF_LOCK_EVENT_BITS, /* xClearOnExit */
|
||||
pdFALSE, /* xWaitForAllBits n.a. */
|
||||
pdMS_TO_TICKS( xWaitMS ) );
|
||||
if( ( xBits & FF_BUF_LOCK_EVENT_BITS ) != 0 )
|
||||
{
|
||||
xReturn = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
xReturn = pdFALSE;
|
||||
}
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void FF_BufferProceed( FF_IOManager_t *pxIOManager )
|
||||
{
|
||||
/* Wake-up all tasks that are waiting for a sector buffer to become available. */
|
||||
xEventGroupSetBits( pxIOManager->xEventGroup, FF_BUF_LOCK_EVENT_BITS );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
Loading…
Add table
Add a link
Reference in a new issue