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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [lwIP_AVR32_UC3/] [NETWORK/] [lwip-port/] [AT32UC3A/] [sys_arch.c] - Blame information for rev 583

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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