xref: /nrf52832-nimble/rt-thread/components/net/lwip-2.0.2/src/arch/sys_arch.c (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * COPYRIGHT (C) 2006-2018, RT-Thread Development Team
3*10465441SEvalZero  * All rights reserved.
4*10465441SEvalZero  *
5*10465441SEvalZero  * Redistribution and use in source and binary forms, with or without modification,
6*10465441SEvalZero  * are permitted provided that the following conditions are met:
7*10465441SEvalZero  *
8*10465441SEvalZero  * 1. Redistributions of source code must retain the above copyright notice,
9*10465441SEvalZero  *    this list of conditions and the following disclaimer.
10*10465441SEvalZero  * 2. Redistributions in binary form must reproduce the above copyright notice,
11*10465441SEvalZero  *    this list of conditions and the following disclaimer in the documentation
12*10465441SEvalZero  *    and/or other materials provided with the distribution.
13*10465441SEvalZero  * 3. The name of the author may not be used to endorse or promote products
14*10465441SEvalZero  *    derived from this software without specific prior written permission.
15*10465441SEvalZero  *
16*10465441SEvalZero  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17*10465441SEvalZero  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18*10465441SEvalZero  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19*10465441SEvalZero  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20*10465441SEvalZero  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21*10465441SEvalZero  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*10465441SEvalZero  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*10465441SEvalZero  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24*10465441SEvalZero  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25*10465441SEvalZero  * OF SUCH DAMAGE.
26*10465441SEvalZero  *
27*10465441SEvalZero  * Change Logs:
28*10465441SEvalZero  * Date           Author       Notes
29*10465441SEvalZero  * 2012-12-8      Bernard      add file header
30*10465441SEvalZero  *                             export bsd socket symbol for RT-Thread Application Module
31*10465441SEvalZero  * 2017-11-15     Bernard      add lock for init_done callback.
32*10465441SEvalZero  */
33*10465441SEvalZero 
34*10465441SEvalZero #include <rtthread.h>
35*10465441SEvalZero 
36*10465441SEvalZero #include "lwip/sys.h"
37*10465441SEvalZero #include "lwip/opt.h"
38*10465441SEvalZero #include "lwip/stats.h"
39*10465441SEvalZero #include "lwip/err.h"
40*10465441SEvalZero #include "arch/sys_arch.h"
41*10465441SEvalZero #include "lwip/debug.h"
42*10465441SEvalZero #include "lwip/netif.h"
43*10465441SEvalZero #include "lwip/netifapi.h"
44*10465441SEvalZero #include "lwip/tcpip.h"
45*10465441SEvalZero #include "netif/ethernetif.h"
46*10465441SEvalZero #include "lwip/sio.h"
47*10465441SEvalZero #include "lwip/init.h"
48*10465441SEvalZero #include "lwip/dhcp.h"
49*10465441SEvalZero #include "lwip/inet.h"
50*10465441SEvalZero 
51*10465441SEvalZero #include <string.h>
52*10465441SEvalZero 
53*10465441SEvalZero /*
54*10465441SEvalZero  * Initialize the network interface device
55*10465441SEvalZero  *
56*10465441SEvalZero  * @return the operation status, ERR_OK on OK, ERR_IF on error
57*10465441SEvalZero  */
netif_device_init(struct netif * netif)58*10465441SEvalZero static err_t netif_device_init(struct netif *netif)
59*10465441SEvalZero {
60*10465441SEvalZero     struct eth_device *ethif;
61*10465441SEvalZero 
62*10465441SEvalZero     ethif = (struct eth_device *)netif->state;
63*10465441SEvalZero     if (ethif != RT_NULL)
64*10465441SEvalZero     {
65*10465441SEvalZero         rt_device_t device;
66*10465441SEvalZero 
67*10465441SEvalZero         /* get device object */
68*10465441SEvalZero         device = (rt_device_t) ethif;
69*10465441SEvalZero         if (rt_device_init(device) != RT_EOK)
70*10465441SEvalZero         {
71*10465441SEvalZero             return ERR_IF;
72*10465441SEvalZero         }
73*10465441SEvalZero 
74*10465441SEvalZero         /* copy device flags to netif flags */
75*10465441SEvalZero         netif->flags = ethif->flags;
76*10465441SEvalZero 
77*10465441SEvalZero         return ERR_OK;
78*10465441SEvalZero     }
79*10465441SEvalZero 
80*10465441SEvalZero     return ERR_IF;
81*10465441SEvalZero }
82*10465441SEvalZero /*
83*10465441SEvalZero  * Initialize the ethernetif layer and set network interface device up
84*10465441SEvalZero  */
tcpip_init_done_callback(void * arg)85*10465441SEvalZero static void tcpip_init_done_callback(void *arg)
86*10465441SEvalZero {
87*10465441SEvalZero     rt_device_t device;
88*10465441SEvalZero     struct eth_device *ethif;
89*10465441SEvalZero     ip4_addr_t ipaddr, netmask, gw;
90*10465441SEvalZero     struct rt_list_node* node;
91*10465441SEvalZero     struct rt_object* object;
92*10465441SEvalZero     struct rt_object_information *information;
93*10465441SEvalZero 
94*10465441SEvalZero     LWIP_ASSERT("invalid arg.\n",arg);
95*10465441SEvalZero 
96*10465441SEvalZero     IP4_ADDR(&gw, 0,0,0,0);
97*10465441SEvalZero     IP4_ADDR(&ipaddr, 0,0,0,0);
98*10465441SEvalZero     IP4_ADDR(&netmask, 0,0,0,0);
99*10465441SEvalZero 
100*10465441SEvalZero     /* enter critical */
101*10465441SEvalZero     rt_enter_critical();
102*10465441SEvalZero 
103*10465441SEvalZero     /* for each network interfaces */
104*10465441SEvalZero     information = rt_object_get_information(RT_Object_Class_Device);
105*10465441SEvalZero     RT_ASSERT(information != RT_NULL);
106*10465441SEvalZero     for (node = information->object_list.next;
107*10465441SEvalZero          node != &(information->object_list);
108*10465441SEvalZero          node = node->next)
109*10465441SEvalZero     {
110*10465441SEvalZero         object = rt_list_entry(node, struct rt_object, list);
111*10465441SEvalZero         device = (rt_device_t)object;
112*10465441SEvalZero         if (device->type == RT_Device_Class_NetIf)
113*10465441SEvalZero         {
114*10465441SEvalZero             ethif = (struct eth_device *)device;
115*10465441SEvalZero 
116*10465441SEvalZero             /* leave critical */
117*10465441SEvalZero             rt_exit_critical();
118*10465441SEvalZero             LOCK_TCPIP_CORE();
119*10465441SEvalZero 
120*10465441SEvalZero             netif_add(ethif->netif, &ipaddr, &netmask, &gw,
121*10465441SEvalZero                       ethif, netif_device_init, tcpip_input);
122*10465441SEvalZero 
123*10465441SEvalZero             if (netif_default == RT_NULL)
124*10465441SEvalZero                 netif_set_default(ethif->netif);
125*10465441SEvalZero 
126*10465441SEvalZero #if LWIP_DHCP
127*10465441SEvalZero             /* set interface up */
128*10465441SEvalZero             netif_set_up(ethif->netif);
129*10465441SEvalZero             /* if this interface uses DHCP, start the DHCP client */
130*10465441SEvalZero             dhcp_start(ethif->netif);
131*10465441SEvalZero #else
132*10465441SEvalZero             /* set interface up */
133*10465441SEvalZero             netif_set_up(ethif->netif);
134*10465441SEvalZero #endif
135*10465441SEvalZero 
136*10465441SEvalZero             if (ethif->flags & ETHIF_LINK_PHYUP)
137*10465441SEvalZero             {
138*10465441SEvalZero                 netif_set_link_up(ethif->netif);
139*10465441SEvalZero             }
140*10465441SEvalZero 
141*10465441SEvalZero             UNLOCK_TCPIP_CORE();
142*10465441SEvalZero             /* enter critical */
143*10465441SEvalZero             rt_enter_critical();
144*10465441SEvalZero         }
145*10465441SEvalZero     }
146*10465441SEvalZero 
147*10465441SEvalZero     /* leave critical */
148*10465441SEvalZero     rt_exit_critical();
149*10465441SEvalZero     rt_sem_release((rt_sem_t)arg);
150*10465441SEvalZero }
151*10465441SEvalZero 
152*10465441SEvalZero /**
153*10465441SEvalZero  * LwIP system initialization
154*10465441SEvalZero  */
155*10465441SEvalZero extern int eth_system_device_init_private(void);
lwip_system_init(void)156*10465441SEvalZero int lwip_system_init(void)
157*10465441SEvalZero {
158*10465441SEvalZero     rt_err_t rc;
159*10465441SEvalZero     struct rt_semaphore done_sem;
160*10465441SEvalZero     static rt_bool_t init_ok = RT_FALSE;
161*10465441SEvalZero 
162*10465441SEvalZero     if (init_ok)
163*10465441SEvalZero     {
164*10465441SEvalZero         rt_kprintf("lwip system already init.\n");
165*10465441SEvalZero         return 0;
166*10465441SEvalZero     }
167*10465441SEvalZero 
168*10465441SEvalZero     eth_system_device_init_private();
169*10465441SEvalZero 
170*10465441SEvalZero     /* set default netif to NULL */
171*10465441SEvalZero     netif_default = RT_NULL;
172*10465441SEvalZero 
173*10465441SEvalZero     rc = rt_sem_init(&done_sem, "done", 0, RT_IPC_FLAG_FIFO);
174*10465441SEvalZero 
175*10465441SEvalZero     if (rc != RT_EOK)
176*10465441SEvalZero     {
177*10465441SEvalZero         LWIP_ASSERT("Failed to create semaphore", 0);
178*10465441SEvalZero 
179*10465441SEvalZero         return -1;
180*10465441SEvalZero     }
181*10465441SEvalZero 
182*10465441SEvalZero     tcpip_init(tcpip_init_done_callback, (void *)&done_sem);
183*10465441SEvalZero 
184*10465441SEvalZero     /* waiting for initialization done */
185*10465441SEvalZero     if (rt_sem_take(&done_sem, RT_WAITING_FOREVER) != RT_EOK)
186*10465441SEvalZero     {
187*10465441SEvalZero         rt_sem_detach(&done_sem);
188*10465441SEvalZero 
189*10465441SEvalZero         return -1;
190*10465441SEvalZero     }
191*10465441SEvalZero     rt_sem_detach(&done_sem);
192*10465441SEvalZero 
193*10465441SEvalZero     /* set default ip address */
194*10465441SEvalZero #if !LWIP_DHCP
195*10465441SEvalZero     if (netif_default != RT_NULL)
196*10465441SEvalZero     {
197*10465441SEvalZero         struct ip4_addr ipaddr, netmask, gw;
198*10465441SEvalZero 
199*10465441SEvalZero         ipaddr.addr = inet_addr(RT_LWIP_IPADDR);
200*10465441SEvalZero         gw.addr = inet_addr(RT_LWIP_GWADDR);
201*10465441SEvalZero         netmask.addr = inet_addr(RT_LWIP_MSKADDR);
202*10465441SEvalZero 
203*10465441SEvalZero         netifapi_netif_set_addr(netif_default, &ipaddr, &netmask, &gw);
204*10465441SEvalZero     }
205*10465441SEvalZero #endif
206*10465441SEvalZero     rt_kprintf("lwIP-%d.%d.%d initialized!\n", LWIP_VERSION_MAJOR, LWIP_VERSION_MINOR, LWIP_VERSION_REVISION);
207*10465441SEvalZero 
208*10465441SEvalZero     init_ok = RT_TRUE;
209*10465441SEvalZero 
210*10465441SEvalZero     return 0;
211*10465441SEvalZero }
212*10465441SEvalZero INIT_PREV_EXPORT(lwip_system_init);
213*10465441SEvalZero 
sys_init(void)214*10465441SEvalZero void sys_init(void)
215*10465441SEvalZero {
216*10465441SEvalZero     /* nothing on RT-Thread porting */
217*10465441SEvalZero }
218*10465441SEvalZero 
lwip_sys_init(void)219*10465441SEvalZero void lwip_sys_init(void)
220*10465441SEvalZero {
221*10465441SEvalZero     lwip_system_init();
222*10465441SEvalZero }
223*10465441SEvalZero 
224*10465441SEvalZero /*
225*10465441SEvalZero  * Create a new semaphore
226*10465441SEvalZero  *
227*10465441SEvalZero  * @return the operation status, ERR_OK on OK; others on error
228*10465441SEvalZero  */
sys_sem_new(sys_sem_t * sem,u8_t count)229*10465441SEvalZero err_t sys_sem_new(sys_sem_t *sem, u8_t count)
230*10465441SEvalZero {
231*10465441SEvalZero     static unsigned short counter = 0;
232*10465441SEvalZero     char tname[RT_NAME_MAX];
233*10465441SEvalZero     sys_sem_t tmpsem;
234*10465441SEvalZero 
235*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
236*10465441SEvalZero 
237*10465441SEvalZero     rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_SEM_NAME, counter);
238*10465441SEvalZero     counter ++;
239*10465441SEvalZero 
240*10465441SEvalZero     tmpsem = rt_sem_create(tname, count, RT_IPC_FLAG_FIFO);
241*10465441SEvalZero     if (tmpsem == RT_NULL)
242*10465441SEvalZero         return ERR_MEM;
243*10465441SEvalZero     else
244*10465441SEvalZero     {
245*10465441SEvalZero         *sem = tmpsem;
246*10465441SEvalZero 
247*10465441SEvalZero         return ERR_OK;
248*10465441SEvalZero     }
249*10465441SEvalZero }
250*10465441SEvalZero 
251*10465441SEvalZero /*
252*10465441SEvalZero  * Deallocate a semaphore
253*10465441SEvalZero  */
sys_sem_free(sys_sem_t * sem)254*10465441SEvalZero void sys_sem_free(sys_sem_t *sem)
255*10465441SEvalZero {
256*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
257*10465441SEvalZero     rt_sem_delete(*sem);
258*10465441SEvalZero }
259*10465441SEvalZero 
260*10465441SEvalZero /*
261*10465441SEvalZero  * Signal a semaphore
262*10465441SEvalZero  */
sys_sem_signal(sys_sem_t * sem)263*10465441SEvalZero void sys_sem_signal(sys_sem_t *sem)
264*10465441SEvalZero {
265*10465441SEvalZero     rt_sem_release(*sem);
266*10465441SEvalZero }
267*10465441SEvalZero 
268*10465441SEvalZero /*
269*10465441SEvalZero  * Block the thread while waiting for the semaphore to be signaled
270*10465441SEvalZero  *
271*10465441SEvalZero  * @return If the timeout argument is non-zero, it will return the number of milliseconds
272*10465441SEvalZero  *         spent waiting for the semaphore to be signaled; If the semaphore isn't signaled
273*10465441SEvalZero  *         within the specified time, it will return SYS_ARCH_TIMEOUT; If the thread doesn't
274*10465441SEvalZero  *         wait for the semaphore, it will return zero
275*10465441SEvalZero  */
sys_arch_sem_wait(sys_sem_t * sem,u32_t timeout)276*10465441SEvalZero u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
277*10465441SEvalZero {
278*10465441SEvalZero     rt_err_t ret;
279*10465441SEvalZero     s32_t t;
280*10465441SEvalZero     u32_t tick;
281*10465441SEvalZero 
282*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
283*10465441SEvalZero 
284*10465441SEvalZero     /* get the begin tick */
285*10465441SEvalZero     tick = rt_tick_get();
286*10465441SEvalZero     if (timeout == 0)
287*10465441SEvalZero         t = RT_WAITING_FOREVER;
288*10465441SEvalZero     else
289*10465441SEvalZero     {
290*10465441SEvalZero         /* convert msecond to os tick */
291*10465441SEvalZero         if (timeout < (1000/RT_TICK_PER_SECOND))
292*10465441SEvalZero             t = 1;
293*10465441SEvalZero         else
294*10465441SEvalZero             t = timeout / (1000/RT_TICK_PER_SECOND);
295*10465441SEvalZero     }
296*10465441SEvalZero 
297*10465441SEvalZero     ret = rt_sem_take(*sem, t);
298*10465441SEvalZero 
299*10465441SEvalZero     if (ret == -RT_ETIMEOUT)
300*10465441SEvalZero         return SYS_ARCH_TIMEOUT;
301*10465441SEvalZero     else
302*10465441SEvalZero     {
303*10465441SEvalZero         if (ret == RT_EOK)
304*10465441SEvalZero             ret = 1;
305*10465441SEvalZero     }
306*10465441SEvalZero 
307*10465441SEvalZero     /* get elapse msecond */
308*10465441SEvalZero     tick = rt_tick_get() - tick;
309*10465441SEvalZero 
310*10465441SEvalZero     /* convert tick to msecond */
311*10465441SEvalZero     tick = tick * (1000 / RT_TICK_PER_SECOND);
312*10465441SEvalZero     if (tick == 0)
313*10465441SEvalZero         tick = 1;
314*10465441SEvalZero 
315*10465441SEvalZero     return tick;
316*10465441SEvalZero }
317*10465441SEvalZero 
318*10465441SEvalZero #ifndef sys_sem_valid
319*10465441SEvalZero /** Check if a semaphore is valid/allocated:
320*10465441SEvalZero  *  return 1 for valid, 0 for invalid
321*10465441SEvalZero  */
sys_sem_valid(sys_sem_t * sem)322*10465441SEvalZero int sys_sem_valid(sys_sem_t *sem)
323*10465441SEvalZero {
324*10465441SEvalZero     return (int)(*sem);
325*10465441SEvalZero }
326*10465441SEvalZero #endif
327*10465441SEvalZero 
328*10465441SEvalZero #ifndef sys_sem_set_invalid
329*10465441SEvalZero /** Set a semaphore invalid so that sys_sem_valid returns 0
330*10465441SEvalZero  */
sys_sem_set_invalid(sys_sem_t * sem)331*10465441SEvalZero void sys_sem_set_invalid(sys_sem_t *sem)
332*10465441SEvalZero {
333*10465441SEvalZero     *sem = RT_NULL;
334*10465441SEvalZero }
335*10465441SEvalZero #endif
336*10465441SEvalZero 
337*10465441SEvalZero /* ====================== Mutex ====================== */
338*10465441SEvalZero 
339*10465441SEvalZero /** Create a new mutex
340*10465441SEvalZero  * @param mutex pointer to the mutex to create
341*10465441SEvalZero  * @return a new mutex
342*10465441SEvalZero  */
sys_mutex_new(sys_mutex_t * mutex)343*10465441SEvalZero err_t sys_mutex_new(sys_mutex_t *mutex)
344*10465441SEvalZero {
345*10465441SEvalZero     static unsigned short counter = 0;
346*10465441SEvalZero     char tname[RT_NAME_MAX];
347*10465441SEvalZero     sys_mutex_t tmpmutex;
348*10465441SEvalZero 
349*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
350*10465441SEvalZero 
351*10465441SEvalZero     rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MUTEX_NAME, counter);
352*10465441SEvalZero     counter ++;
353*10465441SEvalZero 
354*10465441SEvalZero     tmpmutex = rt_mutex_create(tname, RT_IPC_FLAG_FIFO);
355*10465441SEvalZero     if (tmpmutex == RT_NULL)
356*10465441SEvalZero         return ERR_MEM;
357*10465441SEvalZero     else
358*10465441SEvalZero     {
359*10465441SEvalZero         *mutex = tmpmutex;
360*10465441SEvalZero 
361*10465441SEvalZero         return ERR_OK;
362*10465441SEvalZero     }
363*10465441SEvalZero }
364*10465441SEvalZero 
365*10465441SEvalZero /** Lock a mutex
366*10465441SEvalZero  * @param mutex the mutex to lock
367*10465441SEvalZero  */
sys_mutex_lock(sys_mutex_t * mutex)368*10465441SEvalZero void sys_mutex_lock(sys_mutex_t *mutex)
369*10465441SEvalZero {
370*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
371*10465441SEvalZero     rt_mutex_take(*mutex, RT_WAITING_FOREVER);
372*10465441SEvalZero 
373*10465441SEvalZero     return;
374*10465441SEvalZero }
375*10465441SEvalZero 
376*10465441SEvalZero /** Unlock a mutex
377*10465441SEvalZero  * @param mutex the mutex to unlock
378*10465441SEvalZero  */
sys_mutex_unlock(sys_mutex_t * mutex)379*10465441SEvalZero void sys_mutex_unlock(sys_mutex_t *mutex)
380*10465441SEvalZero {
381*10465441SEvalZero     rt_mutex_release(*mutex);
382*10465441SEvalZero }
383*10465441SEvalZero 
384*10465441SEvalZero /** Delete a semaphore
385*10465441SEvalZero  * @param mutex the mutex to delete
386*10465441SEvalZero  */
sys_mutex_free(sys_mutex_t * mutex)387*10465441SEvalZero void sys_mutex_free(sys_mutex_t *mutex)
388*10465441SEvalZero {
389*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
390*10465441SEvalZero 
391*10465441SEvalZero     rt_mutex_delete(*mutex);
392*10465441SEvalZero }
393*10465441SEvalZero 
394*10465441SEvalZero #ifndef sys_mutex_valid
395*10465441SEvalZero /** Check if a mutex is valid/allocated:
396*10465441SEvalZero  *  return 1 for valid, 0 for invalid
397*10465441SEvalZero  */
sys_mutex_valid(sys_mutex_t * mutex)398*10465441SEvalZero int sys_mutex_valid(sys_mutex_t *mutex)
399*10465441SEvalZero {
400*10465441SEvalZero     return (int)(*mutex);
401*10465441SEvalZero }
402*10465441SEvalZero #endif
403*10465441SEvalZero 
404*10465441SEvalZero #ifndef sys_mutex_set_invalid
405*10465441SEvalZero /** Set a mutex invalid so that sys_mutex_valid returns 0
406*10465441SEvalZero  */
sys_mutex_set_invalid(sys_mutex_t * mutex)407*10465441SEvalZero void sys_mutex_set_invalid(sys_mutex_t *mutex)
408*10465441SEvalZero {
409*10465441SEvalZero     *mutex = RT_NULL;
410*10465441SEvalZero }
411*10465441SEvalZero #endif
412*10465441SEvalZero 
413*10465441SEvalZero /* ====================== Mailbox ====================== */
414*10465441SEvalZero 
415*10465441SEvalZero /*
416*10465441SEvalZero  * Create an empty mailbox for maximum "size" elements
417*10465441SEvalZero  *
418*10465441SEvalZero  * @return the operation status, ERR_OK on OK; others on error
419*10465441SEvalZero  */
sys_mbox_new(sys_mbox_t * mbox,int size)420*10465441SEvalZero err_t sys_mbox_new(sys_mbox_t *mbox, int size)
421*10465441SEvalZero {
422*10465441SEvalZero     static unsigned short counter = 0;
423*10465441SEvalZero     char tname[RT_NAME_MAX];
424*10465441SEvalZero     sys_mbox_t tmpmbox;
425*10465441SEvalZero 
426*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
427*10465441SEvalZero 
428*10465441SEvalZero     rt_snprintf(tname, RT_NAME_MAX, "%s%d", SYS_LWIP_MBOX_NAME, counter);
429*10465441SEvalZero     counter ++;
430*10465441SEvalZero 
431*10465441SEvalZero     tmpmbox = rt_mb_create(tname, size, RT_IPC_FLAG_FIFO);
432*10465441SEvalZero     if (tmpmbox != RT_NULL)
433*10465441SEvalZero     {
434*10465441SEvalZero         *mbox = tmpmbox;
435*10465441SEvalZero 
436*10465441SEvalZero         return ERR_OK;
437*10465441SEvalZero     }
438*10465441SEvalZero 
439*10465441SEvalZero     return ERR_MEM;
440*10465441SEvalZero }
441*10465441SEvalZero 
442*10465441SEvalZero /*
443*10465441SEvalZero  * Deallocate a mailbox
444*10465441SEvalZero  */
sys_mbox_free(sys_mbox_t * mbox)445*10465441SEvalZero void sys_mbox_free(sys_mbox_t *mbox)
446*10465441SEvalZero {
447*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
448*10465441SEvalZero 
449*10465441SEvalZero     rt_mb_delete(*mbox);
450*10465441SEvalZero 
451*10465441SEvalZero     return;
452*10465441SEvalZero }
453*10465441SEvalZero 
454*10465441SEvalZero /** Post a message to an mbox - may not fail
455*10465441SEvalZero  * -> blocks if full, only used from tasks not from ISR
456*10465441SEvalZero  * @param mbox mbox to posts the message
457*10465441SEvalZero  * @param msg message to post (ATTENTION: can be NULL)
458*10465441SEvalZero  */
sys_mbox_post(sys_mbox_t * mbox,void * msg)459*10465441SEvalZero void sys_mbox_post(sys_mbox_t *mbox, void *msg)
460*10465441SEvalZero {
461*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
462*10465441SEvalZero 
463*10465441SEvalZero     rt_mb_send_wait(*mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER);
464*10465441SEvalZero 
465*10465441SEvalZero     return;
466*10465441SEvalZero }
467*10465441SEvalZero 
468*10465441SEvalZero /*
469*10465441SEvalZero  * Try to post the "msg" to the mailbox
470*10465441SEvalZero  *
471*10465441SEvalZero  * @return return ERR_OK if the "msg" is posted, ERR_MEM if the mailbox is full
472*10465441SEvalZero  */
sys_mbox_trypost(sys_mbox_t * mbox,void * msg)473*10465441SEvalZero err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
474*10465441SEvalZero {
475*10465441SEvalZero     if (rt_mb_send(*mbox, (rt_uint32_t)msg) == RT_EOK)
476*10465441SEvalZero         return ERR_OK;
477*10465441SEvalZero 
478*10465441SEvalZero     return ERR_MEM;
479*10465441SEvalZero }
480*10465441SEvalZero 
481*10465441SEvalZero /** Wait for a new message to arrive in the mbox
482*10465441SEvalZero  * @param mbox mbox to get a message from
483*10465441SEvalZero  * @param msg pointer where the message is stored
484*10465441SEvalZero  * @param timeout maximum time (in milliseconds) to wait for a message
485*10465441SEvalZero  * @return time (in milliseconds) waited for a message, may be 0 if not waited
486*10465441SEvalZero            or SYS_ARCH_TIMEOUT on timeout
487*10465441SEvalZero  *         The returned time has to be accurate to prevent timer jitter!
488*10465441SEvalZero  */
sys_arch_mbox_fetch(sys_mbox_t * mbox,void ** msg,u32_t timeout)489*10465441SEvalZero u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
490*10465441SEvalZero {
491*10465441SEvalZero     rt_err_t ret;
492*10465441SEvalZero     s32_t t;
493*10465441SEvalZero     u32_t tick;
494*10465441SEvalZero 
495*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
496*10465441SEvalZero 
497*10465441SEvalZero     /* get the begin tick */
498*10465441SEvalZero     tick = rt_tick_get();
499*10465441SEvalZero 
500*10465441SEvalZero     if(timeout == 0)
501*10465441SEvalZero         t = RT_WAITING_FOREVER;
502*10465441SEvalZero     else
503*10465441SEvalZero     {
504*10465441SEvalZero         /* convirt msecond to os tick */
505*10465441SEvalZero         if (timeout < (1000/RT_TICK_PER_SECOND))
506*10465441SEvalZero             t = 1;
507*10465441SEvalZero         else
508*10465441SEvalZero             t = timeout / (1000/RT_TICK_PER_SECOND);
509*10465441SEvalZero     }
510*10465441SEvalZero 
511*10465441SEvalZero     ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, t);
512*10465441SEvalZero 
513*10465441SEvalZero     if(ret == -RT_ETIMEOUT)
514*10465441SEvalZero         return SYS_ARCH_TIMEOUT;
515*10465441SEvalZero     else
516*10465441SEvalZero     {
517*10465441SEvalZero         LWIP_ASSERT("rt_mb_recv returned with error!", ret == RT_EOK);
518*10465441SEvalZero     }
519*10465441SEvalZero 
520*10465441SEvalZero     /* get elapse msecond */
521*10465441SEvalZero     tick = rt_tick_get() - tick;
522*10465441SEvalZero 
523*10465441SEvalZero     /* convert tick to msecond */
524*10465441SEvalZero     tick = tick * (1000 / RT_TICK_PER_SECOND);
525*10465441SEvalZero     if (tick == 0)
526*10465441SEvalZero         tick = 1;
527*10465441SEvalZero 
528*10465441SEvalZero     return tick;
529*10465441SEvalZero }
530*10465441SEvalZero 
531*10465441SEvalZero /** Wait for a new message to arrive in the mbox
532*10465441SEvalZero  * @param mbox mbox to get a message from
533*10465441SEvalZero  * @param msg pointer where the message is stored
534*10465441SEvalZero  * @param timeout maximum time (in milliseconds) to wait for a message
535*10465441SEvalZero  * @return 0 (milliseconds) if a message has been received
536*10465441SEvalZero  *         or SYS_MBOX_EMPTY if the mailbox is empty
537*10465441SEvalZero  */
sys_arch_mbox_tryfetch(sys_mbox_t * mbox,void ** msg)538*10465441SEvalZero u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
539*10465441SEvalZero {
540*10465441SEvalZero     int ret;
541*10465441SEvalZero 
542*10465441SEvalZero     ret = rt_mb_recv(*mbox, (rt_ubase_t *)msg, 0);
543*10465441SEvalZero 
544*10465441SEvalZero     if(ret == -RT_ETIMEOUT)
545*10465441SEvalZero         return SYS_ARCH_TIMEOUT;
546*10465441SEvalZero     else
547*10465441SEvalZero     {
548*10465441SEvalZero         if (ret == RT_EOK)
549*10465441SEvalZero             ret = 1;
550*10465441SEvalZero     }
551*10465441SEvalZero 
552*10465441SEvalZero     return ret;
553*10465441SEvalZero }
554*10465441SEvalZero 
555*10465441SEvalZero #ifndef sys_mbox_valid
556*10465441SEvalZero /** Check if an mbox is valid/allocated:
557*10465441SEvalZero  *  return 1 for valid, 0 for invalid
558*10465441SEvalZero  */
sys_mbox_valid(sys_mbox_t * mbox)559*10465441SEvalZero int sys_mbox_valid(sys_mbox_t *mbox)
560*10465441SEvalZero {
561*10465441SEvalZero     return (int)(*mbox);
562*10465441SEvalZero }
563*10465441SEvalZero #endif
564*10465441SEvalZero 
565*10465441SEvalZero #ifndef sys_mbox_set_invalid
566*10465441SEvalZero /** Set an mbox invalid so that sys_mbox_valid returns 0
567*10465441SEvalZero  */
sys_mbox_set_invalid(sys_mbox_t * mbox)568*10465441SEvalZero void sys_mbox_set_invalid(sys_mbox_t *mbox)
569*10465441SEvalZero {
570*10465441SEvalZero     *mbox = RT_NULL;
571*10465441SEvalZero }
572*10465441SEvalZero #endif
573*10465441SEvalZero 
574*10465441SEvalZero /* ====================== System ====================== */
575*10465441SEvalZero 
576*10465441SEvalZero /*
577*10465441SEvalZero  * Start a new thread named "name" with priority "prio" that will begin
578*10465441SEvalZero  * its execution in the function "thread()". The "arg" argument will be
579*10465441SEvalZero  * passed as an argument to the thread() function
580*10465441SEvalZero  */
sys_thread_new(const char * name,lwip_thread_fn thread,void * arg,int stacksize,int prio)581*10465441SEvalZero sys_thread_t sys_thread_new(const char    *name,
582*10465441SEvalZero                             lwip_thread_fn thread,
583*10465441SEvalZero                             void          *arg,
584*10465441SEvalZero                             int            stacksize,
585*10465441SEvalZero                             int            prio)
586*10465441SEvalZero {
587*10465441SEvalZero     rt_thread_t t;
588*10465441SEvalZero 
589*10465441SEvalZero     RT_DEBUG_NOT_IN_INTERRUPT;
590*10465441SEvalZero 
591*10465441SEvalZero     /* create thread */
592*10465441SEvalZero     t = rt_thread_create(name, thread, arg, stacksize, prio, 20);
593*10465441SEvalZero     RT_ASSERT(t != RT_NULL);
594*10465441SEvalZero 
595*10465441SEvalZero     /* startup thread */
596*10465441SEvalZero     rt_thread_startup(t);
597*10465441SEvalZero 
598*10465441SEvalZero     return t;
599*10465441SEvalZero }
600*10465441SEvalZero 
sys_arch_protect(void)601*10465441SEvalZero sys_prot_t sys_arch_protect(void)
602*10465441SEvalZero {
603*10465441SEvalZero     rt_base_t level;
604*10465441SEvalZero 
605*10465441SEvalZero     /* disable interrupt */
606*10465441SEvalZero     level = rt_hw_interrupt_disable();
607*10465441SEvalZero 
608*10465441SEvalZero     return level;
609*10465441SEvalZero }
610*10465441SEvalZero 
sys_arch_unprotect(sys_prot_t pval)611*10465441SEvalZero void sys_arch_unprotect(sys_prot_t pval)
612*10465441SEvalZero {
613*10465441SEvalZero     /* enable interrupt */
614*10465441SEvalZero     rt_hw_interrupt_enable(pval);
615*10465441SEvalZero 
616*10465441SEvalZero     return;
617*10465441SEvalZero }
618*10465441SEvalZero 
sys_arch_assert(const char * file,int line)619*10465441SEvalZero void sys_arch_assert(const char *file, int line)
620*10465441SEvalZero {
621*10465441SEvalZero     rt_kprintf("\nAssertion: %d in %s, thread %s\n",
622*10465441SEvalZero                line, file, rt_thread_self()->name);
623*10465441SEvalZero     RT_ASSERT(0);
624*10465441SEvalZero }
625*10465441SEvalZero 
sys_jiffies(void)626*10465441SEvalZero u32_t sys_jiffies(void)
627*10465441SEvalZero {
628*10465441SEvalZero     return rt_tick_get();
629*10465441SEvalZero }
630*10465441SEvalZero 
sys_now(void)631*10465441SEvalZero u32_t sys_now(void)
632*10465441SEvalZero {
633*10465441SEvalZero     return rt_tick_get() * (1000 / RT_TICK_PER_SECOND);
634*10465441SEvalZero }
635*10465441SEvalZero 
636*10465441SEvalZero 
637*10465441SEvalZero RT_WEAK
mem_init(void)638*10465441SEvalZero void mem_init(void)
639*10465441SEvalZero {
640*10465441SEvalZero }
641*10465441SEvalZero 
mem_calloc(mem_size_t count,mem_size_t size)642*10465441SEvalZero void *mem_calloc(mem_size_t count, mem_size_t size)
643*10465441SEvalZero {
644*10465441SEvalZero     return rt_calloc(count, size);
645*10465441SEvalZero }
646*10465441SEvalZero 
mem_trim(void * mem,mem_size_t size)647*10465441SEvalZero void *mem_trim(void *mem, mem_size_t size)
648*10465441SEvalZero {
649*10465441SEvalZero     // return rt_realloc(mem, size);
650*10465441SEvalZero     /* not support trim yet */
651*10465441SEvalZero     return mem;
652*10465441SEvalZero }
653*10465441SEvalZero 
mem_malloc(mem_size_t size)654*10465441SEvalZero void *mem_malloc(mem_size_t size)
655*10465441SEvalZero {
656*10465441SEvalZero     return rt_malloc(size);
657*10465441SEvalZero }
658*10465441SEvalZero 
mem_free(void * mem)659*10465441SEvalZero void  mem_free(void *mem)
660*10465441SEvalZero {
661*10465441SEvalZero     rt_free(mem);
662*10465441SEvalZero }
663*10465441SEvalZero 
664*10465441SEvalZero #ifdef RT_LWIP_PPP
sio_read(sio_fd_t fd,u8_t * buf,u32_t size)665*10465441SEvalZero u32_t sio_read(sio_fd_t fd, u8_t *buf, u32_t size)
666*10465441SEvalZero {
667*10465441SEvalZero     u32_t len;
668*10465441SEvalZero 
669*10465441SEvalZero     RT_ASSERT(fd != RT_NULL);
670*10465441SEvalZero 
671*10465441SEvalZero     len = rt_device_read((rt_device_t)fd, 0, buf, size);
672*10465441SEvalZero     if (len <= 0)
673*10465441SEvalZero         return 0;
674*10465441SEvalZero 
675*10465441SEvalZero     return len;
676*10465441SEvalZero }
677*10465441SEvalZero 
sio_write(sio_fd_t fd,u8_t * buf,u32_t size)678*10465441SEvalZero u32_t sio_write(sio_fd_t fd, u8_t *buf, u32_t size)
679*10465441SEvalZero {
680*10465441SEvalZero     RT_ASSERT(fd != RT_NULL);
681*10465441SEvalZero 
682*10465441SEvalZero     return rt_device_write((rt_device_t)fd, 0, buf, size);
683*10465441SEvalZero }
684*10465441SEvalZero 
sio_read_abort(sio_fd_t fd)685*10465441SEvalZero void sio_read_abort(sio_fd_t fd)
686*10465441SEvalZero {
687*10465441SEvalZero     rt_kprintf("read_abort\n");
688*10465441SEvalZero }
689*10465441SEvalZero 
ppp_trace(int level,const char * format,...)690*10465441SEvalZero void ppp_trace(int level, const char *format, ...)
691*10465441SEvalZero {
692*10465441SEvalZero     va_list args;
693*10465441SEvalZero     rt_size_t length;
694*10465441SEvalZero     static char rt_log_buf[RT_CONSOLEBUF_SIZE];
695*10465441SEvalZero 
696*10465441SEvalZero     va_start(args, format);
697*10465441SEvalZero     length = rt_vsprintf(rt_log_buf, format, args);
698*10465441SEvalZero     rt_device_write((rt_device_t)rt_console_get_device(), 0, rt_log_buf, length);
699*10465441SEvalZero     va_end(args);
700*10465441SEvalZero }
701*10465441SEvalZero #endif
702*10465441SEvalZero 
703*10465441SEvalZero /*
704*10465441SEvalZero  * export bsd socket symbol for RT-Thread Application Module
705*10465441SEvalZero  */
706*10465441SEvalZero #if LWIP_SOCKET
707*10465441SEvalZero #include <lwip/sockets.h>
708*10465441SEvalZero RTM_EXPORT(lwip_accept);
709*10465441SEvalZero RTM_EXPORT(lwip_bind);
710*10465441SEvalZero RTM_EXPORT(lwip_shutdown);
711*10465441SEvalZero RTM_EXPORT(lwip_getpeername);
712*10465441SEvalZero RTM_EXPORT(lwip_getsockname);
713*10465441SEvalZero RTM_EXPORT(lwip_getsockopt);
714*10465441SEvalZero RTM_EXPORT(lwip_setsockopt);
715*10465441SEvalZero RTM_EXPORT(lwip_close);
716*10465441SEvalZero RTM_EXPORT(lwip_connect);
717*10465441SEvalZero RTM_EXPORT(lwip_listen);
718*10465441SEvalZero RTM_EXPORT(lwip_recv);
719*10465441SEvalZero RTM_EXPORT(lwip_read);
720*10465441SEvalZero RTM_EXPORT(lwip_recvfrom);
721*10465441SEvalZero RTM_EXPORT(lwip_send);
722*10465441SEvalZero RTM_EXPORT(lwip_sendto);
723*10465441SEvalZero RTM_EXPORT(lwip_socket);
724*10465441SEvalZero RTM_EXPORT(lwip_write);
725*10465441SEvalZero RTM_EXPORT(lwip_select);
726*10465441SEvalZero RTM_EXPORT(lwip_ioctl);
727*10465441SEvalZero RTM_EXPORT(lwip_fcntl);
728*10465441SEvalZero 
729*10465441SEvalZero RTM_EXPORT(lwip_htons);
730*10465441SEvalZero RTM_EXPORT(lwip_htonl);
731*10465441SEvalZero 
732*10465441SEvalZero #if LWIP_DNS
733*10465441SEvalZero #include <lwip/netdb.h>
734*10465441SEvalZero RTM_EXPORT(lwip_gethostbyname);
735*10465441SEvalZero RTM_EXPORT(lwip_gethostbyname_r);
736*10465441SEvalZero RTM_EXPORT(lwip_freeaddrinfo);
737*10465441SEvalZero RTM_EXPORT(lwip_getaddrinfo);
738*10465441SEvalZero #endif
739*10465441SEvalZero 
740*10465441SEvalZero #endif
741*10465441SEvalZero 
742*10465441SEvalZero #if LWIP_DHCP
743*10465441SEvalZero #include <lwip/dhcp.h>
744*10465441SEvalZero RTM_EXPORT(dhcp_start);
745*10465441SEvalZero RTM_EXPORT(dhcp_renew);
746*10465441SEvalZero RTM_EXPORT(dhcp_stop);
747*10465441SEvalZero #endif
748*10465441SEvalZero 
749*10465441SEvalZero #if LWIP_NETIF_API
750*10465441SEvalZero #include <lwip/netifapi.h>
751*10465441SEvalZero RTM_EXPORT(netifapi_netif_set_addr);
752*10465441SEvalZero #endif
753*10465441SEvalZero 
754*10465441SEvalZero #if LWIP_NETIF_LINK_CALLBACK
755*10465441SEvalZero RTM_EXPORT(netif_set_link_callback);
756*10465441SEvalZero #endif
757*10465441SEvalZero 
758*10465441SEvalZero #if LWIP_NETIF_STATUS_CALLBACK
759*10465441SEvalZero RTM_EXPORT(netif_set_status_callback);
760*10465441SEvalZero #endif
761*10465441SEvalZero 
762*10465441SEvalZero RTM_EXPORT(netif_find);
763*10465441SEvalZero RTM_EXPORT(netif_set_addr);
764*10465441SEvalZero RTM_EXPORT(netif_set_ipaddr);
765*10465441SEvalZero RTM_EXPORT(netif_set_gw);
766*10465441SEvalZero RTM_EXPORT(netif_set_netmask);
767