OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_Demo_Rowley_ARM7/] [lwip-1.1.0/] [contrib/] [port/] [FreeRTOS/] [AT91SAM7X/] [sys_arch.c] - Blame information for rev 583

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 583 jeremybenn
/*
2
 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without modification,
6
 * are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25
 * OF SUCH DAMAGE.
26
 *
27
 * This file is part of the lwIP TCP/IP stack.
28
 *
29
 * Author: Adam Dunkels <adam@sics.se>
30
 *
31
 */
32
 
33
/* lwIP includes. */
34
#include "lwip/debug.h"
35
#include "lwip/def.h"
36
#include "lwip/sys.h"
37
#include "lwip/mem.h"
38
 
39
/* Message queue constants. */
40
#define archMESG_QUEUE_LENGTH   ( 6 )
41
#define archPOST_BLOCK_TIME_MS  ( ( unsigned long ) 10000 )
42
 
43
struct timeoutlist
44
{
45
        struct sys_timeouts timeouts;
46
        xTaskHandle pid;
47
};
48
 
49
/* This is the number of threads that can be started with sys_thread_new() */
50
#define SYS_THREAD_MAX 4
51
 
52
#define lwipTCP_STACK_SIZE                      600
53
#define lwipBASIC_SERVER_STACK_SIZE     250
54
 
55
static struct timeoutlist timeoutlist[SYS_THREAD_MAX];
56
static u16_t nextthread = 0;
57
int intlevel = 0;
58
 
59
 
60
/*-----------------------------------------------------------------------------------*/
61
//  Creates an empty mailbox.
62
sys_mbox_t
63
sys_mbox_new(void)
64
{
65
        xQueueHandle mbox;
66
 
67
        mbox = xQueueCreate( archMESG_QUEUE_LENGTH, sizeof( void * ) );
68
 
69
        return mbox;
70
}
71
 
72
/*-----------------------------------------------------------------------------------*/
73
/*
74
  Deallocates a mailbox. If there are messages still present in the
75
  mailbox when the mailbox is deallocated, it is an indication of a
76
  programming error in lwIP and the developer should be notified.
77
*/
78
void
79
sys_mbox_free(sys_mbox_t mbox)
80
{
81
        if( uxQueueMessagesWaiting( mbox ) )
82
        {
83
                /* Line for breakpoint.  Should never break here! */
84
                __asm volatile ( "NOP" );
85
        }
86
 
87
        vQueueDelete( mbox );
88
}
89
 
90
/*-----------------------------------------------------------------------------------*/
91
//   Posts the "msg" to the mailbox.
92
void
93
sys_mbox_post(sys_mbox_t mbox, void *data)
94
{
95
        xQueueSend( mbox, &data, ( portTickType ) ( archPOST_BLOCK_TIME_MS / portTICK_RATE_MS ) );
96
}
97
 
98
 
99
/*-----------------------------------------------------------------------------------*/
100
/*
101
  Blocks the thread until a message arrives in the mailbox, but does
102
  not block the thread longer than "timeout" milliseconds (similar to
103
  the sys_arch_sem_wait() function). The "msg" argument is a result
104
  parameter that is set by the function (i.e., by doing "*msg =
105
  ptr"). The "msg" parameter maybe NULL to indicate that the message
106
  should be dropped.
107
 
108
  The return values are the same as for the sys_arch_sem_wait() function:
109
  Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
110
  timeout.
111
 
112
  Note that a function with a similar name, sys_mbox_fetch(), is
113
  implemented by lwIP.
114
*/
115
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
116
{
117
void *dummyptr;
118
portTickType StartTime, EndTime, Elapsed;
119
 
120
        StartTime = xTaskGetTickCount();
121
 
122
        if( msg == NULL )
123
        {
124
                msg = &dummyptr;
125
        }
126
 
127
        if(     timeout != 0 )
128
        {
129
                if(pdTRUE == xQueueReceive( mbox, &(*msg), timeout ) )
130
                {
131
                        EndTime = xTaskGetTickCount();
132
                        Elapsed = EndTime - StartTime;
133
                        if( Elapsed == 0 )
134
                        {
135
                                Elapsed = 1;
136
                        }
137
                        return ( Elapsed );
138
                }
139
                else // timed out blocking for message
140
                {
141
                        *msg = NULL;
142
                        return SYS_ARCH_TIMEOUT;
143
                }
144
        }
145
        else // block forever for a message.
146
        {
147
                while( pdTRUE != xQueueReceive( mbox, &(*msg), 10000 ) ) // time is arbitrary
148
                {
149
                        ;
150
                }
151
                EndTime = xTaskGetTickCount();
152
                Elapsed = EndTime - StartTime;
153
                if( Elapsed == 0 )
154
                {
155
                        Elapsed = 1;
156
                }
157
                return ( Elapsed ); // return time blocked TBD test     
158
        }
159
}
160
 
