1 /*
2 * Copyright (c) 2022-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2022-09-21
13 * Description: 网络
14 */
15 #include <arch/sys_arch.h>
16 #include <lwip/sys.h>
17 #include <lwip/debug.h>
18 #include "prt_config.h"
19 #include "prt_task.h"
20 #include "prt_queue.h"
21 #include "prt_sem.h"
22 #include "prt_config.h"
23 #include "prt_sys.h"
24 #include "prt_tick_external.h"
25 #include "prt_task_external.h"
26 #include "prt_clk.h"
27 #include "prt_queue_external.h"
28
29 #if (OS_MAX_CORE_NUM > 1)
30 OS_SPIN_LOCK_INIT(g_archProtectSpin);
31 static TskHandle g_lwprotThread = OS_ERRNO_TSK_ID_INVALID;
32 static S32 g_lwprotCount = 0;
33 #endif /* OS_MAX_CORE_NUM */
34
35 #define LWIP_LOG_BUF_SIZE 128
36
37 #define ROUND_UP_DIV(val, div) ((U64)(((U64)(val) + (U64)(div) - 1) / (U64)(div)))
38
39 /**
40 * Thread and System misc
41 */
sys_thread_new(const char * name,lwip_thread_fn thread,void * arg,int stackSize,int prio)42 sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio)
43 {
44 TskHandle taskId = OS_ERRNO_TSK_ID_INVALID;
45 U32 ret;
46 struct TskInitParam task = {0};
47
48 if (name == NULL || (strlen(name) == 0)) {
49 LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: name is null"));
50 return -1;
51 }
52
53 /* Create host Task */
54 task.taskEntry = (TskEntryFunc)thread;
55 task.stackSize = (U32)stackSize;
56 task.name = (char *)name;
57 task.taskPrio = (TskPrior)prio;
58 task.stackAddr = 0;
59 ret = PRT_TaskCreate(&taskId, &task);
60 if (ret != OS_OK) {
61 LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: PRT_TaskCreate error %u\n", ret));
62 return ret;
63 }
64
65 ret = PRT_TaskResume(taskId);
66 if (ret != OS_OK) {
67 LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: PRT_TaskResume error %u\n", ret));
68 return ret;
69 }
70 return taskId;
71 }
72
sys_init(void)73 void sys_init(void)
74 {
75 U32 seedlsb = (U32)PRT_ClkGetCycleCount64();
76 srand(seedlsb);
77 }
78
sys_now(void)79 u32_t sys_now(void)
80 {
81 return (U32)(((U32)PRT_TickGetCount() * OS_SYS_MS_PER_SECOND) / OS_TICK_PER_SECOND);
82 }
83
84 /**
85 * Protector
86 */
sys_arch_protect(void)87 sys_prot_t sys_arch_protect(void)
88 {
89 #if (OS_MAX_CORE_NUM > 1)
90 /* Note that we are using spinlock instead of mutex for LiteOS-SMP here:
91 * 1. spinlock is more effective for short critical region protection.
92 * 2. this function is called only in task context, not in interrupt handler.
93 * so it's not needed to disable interrupt.
94 */
95 if (g_lwprotThread != RUNNING_TASK->taskPid) {
96 /* We are locking the spinlock where it has not been locked before
97 * or is being locked by another thread */
98 g_lwprotThread = RUNNING_TASK->taskPid;
99 g_lwprotCount = 1;
100 } else {
101 /* It is already locked by THIS thread */
102 g_lwprotCount++;
103 }
104 #else
105 PRT_TaskLock();
106
107 #endif /* OS_MAX_CORE_NUM */
108 return 0; /* return value is unused */
109 }
110
sys_arch_unprotect(sys_prot_t pval)111 void sys_arch_unprotect(sys_prot_t pval)
112 {
113 LWIP_UNUSED_ARG(pval);
114 #if (OS_MAX_CORE_NUM > 1)
115 if (g_lwprotThread == RUNNING_TASK->taskPid) {
116 g_lwprotCount--;
117 if (g_lwprotCount == 0) {
118 g_lwprotThread = OS_ERRNO_TSK_ID_INVALID;
119 }
120 }
121 #else
122
123 PRT_TaskUnlock();
124 #endif /* OS_MAX_CORE_NUM */
125 }
126
127 /**
128 * MessageBox
129 */
sys_mbox_new(sys_mbox_t * mbox,int size)130 err_t sys_mbox_new(sys_mbox_t *mbox, int size)
131 {
132 if (mbox == NULL) {
133 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_new: mbox is null"));
134 return ERR_ARG;
135 }
136
137 char qName[] = "lwIP";
138 U32 ret = PRT_QueueCreate((U16)size, sizeof(void *), (U32 *)mbox);
139 switch (ret) {
140 case OS_OK:
141 return ERR_OK;
142 case OS_ERRNO_QUEUE_CB_UNAVAILABLE:
143 case OS_ERRNO_QUEUE_CREATE_NO_MEMORY:
144 return ERR_MEM;
145 default:
146 break;
147 }
148
149 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_QueueCreate error %u\n", __FUNCTION__, ret));
150 return ERR_ARG;
151 }
152
sys_mbox_post(sys_mbox_t * mbox,void * msg)153 void sys_mbox_post(sys_mbox_t *mbox, void *msg)
154 {
155 if (mbox == NULL) {
156 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox is null"));
157 return;
158 }
159
160 /* Caution: the second parameter is NOT &msg */
161 enum QueuePrio prio = OS_QUEUE_NORMAL;
162 U32 ret = PRT_QueueWrite((U32)(*mbox), (void*)&msg, sizeof(char *), OS_WAIT_FOREVER, (U32)prio);
163 if (ret != OS_OK) {
164 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_QueueWrite error %u\n", __FUNCTION__, ret));
165 }
166 }
167
sys_mbox_trypost(sys_mbox_t * mbox,void * msg)168 err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
169 {
170 if (mbox == NULL) {
171 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox is null"));
172 return ERR_ARG;
173 }
174
175 /* Caution: the second parameter is NOT &msg */
176 enum QueuePrio prio = OS_QUEUE_NORMAL;
177 U32 ret = PRT_QueueWrite((U32)(*mbox), (void*)&msg, sizeof(char *), 0, (U32)prio);
178 switch (ret) {
179 case OS_OK:
180 return ERR_OK;
181 case OS_ERRNO_QUEUE_NO_SOURCE:
182 return ERR_MEM;
183 default:
184 break;
185 }
186 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_QueueWrite error %u\n", __FUNCTION__, ret));
187 return ERR_ARG;
188 }
189
sys_mbox_trypost_fromisr(sys_mbox_t * mbox,void * msg)190 err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
191 {
192 (void)mbox;
193 (void)msg;
194 return ERR_ARG;
195 }
196
sys_arch_mbox_fetch(sys_mbox_t * mbox,void ** msg,u32_t timeoutMs)197 u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
198 {
199 if (mbox == NULL) {
200 LWIP_DEBUGF(SYS_DEBUG, ("sys_arch_mbox_fetch: mbox is null"));
201 return (u32_t)ERR_ARG;
202 }
203 void *ignore = 0; /* if msg == NULL, the fetched msg should be dropped */
204 U64 tick = ROUND_UP_DIV((U64)timeoutMs * OS_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
205 U32 ret = PRT_QueueRead((U32)(*mbox), msg ? msg : &ignore, sizeof(void *), tick ? (U32)tick : OS_WAIT_FOREVER);
206 switch (ret) {
207 case OS_OK:
208 return ERR_OK;
209 case OS_ERRNO_QUEUE_NO_SOURCE:
210 case OS_ERRNO_QUEUE_TIMEOUT:
211 return SYS_ARCH_TIMEOUT;
212 default:
213 break;
214 }
215
216 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_QueueRead error 0x%x\n", __FUNCTION__, ret));
217 return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
218 }
219
sys_arch_mbox_tryfetch(sys_mbox_t * mbox,void ** msg)220 u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
221 {
222 if (mbox == NULL) {
223 LWIP_DEBUGF(SYS_DEBUG, ("sys_arch_mbox_tryfetch: mbox is null"));
224 return (u32_t)ERR_ARG;
225 }
226
227 void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
228 U32 ret = PRT_QueueRead((U32)*mbox, msg ? msg : &ignore, sizeof(void *), 0);
229 switch (ret) {
230 case OS_OK:
231 return ERR_OK;
232 case OS_ERRNO_QUEUE_NO_SOURCE:
233 return SYS_MBOX_EMPTY;
234 case OS_ERRNO_QUEUE_TIMEOUT:
235 return SYS_ARCH_TIMEOUT;
236 default:
237 break;
238 }
239 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_QueueRead error %u\n", __FUNCTION__, ret));
240 return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */
241 }
242
sys_mbox_free(sys_mbox_t * mbox)243 void sys_mbox_free(sys_mbox_t *mbox)
244 {
245 if (mbox == NULL) {
246 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_free: mbox is null"));
247 return;
248 }
249 (void)PRT_QueueDelete(*mbox);
250 }
251
sys_mbox_valid(sys_mbox_t * mbox)252 int sys_mbox_valid(sys_mbox_t *mbox)
253 {
254 if (*mbox == NULL) {
255 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_valid: mbox is null"));
256 return ERR_ARG;
257 }
258 U32 innerId = OS_QUEUE_INNER_ID(*mbox);
259 struct TagQueCb *queueCb = NULL;
260 queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(innerId);
261 return queueCb->queueState == OS_QUEUE_USED;
262 }
263
sys_mbox_set_invalid(sys_mbox_t * mbox)264 void sys_mbox_set_invalid(sys_mbox_t *mbox)
265 {
266 if (mbox == NULL) {
267 LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_set_invalid: mbox is null"));
268 return;
269 }
270 *mbox = OS_QUEUE_MAX_SUPPORT_NUM;
271 }
272
273 /**
274 * Semaphore
275 */
sys_sem_new(sys_sem_t * sem,u8_t count)276 err_t sys_sem_new(sys_sem_t *sem, u8_t count)
277 {
278 if (sem == NULL) {
279 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_new: sem is null"));
280 return ERR_ARG;
281 }
282
283 U32 ret = PRT_SemCreate((U32)count, (SemHandle*)sem);
284 if (ret != OS_OK) {
285 return ERR_ARG;
286 }
287
288 return ERR_OK;
289 }
290
sys_sem_signal(sys_sem_t * sem)291 void sys_sem_signal(sys_sem_t *sem)
292 {
293 if (sem == NULL) {
294 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_signal: sem is null"));
295 return;
296 }
297 (void)PRT_SemPost((SemHandle)(*sem));
298 }
299
sys_arch_sem_wait(sys_sem_t * sem,u32_t timeoutMs)300 u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs)
301 {
302 if (sem == NULL) {
303 LWIP_DEBUGF(SYS_DEBUG, ("sys_arch_sem_wait: sem is null"));
304 return (u32_t)ERR_ARG;
305 }
306 U64 tick = ROUND_UP_DIV((U64)timeoutMs * OS_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
307 U32 ret = PRT_SemPend((SemHandle)(*sem), tick ? (U32)tick : OS_WAIT_FOREVER);
308 switch (ret) {
309 case OS_OK:
310 return ERR_OK;
311 case OS_ERRNO_SEM_TIMEOUT:
312 return SYS_ARCH_TIMEOUT;
313 default:
314 break;
315 }
316 LWIP_DEBUGF(SYS_DEBUG, ("%s: PRT_SemPend error %u\n", __FUNCTION__, ret));
317 return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
318 }
319
sys_sem_free(sys_sem_t * sem)320 void sys_sem_free(sys_sem_t *sem)
321 {
322 if (sem == NULL) {
323 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_free: sem is null"));
324 return;
325 }
326 (void)PRT_SemDelete((SemHandle)(*sem));
327 }
328
sys_sem_valid(sys_sem_t * sem)329 int sys_sem_valid(sys_sem_t *sem)
330 {
331 if (sem == NULL) {
332 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_valid: sem is null"));
333 return ERR_ARG;
334 }
335 return (SemHandle)(*sem) != OS_SEM_MAX_SUPPORT_NUM;
336 }
337
sys_sem_set_invalid(sys_sem_t * sem)338 void sys_sem_set_invalid(sys_sem_t *sem)
339 {
340 if (sem == NULL) {
341 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_set_invalid: sem is null"));
342 return;
343 }
344 *sem = OS_SEM_MAX_SUPPORT_NUM;
345 }
346
347 /**
348 * Mutex
349 */
sys_mutex_new(sys_mutex_t * mutex)350 err_t sys_mutex_new(sys_mutex_t *mutex)
351 {
352 if (mutex == NULL) {
353 LWIP_DEBUGF(SYS_DEBUG, ("sys_sem_new: sem is null"));
354 return ERR_ARG;
355 }
356
357 U32 ret = PRT_SemCreate(1, (SemHandle*)(mutex));
358 if (ret != OS_OK) {
359 return ERR_ARG;
360 }
361
362 return ERR_OK;
363 }
364
sys_mutex_lock(sys_mutex_t * mutex)365 void sys_mutex_lock(sys_mutex_t *mutex)
366 {
367 if (mutex == NULL) {
368 LWIP_DEBUGF(SYS_DEBUG, ("sys_mutex_lock: mutex is null"));
369 return;
370 }
371
372 (void)PRT_SemPend((SemHandle)(*mutex), OS_WAIT_FOREVER);
373 }
374
sys_mutex_unlock(sys_mutex_t * mutex)375 void sys_mutex_unlock(sys_mutex_t *mutex)
376 {
377 if (mutex == NULL) {
378 LWIP_DEBUGF(SYS_DEBUG, ("sys_mutex_unlock: mutex is null"));
379 return;
380 }
381
382 (void)PRT_SemPost((SemHandle)(*mutex));
383 }
384
sys_mutex_free(sys_mutex_t * mutex)385 void sys_mutex_free(sys_mutex_t *mutex)
386 {
387 if (mutex == NULL) {
388 LWIP_DEBUGF(SYS_DEBUG, ("sys_mutex_free: mutex is null"));
389 return;
390 }
391
392 (void)PRT_SemDelete((SemHandle)(*mutex));
393 }
394
sys_mutex_valid(sys_mutex_t * mutex)395 int sys_mutex_valid(sys_mutex_t *mutex)
396 {
397 if (mutex == NULL) {
398 LWIP_DEBUGF(SYS_DEBUG, ("sys_mutex_valid: mutex is null"));
399 return ERR_ARG;
400 }
401
402 return *mutex != OS_SEM_MAX_SUPPORT_NUM;
403 }
404
sys_mutex_set_invalid(sys_mutex_t * mutex)405 void sys_mutex_set_invalid(sys_mutex_t *mutex)
406 {
407 if (mutex == NULL) {
408 LWIP_DEBUGF(SYS_DEBUG, ("sys_mutex_set_invalid: mutex is null"));
409 return;
410 }
411
412 *mutex = OS_SEM_MAX_SUPPORT_NUM;
413 }
414
OsLwipLogPrintf(const char * fmt,...)415 void OsLwipLogPrintf(const char *fmt, ...)
416 {
417 if ((fmt == NULL) || (strlen(fmt) == 0)) {
418 return;
419 }
420
421 int len;
422 char buf[LWIP_LOG_BUF_SIZE] = {0};
423 va_list ap;
424 va_start(ap, fmt);
425 len = vsprintf_s(buf, sizeof(buf) - 1, fmt, ap);
426 va_end(ap);
427 if (len < 0) {
428 LWIP_LOGGER("log param invalid or buf is not enough.");
429 return;
430 }
431
432 printf("%s\n\r", buf);
433 LWIP_LOGGER(buf);
434 }
435