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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [ARM9_STR91X_IAR/] [lwip/] [api/] [sys_arch.c] - Blame information for rev 577

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 577 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
#include <stdio.h>
40
 
41
/* Message queue constants. */
42
#define archMESG_QUEUE_LENGTH   ( 6 )
43
#define archPOST_BLOCK_TIME_MS  ( ( unsigned long ) 10000 )
44
 
45
struct timeoutlist
46
{
47
        struct sys_timeouts timeouts;
48
        xTaskHandle pid;
49
};
50
 
51
/* This is the number of threads that can be started with sys_thread_new() */
52
#define SYS_THREAD_MAX 4
53
 
54
static struct timeoutlist timeoutlist[SYS_THREAD_MAX];
55
static u16_t nextthread = 0;
56
int intlevel = 0;
57
 
58
static sys_arch_state_t s_sys_arch_state;
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
        s_sys_arch_state.nTaskCount = 0;
280
        sys_set_default_state();
281
}
282
 
283
/*-----------------------------------------------------------------------------------*/
284
/*
285
  Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
286
  each thread has a list of timeouts which is represented as a linked
287
  list of sys_timeout structures. The sys_timeouts structure holds a
288
  pointer to a linked list of timeouts. This function is called by
289
  the lwIP timeout scheduler and must not return a NULL value.
290
 
291
  In a single threaded sys_arch implementation, this function will
292
  simply return a pointer to a global sys_timeouts variable stored in
293
  the sys_arch module.
294
*/
295
struct sys_timeouts *
296
sys_arch_timeouts(void)
297
{
298
int i;
299
xTaskHandle pid;
300
struct timeoutlist *tl;
301
 
302
        pid = xTaskGetCurrentTaskHandle( );
303
 
304
        for(i = 0; i < nextthread; i++)
305
        {
306
                tl = &timeoutlist[i];
307
                if(tl->pid == pid)
308
                {
309
                        return &(tl->timeouts);
310
                }
311
        }
312
 
313
        // Error
314
        return NULL;
315
}
316
 
317
/*-----------------------------------------------------------------------------------*/
318
/*-----------------------------------------------------------------------------------*/
319
// TBD
320
/*-----------------------------------------------------------------------------------*/
321
/*
322
  Starts a new thread with priority "prio" that will begin its execution in the
323
  function "thread()". The "arg" argument will be passed as an argument to the
324
  thread() function. The id of the new thread is returned. Both the id and
325
  the priority are system dependent.
326
*/
327
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
328
{
329
xTaskHandle CreatedTask;
330
int result;
331
 
332
        result = xTaskCreate(thread, ( signed char * ) s_sys_arch_state.cTaskName, s_sys_arch_state.nStackDepth, arg, prio, &CreatedTask );
333
 
334
        // For each task created, store the task handle (pid) in the timers array.
335
        // This scheme doesn't allow for threads to be deleted
336
        timeoutlist[nextthread++].pid = CreatedTask;
337
 
338
        if(result == pdPASS)
339
        {
340
                ++s_sys_arch_state.nTaskCount;
341
 
342
                return CreatedTask;
343
        }
344
        else
345
        {
346
                return NULL;
347
        }
348
}
349
 
350
/*
351
  This optional function does a "fast" critical region protection and returns
352
  the previous protection level. This function is only called during very short
353
  critical regions. An embedded system which supports ISR-based drivers might
354
  want to implement this function by disabling interrupts. Task-based systems
355
  might want to implement this by using a mutex or disabling tasking. This
356
  function should support recursive calls from the same task or interrupt. In
357
  other words, sys_arch_protect() could be called while already protected. In
358
  that case the return value indicates that it is already protected.
359
 
360
  sys_arch_protect() is only required if your port is supporting an operating
361
  system.
362
*/
363
sys_prot_t sys_arch_protect(void)
364
{
365
        vPortEnterCritical();
366
        return 1;
367
}
368
 
369
/*
370
  This optional function does a "fast" set of critical region protection to the
371
  value specified by pval. See the documentation for sys_arch_protect() for
372
  more information. This function is only required if your port is supporting
373
  an operating system.
374
*/
375
void sys_arch_unprotect(sys_prot_t pval)
376
{
377
        ( void ) pval;
378
        vPortExitCritical();
379
}
380
 
381
void sys_set_default_state()
382
{
383
        s_sys_arch_state.nStackDepth = configMINIMAL_STACK_SIZE;
384
        sprintf(s_sys_arch_state.cTaskName, "thread%d", s_sys_arch_state.nTaskCount);
385
}
386
 
387
void sys_set_state(signed char *pTaskName, unsigned short nStackSize)
388
{
389
        s_sys_arch_state.nStackDepth = nStackSize;
390
        sprintf(s_sys_arch_state.cTaskName, "%s", pTaskName);
391
}

powered by: WebSVN 2.1.0

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