161
/*-----------------------------------------------------------------------------------*/
162
//  Creates and returns a new semaphore. The "count" argument specifies
163
//  the initial state of the semaphore. TBD finish and test
164
sys_sem_t
165
sys_sem_new(u8_t count)
166
{
167
        xSemaphoreHandle  xSemaphore;
168
 
169
        portENTER_CRITICAL();
170
        vSemaphoreCreateBinary( xSemaphore );
171
        if(count == 0)   // Means it can't be taken
172
        {
173
                xSemaphoreTake(xSemaphore,1);
174
        }
175
        portEXIT_CRITICAL();
176
 
177
        if( xSemaphore == NULL )
178
        {
179
                return NULL;    // TBD need assert
180
        }
181
        else
182
        {
183
                return xSemaphore;
184
        }
185
}
186
 
187
/*-----------------------------------------------------------------------------------*/
188
/*
189
  Blocks the thread while waiting for the semaphore to be
190
  signaled. If the "timeout" argument is non-zero, the thread should
191
  only be blocked for the specified time (measured in
192
  milliseconds).
193
 
194
  If the timeout argument is non-zero, the return value is the number of
195
  milliseconds spent waiting for the semaphore to be signaled. If the
196
  semaphore wasn't signaled within the specified time, the return value is
197
  SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
198
  (i.e., it was already signaled), the function may return zero.
199
 
200
  Notice that lwIP implements a function with a similar name,
201
  sys_sem_wait(), that uses the sys_arch_sem_wait() function.
202
*/
203
u32_t
204
sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
205
{
206
portTickType StartTime, EndTime, Elapsed;
207
 
208
        StartTime = xTaskGetTickCount();
209
 
210
        if(     timeout != 0)
211
        {
212
                if( xSemaphoreTake( sem, timeout ) == pdTRUE )
213
                {
214
                        EndTime = xTaskGetTickCount();
215
                        Elapsed = EndTime - StartTime;
216
                        if( Elapsed == 0 )
217
                        {
218
                                Elapsed = 1;
219
                        }
220
                        return (Elapsed); // return time blocked TBD test       
221
                }
222
                else
223
                {
224
                        return SYS_ARCH_TIMEOUT;
225
                }
226
        }
227
        else // must block without a timeout
228
        {
229
                while( xSemaphoreTake( sem, 10000 ) != pdTRUE )
230
                {
231
                        ;
232
                }
233
                EndTime = xTaskGetTickCount();
234
                Elapsed = EndTime - StartTime;
235
                if( Elapsed == 0 )
236
                {
237
                        Elapsed = 1;
238
                }
239
 
240
                return ( Elapsed ); // return time blocked      
241
 
242
        }
243
}
244
 
245
/*-----------------------------------------------------------------------------------*/
246
// Signals a semaphore
247
void
248
sys_sem_signal(sys_sem_t sem)
249
{
250
        xSemaphoreGive( sem );
251
}
252
 
253
/*-----------------------------------------------------------------------------------*/
254
// Deallocates a semaphore
255
void
256
sys_sem_free(sys_sem_t sem)
257
{
258
        vQueueDelete( sem );
259
}
260
 
