1 //==========================================================================
2 //####ECOSGPLCOPYRIGHTBEGIN####
3 // -------------------------------------------
4 // This file is part of eCos, the Embedded Configurable Operating System.
5 // Copyright (C) 2004 eCosCentric
7 // eCos is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 2 or (at your option) any later version.
11 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 // You should have received a copy of the GNU General Public License along
17 // with eCos; if not, write to the Free Software Foundation, Inc.,
18 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20 // As a special exception, if other files instantiate templates or use macros
21 // or inline functions from this file, or you compile this file and link it
22 // with other works to produce a work based on this file, this file does not
23 // by itself cause the resulting work to be covered by the GNU General Public
24 // License. However the source code for this file must still be made available
25 // in accordance with section (3) of the GNU General Public License.
27 // This exception does not invalidate any other reasons why a work based on
28 // this file might be covered by the GNU General Public License.
29 // -------------------------------------------
30 //####ECOSGPLCOPYRIGHTEND####
31 //==========================================================================
32 // Author: Jani Monoses
33 // Contributors: Claudio Leonel Salvadori
37 * This file implements the eCos specific sys_arch functions used by lwIP
41 #include "arch/sys_arch.h"
45 #define tick_to_msec(tick) ((u16_t)((tick)*10+1))
46 #define msec_to_tick(msec) ((cyg_tick_count_t)(msec+9)/10)
48 /* We use a common var mempool for allocating semaphores, mboxes and threads... */
49 static char memvar[CYGNUM_LWIP_VARMEMPOOL_SIZE];
50 static cyg_mempool_var var_mempool;
51 static cyg_handle_t var_mempool_h;
54 #define SYS_THREADS 2 /* polling thread and tcpip_thread */
56 #define THREAD_COUNT (CYGNUM_LWIP_APP_THREADS + SYS_THREADS)
57 static char memfix[CYGNUM_LWIP_THREAD_STACK_SIZE * THREAD_COUNT];
59 /* List of threads: associate eCos thread info with lwIP timeout info */
61 struct lwip_thread * next;
62 struct sys_timeouts to;
68 * Timeout for threads which were not created by sys_thread_new
71 struct sys_timeouts to;
74 * Set up memory pools and threads
78 cyg_mempool_var_create(memvar, sizeof(memvar), &var_mempool_h, &var_mempool);
85 * Create a new mbox.If no memory is available return NULL
87 sys_mbox_t sys_mbox_new(void)
91 mbox = (cyg_mbox *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_mbox));
97 cyg_mbox_create(&m, mbox);
102 * Destroy the mbox and release the space it took up in the pool
104 void sys_mbox_free(sys_mbox_t mbox)
106 cyg_mbox_delete(mbox);
107 cyg_mempool_var_free(var_mempool_h,(void*)mbox);
111 * cyg_mbox_put should not be passed a NULL otherwise the cyg_mbox_get will not
112 * know if it's real data or error condition. But lwIP does pass NULL on occasion
113 * in cases when maybe using a semaphore would be better. So this dummy_msg replaces
120 * Post data to a mbox.
122 void sys_mbox_post(sys_mbox_t mbox, void *data)
126 while (cyg_mbox_put(mbox,data) == false);
131 sys_mbox_fetch(sys_mbox_t mbox, void **msg){
133 d = cyg_mbox_get(mbox);
141 * Fetch data from a mbox.Wait for at most timeout millisecs
142 * Return -1 if timed out otherwise time spent waiting.
144 u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u32_t timeout)
147 cyg_tick_count_t end_time = 0, start_time = 0;
149 start_time = cyg_current_time();
150 d = cyg_mbox_timed_get(mbox, start_time + msec_to_tick(timeout));
151 end_time = cyg_current_time();
154 return SYS_ARCH_TIMEOUT;
156 d = cyg_mbox_get(mbox);
160 if (d == (void *)&dummy_msg)
166 return tick_to_msec(end_time - start_time);
170 * Create a new semaphore and initialize it.
171 * If no memory is available return NULL
173 sys_sem_t sys_sem_new(u8_t count)
177 sem = (cyg_sem_t *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_sem_t));
181 cyg_semaphore_init(sem, count);
187 sys_sem_wait(sys_sem_t sem)
189 cyg_semaphore_wait(sem);
194 sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg)
198 * Wait on a semaphore for at most timeout millisecs
199 * Return -1 if timed out otherwise time spent waiting.
201 u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
204 cyg_tick_count_t end_time = 0, start_time = 0;
207 start_time = cyg_current_time();
208 r = cyg_semaphore_timed_wait(sem, start_time + msec_to_tick(timeout));
209 end_time = cyg_current_time();
212 return SYS_ARCH_TIMEOUT;
215 cyg_semaphore_wait(sem);
218 return tick_to_msec(end_time - start_time);
224 void sys_sem_signal(sys_sem_t sem)
226 cyg_semaphore_post(sem);
230 * Destroy the semaphore and release the space it took up in the pool
232 void sys_sem_free(sys_sem_t sem)
234 cyg_semaphore_destroy(sem);
235 cyg_mempool_var_free(var_mempool_h,(void*)sem);
241 sys_thread_t sys_thread_new(void (*function) (void *arg), void *arg,int prio)
243 struct lwip_thread * nt;
245 static int thread_count = 0;
246 nt = (struct lwip_thread *)cyg_mempool_var_alloc(var_mempool_h, sizeof(struct lwip_thread));
253 stack = (void *)(memfix+CYGNUM_LWIP_THREAD_STACK_SIZE*thread_count++);
254 cyg_thread_create(prio, (cyg_thread_entry_t *)function, (cyg_addrword_t)arg,
255 (char *)arg , stack, CYGNUM_LWIP_THREAD_STACK_SIZE, &(nt->th), &(nt->t) );
257 cyg_thread_resume(nt->th);
262 * Return current thread's timeout info
264 struct sys_timeouts *sys_arch_timeouts(void)
267 struct lwip_thread *t;
269 ct = cyg_thread_self();
270 for(t = threads; t; t = t->next)