]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/lwip_tcpip/v2_0/src/ecos/sys_arch.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / lwip_tcpip / v2_0 / src / ecos / sys_arch.c
1 //==========================================================================
2 //####ECOSGPLCOPYRIGHTBEGIN####
3 // -------------------------------------------
4 // This file is part of eCos, the Embedded Configurable Operating System.
5 // Copyright (C) 2004 eCosCentric 
6 //
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.
10 //
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
14 // for more details.
15 //
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.
19 //
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.
26 //
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
34 //
35
36 /* 
37  * This file implements the eCos specific sys_arch functions used by lwIP 
38  */
39
40 #include "lwip/opt.h"
41 #include "arch/sys_arch.h"
42 #include "lwip/sys.h"
43 #include "lwip/def.h"
44
45 #define tick_to_msec(tick)      ((u16_t)((tick)*10+1)) 
46 #define msec_to_tick(msec)      ((cyg_tick_count_t)(msec+9)/10)
47
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;
52
53
54 #define SYS_THREADS     2       /* polling thread and tcpip_thread */
55
56 #define THREAD_COUNT    (CYGNUM_LWIP_APP_THREADS + SYS_THREADS)
57 static char memfix[CYGNUM_LWIP_THREAD_STACK_SIZE * THREAD_COUNT];
58
59 /* List of threads: associate eCos thread info with lwIP timeout info */
60 struct lwip_thread {
61         struct lwip_thread * next;
62         struct sys_timeouts to;
63         cyg_handle_t th;
64         cyg_thread t;           
65 } *threads;
66
67 /* 
68  * Timeout for threads which were not created by sys_thread_new
69  * usually "main"
70  */ 
71 struct sys_timeouts to;
72
73 /* 
74  * Set up memory pools and threads
75  */
76 void sys_init(void)
77 {
78         cyg_mempool_var_create(memvar, sizeof(memvar), &var_mempool_h, &var_mempool);   
79
80         threads = NULL;
81         to.next = NULL;
82 }
83
84 /*
85  * Create a new mbox.If no memory is available return NULL 
86  */
87 sys_mbox_t sys_mbox_new(void)
88 {
89         cyg_mbox * mbox;
90         cyg_handle_t m;
91         mbox = (cyg_mbox *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_mbox));
92         
93         /* out of memory? */
94         if(!mbox) 
95                 return SYS_MBOX_NULL;
96         
97         cyg_mbox_create(&m, mbox);
98         return m;
99 }
100
101 /*
102  * Destroy the mbox and release the space it took up in the pool
103  */
104 void sys_mbox_free(sys_mbox_t mbox)
105 {
106         cyg_mbox_delete(mbox);
107         cyg_mempool_var_free(var_mempool_h,(void*)mbox);
108 }
109
110 /* 
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
114  * NULL data
115  */
116
117 int dummy_msg = 1;
118
119 /* 
120  * Post data to a mbox.
121  */ 
122 void sys_mbox_post(sys_mbox_t mbox, void *data)
123 {
124         if (!data)
125                 data = &dummy_msg;
126         while (cyg_mbox_put(mbox,data) == false);
127 }
128
129 #if 0
130 void
131 sys_mbox_fetch(sys_mbox_t mbox, void **msg){
132         void *d;
133         d = cyg_mbox_get(mbox);
134         if (msg)
135                 *msg = d;
136         
137 }
138 #endif
139
140 /* 
141  * Fetch data from a mbox.Wait for at most timeout millisecs
142  * Return -1 if timed out otherwise time spent waiting.
143  */ 
144 u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u32_t timeout)
145 {
146         void *d;
147         cyg_tick_count_t end_time = 0, start_time = 0;
148         if (timeout) {
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();
152
153                 if (d == NULL)
154                         return SYS_ARCH_TIMEOUT;
155         } else {
156                 d = cyg_mbox_get(mbox);
157         }
158
159         if (data) {
160                 if (d == (void *)&dummy_msg)
161                         *data = NULL;
162                 else
163                         *data = d;
164         }
165
166         return tick_to_msec(end_time - start_time);     
167 }
168
169 /*
170  * Create a new semaphore and initialize it.
171  * If no memory is available return NULL 
172  */
173 sys_sem_t sys_sem_new(u8_t count)
174 {
175         sys_sem_t sem;
176
177         sem = (cyg_sem_t *)cyg_mempool_var_try_alloc(var_mempool_h, sizeof(cyg_sem_t));
178         /* out of memory? */
179         if(!sem)
180                 return SYS_SEM_NULL;
181         cyg_semaphore_init(sem, count);
182         return sem;
183 }
184
185 #if 0
186 void
187 sys_sem_wait(sys_sem_t sem)
188 {
189         cyg_semaphore_wait(sem);
190
191 }
192
193 void
194 sys_timeout(u16_t msecs, sys_timeout_handler h, void *arg)
195 {}
196 #endif
197 /* 
198  * Wait on a semaphore for at most timeout millisecs
199  * Return -1 if timed out otherwise time spent waiting.
200  */ 
201 u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
202 {
203         cyg_bool_t r;
204         cyg_tick_count_t end_time = 0, start_time = 0;
205
206         if (timeout) {
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();
210
211                 if (r == false) {
212                         return SYS_ARCH_TIMEOUT;
213                 }       
214         } else {
215                 cyg_semaphore_wait(sem);
216         }
217
218         return tick_to_msec(end_time - start_time);     
219 }
220
221 /*
222  * Signal a semaphore
223  */ 
224 void sys_sem_signal(sys_sem_t sem)
225 {
226         cyg_semaphore_post(sem);
227 }
228
229 /* 
230  * Destroy the semaphore and release the space it took up in the pool 
231  */
232 void sys_sem_free(sys_sem_t sem)
233 {
234         cyg_semaphore_destroy(sem);
235         cyg_mempool_var_free(var_mempool_h,(void*)sem);
236 }
237
238 /*
239  * Create new thread 
240  */
241 sys_thread_t sys_thread_new(void (*function) (void *arg), void *arg,int prio)
242 {
243         struct lwip_thread * nt;
244         void * stack;
245         static int thread_count = 0;
246         nt = (struct lwip_thread *)cyg_mempool_var_alloc(var_mempool_h, sizeof(struct lwip_thread));
247
248         nt->next = threads;
249         nt->to.next = NULL;
250         
251         threads = nt;
252
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) );
256
257         cyg_thread_resume(nt->th);
258         return nt->th;
259 }
260
261 /* 
262  * Return current thread's timeout info
263  */
264 struct sys_timeouts *sys_arch_timeouts(void)
265 {
266         cyg_handle_t ct;
267         struct lwip_thread *t;
268
269         ct = cyg_thread_self();
270         for(t = threads; t; t = t->next)
271                 if (t->th == ct)
272                         return &(t->to);
273         
274         return &to;
275 }