261
/*-----------------------------------------------------------------------------------*/
262
// Initialize sys arch
263
void
264
sys_init(void)
265
{
266
 
267
        int i;
268
 
269
        // Initialize the the per-thread sys_timeouts structures
270
        // make sure there are no valid pids in the list
271
        for(i = 0; i < SYS_THREAD_MAX; i++)
272
        {
273
                timeoutlist[i].pid = 0;
274
        }
275
 
276
        // keep track of how many threads have been created
277
        nextthread = 0;
278
}
279
 
280
/*-----------------------------------------------------------------------------------*/
281
/*
282
  Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
283
  each thread has a list of timeouts which is represented as a linked
284
  list of sys_timeout structures. The sys_timeouts structure holds a
285
  pointer to a linked list of timeouts. This function is called by
286
  the lwIP timeout scheduler and must not return a NULL value.
287
 
288
  In a single threaded sys_arch implementation, this function will
289
  simply return a pointer to a global sys_timeouts variable stored in
290
  the sys_arch module.
291
*/
292
struct sys_timeouts *
293
sys_arch_timeouts(void)
294
{
295
int i;
296
xTaskHandle pid;
297
struct timeoutlist *tl;
298
 
299
        pid = xTaskGetCurrentTaskHandle( );
300
 
301
        for(i = 0; i < nextthread; i++)
302
        {
303
                tl = &timeoutlist[i];
304
                if(tl->pid == pid)
305
                {
306
                        return &(tl->timeouts);
307
                }
308
        }
309
 
310
        // Error
311
        return NULL;
312
}
313
 
314
/*-----------------------------------------------------------------------------------*/
315
/*-----------------------------------------------------------------------------------*/
316
// TBD 
317
/*-----------------------------------------------------------------------------------*/
318
/*
319
  Starts a new thread with priority "prio" that will begin its execution in the
320
  function "thread()". The "arg" argument will be passed as an argument to the
321
  thread() function. The id of the new thread is returned. Both the id and
322
  the priority are system dependent.
323
*/
324
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
325
{
326
xTaskHandle CreatedTask;
327
int result;
328
static int iCall = 0;
329
 
330
        if( iCall == 0 )
331
        {
332
                /* The first time this is called we are creating the lwIP handler. */
333
                result = xTaskCreate( thread, ( signed char * ) "lwIP", lwipTCP_STACK_SIZE, arg, prio, &CreatedTask );
334
                iCall++;
335
        }
336
        else
337
        {
338
                result = xTaskCreate( thread, ( signed char * ) "WEBSvr", lwipBASIC_SERVER_STACK_SIZE, arg, prio, &CreatedTask );
339
        }
340
 
341
        // For each task created, store the task handle (pid) in the timers array.
342
        // This scheme doesn't allow for threads to be deleted
343
        timeoutlist[nextthread++].pid = CreatedTask;
344
 
345
        if(result == pdPASS)
346
        {
347
                return CreatedTask;
348
        }
349
        else
350
        {
351
                return NULL;
352
        }
353
}
354
 
355
/*
356
  This optional function does a "fast" critical region protection and returns
357
  the previous protection level. This function is only called during very short
358
  critical regions. An embedded system which supports ISR-based drivers might
359
  want to implement this function by disabling interrupts. Task-based systems
360
  might want to implement this by using a mutex or disabling tasking. This
361
  function should support recursive calls from the same task or interrupt. In
362
  other words, sys_arch_protect() could be called while already protected. In
363
  that case the return value indicates that it is already protected.
364
 
365
  sys_arch_protect() is only required if your port is supporting an operating
366
  system.
367
*/
368
sys_prot_t sys_arch_protect(void)
369
{
370
        vPortEnterCritical();
371
        return 1;
372
}
373
 
374
/*
375
  This optional function does a "fast" set of critical region protection to the
376
  value specified by pval. See the documentation for sys_arch_protect() for
377
  more information. This function is only required if your port is supporting
378
  an operating system.
379
*/
380
void sys_arch_unprotect(sys_prot_t pval)
381
{
382
        ( void ) pval;
383
        vPortExitCritical();
384
}
385
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.