forked from tass-belgium/picotcp-bsd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
pico_osal_freertos.c
176 lines (149 loc) · 3.65 KB
/
pico_osal_freertos.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
* 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();
}