Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lwip / freertos / sys_arch.c
1 /*
2  *    Copyright (c) 2020 Project CHIP Authors
3  *    Copyright (c) 2018-2019 Google LLC.
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /*
19  *
20  *    Description:
21  *      LwIP sys_arch definitions for use with FreeRTOS.
22  *
23  */
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "FreeRTOS.h"
29 #include "queue.h"
30 #include "semphr.h"
31 #include "task.h"
32
33 #include "arch/sys_arch.h"
34 #include "lwip/debug.h"
35 #include "lwip/def.h"
36 #include "lwip/mem.h"
37 #include "lwip/opt.h"
38 #include "lwip/stats.h"
39 #include "lwip/sys.h"
40
41 #ifndef LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
42 #define LWIP_FREERTOS_USE_STATIC_TCPIP_TASK configSUPPORT_STATIC_ALLOCATION
43 #endif
44
45 #ifndef LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
46 #define LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE configSUPPORT_STATIC_ALLOCATION
47 #endif
48
49 #if LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
50 static StaticTask_t gTCPIPTask;
51 static StackType_t gTCPIPTaskStack[TCPIP_THREAD_STACKSIZE / sizeof(StackType_t)];
52 #endif
53
54 #if LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
55 static StaticQueue_t gTCPIPMsgQueue;
56 static uint8_t gTCPIPMsgQueueStorage[SYS_MESG_QUEUE_LENGTH * sizeof(void *)];
57 #endif
58
59 static inline u32_t TicksToMS(TickType_t ticks)
60 {
61     return (ticks * 1000) / configTICK_RATE_HZ;
62 }
63
64 void sys_init(void)
65 {
66     // nothing to do.
67 }
68
69 err_t sys_sem_new(sys_sem_t * sem, u8_t count)
70 {
71     *sem = xSemaphoreCreateBinary();
72     if (*sem != NULL)
73     {
74         if (count != 0)
75         {
76             xSemaphoreGive(*sem);
77         }
78         SYS_STATS_INC_USED(sem);
79         return ERR_OK;
80     }
81     else
82     {
83         SYS_STATS_INC(sem.err);
84         return ERR_MEM;
85     }
86 }
87
88 void sys_sem_free(sys_sem_t * sem)
89 {
90     vSemaphoreDelete(*sem);
91     SYS_STATS_DEC(sem);
92 }
93
94 void sys_sem_signal(sys_sem_t * sem)
95 {
96     xSemaphoreGive(*sem);
97 }
98
99 u32_t sys_arch_sem_wait(sys_sem_t * sem, u32_t timeout)
100 {
101     TickType_t timeoutTicks, startTime;
102     BaseType_t res;
103
104     if (timeout == 0)
105         timeoutTicks = portMAX_DELAY;
106     else
107         timeoutTicks = pdMS_TO_TICKS(timeout);
108
109     startTime = xTaskGetTickCount();
110
111     do
112     {
113         res = xSemaphoreTake(*sem, timeoutTicks);
114     } while (res != pdTRUE && timeout == 0);
115
116     if (res == pdTRUE)
117     {
118         u32_t elapsedTime = TicksToMS(xTaskGetTickCount() - startTime);
119         if (elapsedTime == 0)
120             elapsedTime = 1;
121         return elapsedTime;
122     }
123     else
124         return SYS_ARCH_TIMEOUT;
125 }
126
127 err_t sys_mutex_new(sys_mutex_t * mutex)
128 {
129     *mutex = xSemaphoreCreateMutex();
130     if (*mutex != NULL)
131     {
132         xSemaphoreGive(*mutex);
133         SYS_STATS_INC_USED(mutex);
134         return ERR_OK;
135     }
136     else
137     {
138         SYS_STATS_INC(mutex.err);
139         return ERR_MEM;
140     }
141 }
142
143 void sys_mutex_free(sys_mutex_t * mutex)
144 {
145     vSemaphoreDelete(*mutex);
146     SYS_STATS_DEC(mutex);
147 }
148
149 void sys_mutex_lock(sys_mutex_t * mutex)
150 {
151     xSemaphoreTake(*mutex, portMAX_DELAY);
152 }
153
154 void sys_mutex_unlock(sys_mutex_t * mutex)
155 {
156     xSemaphoreGive(*mutex);
157 }
158
159 err_t sys_mbox_new(sys_mbox_t * mbox, int size)
160 {
161     if (size != SYS_MESG_QUEUE_LENGTH)
162     {
163         SYS_STATS_INC(mbox.err);
164         return ERR_MEM;
165     }
166
167 #if LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
168     *mbox = xQueueCreateStatic((UBaseType_t) size, (UBaseType_t) sizeof(void *), gTCPIPMsgQueueStorage, &gTCPIPMsgQueue);
169 #else
170     *mbox = xQueueCreate((UBaseType_t) size, (UBaseType_t) sizeof(void *));
171 #endif
172     if (*mbox != NULL)
173     {
174         SYS_STATS_INC_USED(mbox);
175         return ERR_OK;
176     }
177     else
178     {
179         SYS_STATS_INC(mbox.err);
180         return ERR_MEM;
181     }
182 }
183
184 void sys_mbox_free(sys_mbox_t * mbox)
185 {
186     vQueueDelete(*mbox);
187 }
188
189 void sys_mbox_post(sys_mbox_t * mbox, void * msg)
190 {
191     BaseType_t res;
192     res = xQueueSendToBack(*mbox, &msg, pdMS_TO_TICKS(SYS_POST_BLOCK_TIME_MS));
193     LWIP_ASSERT("Error posting to LwIP mbox", res == pdTRUE);
194 }
195
196 u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void ** msg, u32_t timeout)
197 {
198     TickType_t timeoutTicks, startTime;
199     BaseType_t res;
200     void * dummy;
201
202     if (msg == NULL)
203         msg = &dummy;
204
205     if (timeout == 0)
206         timeoutTicks = portMAX_DELAY;
207     else
208         timeoutTicks = pdMS_TO_TICKS(timeout);
209
210     startTime = xTaskGetTickCount();
211
212     do
213     {
214         res = xQueueReceive(*mbox, (void *) msg, timeoutTicks);
215     } while (res != pdTRUE && timeout == 0);
216
217     if (res == pdTRUE)
218     {
219         u32_t elapsedTime = TicksToMS(xTaskGetTickCount() - startTime);
220         if (elapsedTime == 0)
221             elapsedTime = 1;
222         return elapsedTime;
223     }
224     else
225     {
226         *msg = NULL;
227         return SYS_ARCH_TIMEOUT;
228     }
229 }
230
231 u32_t sys_arch_mbox_tryfetch(sys_mbox_t * mbox, void ** msg)
232 {
233     BaseType_t res;
234     void * dummy;
235
236     if (msg == NULL)
237         msg = &dummy;
238
239     res = xQueueReceive(*mbox, (void *) msg, 0);
240
241     return (res == pdTRUE) ? 0 : SYS_MBOX_EMPTY;
242 }
243
244 err_t sys_mbox_trypost(sys_mbox_t * mbox, void * msg)
245 {
246     BaseType_t res;
247
248     res = xQueueSendToBack(*mbox, &msg, 0);
249
250     if (res == pdTRUE)
251         return ERR_OK;
252     else
253     {
254         SYS_STATS_INC(mbox.err);
255         return ERR_MEM;
256     }
257 }
258
259 sys_thread_t sys_thread_new(const char * name, lwip_thread_fn thread, void * arg, int stacksize, int prio)
260 {
261     TaskHandle_t taskH;
262     const unsigned short stacksizeWords = (unsigned short) (stacksize / sizeof(StackType_t));
263
264     if (strcmp(name, TCPIP_THREAD_NAME) != 0 || stacksize != TCPIP_THREAD_STACKSIZE)
265         return NULL;
266
267 #if LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
268     taskH = xTaskCreateStatic(thread, name, stacksizeWords, arg, (UBaseType_t) prio, gTCPIPTaskStack, &gTCPIPTask);
269 #else  // LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
270     if (xTaskCreate(thread, name, stacksizeWords, arg, (UBaseType_t) prio, &taskH) != pdPASS)
271         taskH = NULL;
272 #endif // LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
273
274     return taskH;
275 }
276
277 err_t sys_thread_finish(sys_thread_t t)
278 {
279 #if INCLUDE_vTaskDelete
280     TaskHandle_t taskH = (TaskHandle_t) t;
281     vTaskDelete(taskH);
282 #endif
283     return ERR_OK;
284 }
285
286 u32_t sys_now(void)
287 {
288     return TicksToMS(xTaskGetTickCount());
289 }
290
291 sys_prot_t sys_arch_protect(void)
292 {
293     return taskENTER_CRITICAL_FROM_ISR();
294 }
295
296 void sys_arch_unprotect(sys_prot_t pval)
297 {
298     taskEXIT_CRITICAL_FROM_ISR(pval);
299 }