177 lines
3.6 KiB
C
177 lines
3.6 KiB
C
/*
|
|
* pico_osal.h
|
|
*
|
|
* Created on: December 2013
|
|
* Author: Maxime Vincent
|
|
* Description: OS Abstraction Layer between PicoTCP and FreeRTOS
|
|
*
|
|
*/
|
|
/* FreeRTOS includes */
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "semphr.h"
|
|
#include "portmacro.h"
|
|
|
|
|
|
/* PicoTCP includes */
|
|
#include "pico_defines.h"
|
|
#include "pico_config.h"
|
|
#include "pico_osal.h"
|
|
|
|
#define osal_dbg(...)
|
|
//#define osal_dbg(...) printf(__VA_ARGS__)
|
|
|
|
/*****************************************************************************
|
|
* Public functions
|
|
****************************************************************************/
|
|
|
|
struct osal_mutex {
|
|
void * mutex;
|
|
uint8_t idx; /* only to keep track of the amount/idx, no real function .. */
|
|
};
|
|
static uint8_t mtx_number = 0;
|
|
|
|
|
|
/* ============= */
|
|
/* == SIGNALS == */
|
|
/* ============= */
|
|
|
|
void * pico_signal_init(void)
|
|
{
|
|
struct osal_mutex *signal;
|
|
signal = pico_zalloc(sizeof(struct osal_mutex));
|
|
osal_dbg("mi: %p for %p\n", signal, __builtin_return_address(0));
|
|
if (!signal)
|
|
return NULL;
|
|
signal->mutex= xSemaphoreCreateBinary();
|
|
signal->idx = mtx_number++;
|
|
return signal;
|
|
}
|
|
|
|
void pico_signal_deinit(void * signal)
|
|
{
|
|
struct osal_mutex * mtx = signal;
|
|
vSemaphoreDelete(mtx->mutex);
|
|
pico_free(signal);
|
|
}
|
|
|
|
void pico_signal_wait(void * signal)
|
|
{
|
|
pico_signal_wait_timeout(signal, (int)portMAX_DELAY);
|
|
}
|
|
|
|
int pico_signal_wait_timeout(void * signal, int timeout)
|
|
{
|
|
int retval = 0;
|
|
if(signal != NULL)
|
|
{
|
|
struct osal_mutex * mtx = signal;
|
|
if (timeout == portMAX_DELAY) {
|
|
while (xSemaphoreTake(mtx->mutex, portMAX_DELAY) == pdFALSE);
|
|
} else {
|
|
retval = xSemaphoreTake(mtx->mutex, timeout);
|
|
}
|
|
}
|
|
if (retval) {
|
|
return 0; /* Success */
|
|
} else {
|
|
return -1; /* Timeout */
|
|
}
|
|
}
|
|
|
|
void pico_signal_send(void * signal)
|
|
{
|
|
if(signal != NULL)
|
|
{
|
|
struct osal_mutex * mtx = signal;
|
|
xSemaphoreGive(mtx->mutex);
|
|
}
|
|
}
|
|
|
|
void pico_signal_send_ISR(void * signal)
|
|
{
|
|
if(signal != NULL)
|
|
{
|
|
struct osal_mutex * mtx = signal;
|
|
long task_switch_needed = 0;
|
|
xSemaphoreGiveFromISR(mtx->mutex, &task_switch_needed);
|
|
portYIELD_FROM_ISR(task_switch_needed);
|
|
}
|
|
}
|
|
|
|
/* ============= */
|
|
/* == MUTEXES == */
|
|
/* ============= */
|
|
|
|
|
|
void *pico_mutex_init(void)
|
|
{
|
|
struct osal_mutex *mutex;
|
|
mutex = pico_zalloc(sizeof(struct osal_mutex));
|
|
osal_dbg("mi: %p for %p\n", mutex, __builtin_return_address(0));
|
|
if (!mutex)
|
|
return NULL;
|
|
mutex->mutex = xSemaphoreCreateMutex();
|
|
mutex->idx = mtx_number++;
|
|
return mutex;
|
|
}
|
|
|
|
void pico_mutex_deinit(void * mutex)
|
|
{
|
|
pico_signal_deinit(mutex);
|
|
}
|
|
|
|
int pico_mutex_lock_timeout(void * mutex, int timeout)
|
|
{
|
|
return pico_signal_wait_timeout(mutex, timeout);
|
|
}
|
|
|
|
void pico_mutex_lock(void * mutex)
|
|
{
|
|
pico_signal_wait_timeout(mutex, (int)portMAX_DELAY);
|
|
}
|
|
|
|
void pico_mutex_unlock(void * mutex)
|
|
{
|
|
pico_signal_send(mutex);
|
|
}
|
|
|
|
void pico_mutex_unlock_ISR(void * mutex)
|
|
{
|
|
pico_signal_send_ISR(mutex);
|
|
}
|
|
|
|
|
|
/* ============= */
|
|
/* == THREADS == */
|
|
/* ============= */
|
|
static char thread_name[4] = "T";
|
|
static int thread_n = 0;
|
|
|
|
pico_thread_t pico_thread_create(pico_thread_fn thread, void *arg, int stack_size, int prio)
|
|
{
|
|
pico_thread_t t = PICO_ZALLOC(sizeof(TaskHandle_t));
|
|
if (!t)
|
|
return NULL;
|
|
thread_name[2] = (thread_n++) % 10;
|
|
thread_name[3] = 0;
|
|
xTaskCreate((TaskFunction_t)thread, thread_name, stack_size, arg, prio, t);
|
|
return t;
|
|
}
|
|
|
|
void pico_thread_destroy(pico_thread_t t)
|
|
{
|
|
vTaskDelete((TaskHandle_t)t);
|
|
PICO_FREE(t);
|
|
}
|
|
|
|
void pico_msleep(int ms)
|
|
{
|
|
vTaskDelay(ms);
|
|
}
|
|
|
|
void pico_threads_schedule(void)
|
|
{
|
|
vTaskStartScheduler();
|
|
}
|