feat: add lab-rv32i-freertos-mutex card
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
#ifndef K11_HOST_FREERTOS_H
|
||||
#define K11_HOST_FREERTOS_H
|
||||
#include <stdint.h>
|
||||
typedef int32_t BaseType_t;
|
||||
typedef uint32_t UBaseType_t;
|
||||
typedef uint32_t TickType_t;
|
||||
typedef void * TaskHandle_t;
|
||||
struct MockSemaphore
|
||||
{
|
||||
BaseType_t locked;
|
||||
TaskHandle_t owner;
|
||||
};
|
||||
typedef struct MockSemaphore * SemaphoreHandle_t;
|
||||
typedef struct MockSemaphore StaticSemaphore_t;
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
#define pdFAIL ( ( BaseType_t ) 0 )
|
||||
#define pdPASS ( ( BaseType_t ) 1 )
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef K11_HOST_SEMPHR_H
|
||||
#define K11_HOST_SEMPHR_H
|
||||
#include "FreeRTOS.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t * );
|
||||
BaseType_t xSemaphoreTake( SemaphoreHandle_t, TickType_t );
|
||||
BaseType_t xSemaphoreGive( SemaphoreHandle_t );
|
||||
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t );
|
||||
void vSemaphoreDelete( SemaphoreHandle_t );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef K11_HOST_TASK_H
|
||||
#define K11_HOST_TASK_H
|
||||
#include "FreeRTOS.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
#include "freertos/mutex.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
unsigned token;
|
||||
unsigned takes;
|
||||
unsigned gives;
|
||||
unsigned deletes;
|
||||
TickType_t last_timeout;
|
||||
|
||||
uint32_t guarded_path( freertos::Mutex & mutex, uint32_t path )
|
||||
{
|
||||
freertos::LockGuard< freertos::Mutex > guard { mutex, 9U };
|
||||
assert( guard.owns_lock() );
|
||||
assert( mutex.owner() == &token );
|
||||
if( path == 0U ) return 10U;
|
||||
if( path == 1U ) return 20U;
|
||||
return 30U;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
extern "C" TaskHandle_t xTaskGetCurrentTaskHandle()
|
||||
{
|
||||
return &token;
|
||||
}
|
||||
extern "C" SemaphoreHandle_t xSemaphoreCreateMutexStatic(
|
||||
StaticSemaphore_t * storage )
|
||||
{
|
||||
*storage = MockSemaphore {};
|
||||
return storage;
|
||||
}
|
||||
extern "C" BaseType_t xSemaphoreTake( SemaphoreHandle_t mutex,
|
||||
TickType_t timeout )
|
||||
{
|
||||
++takes;
|
||||
last_timeout = timeout;
|
||||
if( mutex->locked != pdFALSE ) return pdFAIL;
|
||||
mutex->locked = pdTRUE;
|
||||
mutex->owner = xTaskGetCurrentTaskHandle();
|
||||
return pdPASS;
|
||||
}
|
||||
extern "C" BaseType_t xSemaphoreGive( SemaphoreHandle_t mutex )
|
||||
{
|
||||
if( mutex->locked == pdFALSE ||
|
||||
mutex->owner != xTaskGetCurrentTaskHandle() ) return pdFAIL;
|
||||
++gives;
|
||||
mutex->locked = pdFALSE;
|
||||
mutex->owner = nullptr;
|
||||
return pdPASS;
|
||||
}
|
||||
extern "C" TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t mutex )
|
||||
{
|
||||
return mutex->owner;
|
||||
}
|
||||
extern "C" void vSemaphoreDelete( SemaphoreHandle_t )
|
||||
{
|
||||
++deletes;
|
||||
}
|
||||
|
||||
static_assert( !std::is_copy_constructible< freertos::Mutex >::value );
|
||||
static_assert( !std::is_move_constructible<
|
||||
freertos::LockGuard< freertos::Mutex > >::value );
|
||||
|
||||
int main()
|
||||
{
|
||||
freertos::StaticMutexStorage storage {};
|
||||
{
|
||||
freertos::Mutex mutex { storage };
|
||||
assert( mutex.valid() && mutex.native_handle() == &storage.control );
|
||||
for( uint32_t path = 0U; path < 3U; ++path )
|
||||
{
|
||||
assert( guarded_path( mutex, path ) == 10U + path * 10U );
|
||||
assert( storage.control.locked == pdFALSE );
|
||||
}
|
||||
assert( takes == 3U && gives == 3U && last_timeout == 9U );
|
||||
|
||||
freertos::LockGuard< freertos::Mutex > outer { mutex, 0U };
|
||||
assert( outer.owns_lock() );
|
||||
freertos::LockGuard< freertos::Mutex > recursive_attempt { mutex, 0U };
|
||||
assert( !recursive_attempt.owns_lock() );
|
||||
}
|
||||
assert( gives == 4U && deletes == 1U );
|
||||
}
|
||||
Reference in New Issue
Block a user