• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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