2 * Copyright (c) 2020 Project CHIP Authors
3 * Copyright (c) 2018-2019 Google LLC.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * LwIP sys_arch definitions for use with FreeRTOS.
33 #include "arch/sys_arch.h"
34 #include "lwip/debug.h"
38 #include "lwip/stats.h"
41 #ifndef LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
42 #define LWIP_FREERTOS_USE_STATIC_TCPIP_TASK configSUPPORT_STATIC_ALLOCATION
45 #ifndef LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
46 #define LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE configSUPPORT_STATIC_ALLOCATION
49 #if LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
50 static StaticTask_t gTCPIPTask;
51 static StackType_t gTCPIPTaskStack[TCPIP_THREAD_STACKSIZE / sizeof(StackType_t)];
54 #if LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
55 static StaticQueue_t gTCPIPMsgQueue;
56 static uint8_t gTCPIPMsgQueueStorage[SYS_MESG_QUEUE_LENGTH * sizeof(void *)];
59 static inline u32_t TicksToMS(TickType_t ticks)
61 return (ticks * 1000) / configTICK_RATE_HZ;
69 err_t sys_sem_new(sys_sem_t * sem, u8_t count)
71 *sem = xSemaphoreCreateBinary();
78 SYS_STATS_INC_USED(sem);
83 SYS_STATS_INC(sem.err);
88 void sys_sem_free(sys_sem_t * sem)
90 vSemaphoreDelete(*sem);
94 void sys_sem_signal(sys_sem_t * sem)
99 u32_t sys_arch_sem_wait(sys_sem_t * sem, u32_t timeout)
101 TickType_t timeoutTicks, startTime;
105 timeoutTicks = portMAX_DELAY;
107 timeoutTicks = pdMS_TO_TICKS(timeout);
109 startTime = xTaskGetTickCount();
113 res = xSemaphoreTake(*sem, timeoutTicks);
114 } while (res != pdTRUE && timeout == 0);
118 u32_t elapsedTime = TicksToMS(xTaskGetTickCount() - startTime);
119 if (elapsedTime == 0)
124 return SYS_ARCH_TIMEOUT;
127 err_t sys_mutex_new(sys_mutex_t * mutex)
129 *mutex = xSemaphoreCreateMutex();
132 xSemaphoreGive(*mutex);
133 SYS_STATS_INC_USED(mutex);
138 SYS_STATS_INC(mutex.err);
143 void sys_mutex_free(sys_mutex_t * mutex)
145 vSemaphoreDelete(*mutex);
146 SYS_STATS_DEC(mutex);
149 void sys_mutex_lock(sys_mutex_t * mutex)
151 xSemaphoreTake(*mutex, portMAX_DELAY);
154 void sys_mutex_unlock(sys_mutex_t * mutex)
156 xSemaphoreGive(*mutex);
159 err_t sys_mbox_new(sys_mbox_t * mbox, int size)
161 if (size != SYS_MESG_QUEUE_LENGTH)
163 SYS_STATS_INC(mbox.err);
167 #if LWIP_FREERTOS_USE_STATIC_TCPIP_QUEUE
168 *mbox = xQueueCreateStatic((UBaseType_t) size, (UBaseType_t) sizeof(void *), gTCPIPMsgQueueStorage, &gTCPIPMsgQueue);
170 *mbox = xQueueCreate((UBaseType_t) size, (UBaseType_t) sizeof(void *));
174 SYS_STATS_INC_USED(mbox);
179 SYS_STATS_INC(mbox.err);
184 void sys_mbox_free(sys_mbox_t * mbox)
189 void sys_mbox_post(sys_mbox_t * mbox, void * msg)
192 res = xQueueSendToBack(*mbox, &msg, pdMS_TO_TICKS(SYS_POST_BLOCK_TIME_MS));
193 LWIP_ASSERT("Error posting to LwIP mbox", res == pdTRUE);
196 u32_t sys_arch_mbox_fetch(sys_mbox_t * mbox, void ** msg, u32_t timeout)
198 TickType_t timeoutTicks, startTime;
206 timeoutTicks = portMAX_DELAY;
208 timeoutTicks = pdMS_TO_TICKS(timeout);
210 startTime = xTaskGetTickCount();
214 res = xQueueReceive(*mbox, (void *) msg, timeoutTicks);
215 } while (res != pdTRUE && timeout == 0);
219 u32_t elapsedTime = TicksToMS(xTaskGetTickCount() - startTime);
220 if (elapsedTime == 0)
227 return SYS_ARCH_TIMEOUT;
231 u32_t sys_arch_mbox_tryfetch(sys_mbox_t * mbox, void ** msg)
239 res = xQueueReceive(*mbox, (void *) msg, 0);
241 return (res == pdTRUE) ? 0 : SYS_MBOX_EMPTY;
244 err_t sys_mbox_trypost(sys_mbox_t * mbox, void * msg)
248 res = xQueueSendToBack(*mbox, &msg, 0);
254 SYS_STATS_INC(mbox.err);
259 sys_thread_t sys_thread_new(const char * name, lwip_thread_fn thread, void * arg, int stacksize, int prio)
262 const unsigned short stacksizeWords = (unsigned short) (stacksize / sizeof(StackType_t));
264 if (strcmp(name, TCPIP_THREAD_NAME) != 0 || stacksize != TCPIP_THREAD_STACKSIZE)
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)
272 #endif // LWIP_FREERTOS_USE_STATIC_TCPIP_TASK
277 err_t sys_thread_finish(sys_thread_t t)
279 #if INCLUDE_vTaskDelete
280 TaskHandle_t taskH = (TaskHandle_t) t;
288 return TicksToMS(xTaskGetTickCount());
291 sys_prot_t sys_arch_protect(void)
293 return taskENTER_CRITICAL_FROM_ISR();
296 void sys_arch_unprotect(sys_prot_t pval)
298 taskEXIT_CRITICAL_FROM_ISR(pval);