no answers.... so.... UP!!! :O)

2008/2/18, Piero 74 <[EMAIL PROTECTED]>:
>
> Hi all!
>
> i wrote sys_arch.c for lwip 130rc1 and freertos.
>
>
> Anyone could give me his opinion? Is it right or it could have bugs?
>
> Thanks, Piero.
>
> here it's the file:
>
>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
> /*
>  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
>  * All rights reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
> modification,
>  * are permitted provided that the following conditions are met:
>  *
>  * 1. Redistributions of source code must retain the above copyright
> notice,
>  *    this list of conditions and the following disclaimer.
>  * 2. Redistributions in binary form must reproduce the above copyright
> notice,
>  *    this list of conditions and the following disclaimer in the
> documentation
>  *    and/or other materials provided with the distribution.
>  * 3. The name of the author may not be used to endorse or promote
> products
>  *    derived from this software without specific prior written
> permission.
>  *
>  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
>  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
>  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
>  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL,
>  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
>  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
>  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
>
>  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
>  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
>  * OF SUCH DAMAGE.
>  *
>  * This file is part of the lwIP TCP/IP stack.
>  *
>  * Author: Adam Dunkels <[EMAIL PROTECTED]>
>  *
>  */
>
> /* lwIP includes. */
> #include "lwip/debug.h"
> #include "lwip/def.h"
> #include "lwip/sys.h"
> #include "lwip/mem.h"
> #include "arch/sys_arch.h"
>
> // FREERTOS
> #include "FreeRTOS.h"
> #include "queue.h"
> #include "task.h"
>
> /* Message queue constants. */
> #define archMESG_QUEUE_LENGTH    ( 8 )                             //
> default if TCPIP_MBOX_SIZE is undefined
> #define archPOST_BLOCK_TIME_MS    ( ( unsigned portLONG ) 100 )
>
> struct timeoutlist
> {
>     struct sys_timeouts timeouts;
>     xTaskHandle pid;
> };
>
> // piero
> /* This is the number of threads that can be started with sys_thread_new()
> */
> #define SYS_THREAD_MAX                  7
>
> #define lwipTCP_STACK_SIZE        600
> #define lwipBASIC_SERVER_STACK_SIZE    150
>
> #define LWIPARCH_NOTIMEOUTMS 100      // every LWIPARCH_NOTIMEOUTMS ms a
> blocking while loop calls user function
> //
>
> // global vars
> static struct timeoutlist aTimeoutlist[SYS_THREAD_MAX];
> static struct sys_timeouts null_timeouts;
> static u16_t nextthread = 0;
>
>
>
> /*-----------------------------------------------------------------------------------*/
> // Initialize sys arch
> // Is called to initialize the sys_arch layer.
> void
> sys_init(void)
> {
>
>     int i;
>
>     // Initialize the the per-thread sys_timeouts structures
>     // make sure there are no valid pids in the list
>     for(i = 0; i < SYS_THREAD_MAX; i++)
>     {
>         aTimeoutlist[i].pid = 0;
>     }
>
>     // keep track of how many threads have been created
>     nextthread = 0;      // #piero#
> }
>
>
> /*-----------------------------------------------------------------------------------*/
> //  Creates and returns a new semaphore. The "count" argument specifies
> //  the initial state of the semaphore. TBD finish and test
> sys_sem_t
> sys_sem_new(u8_t count)
> {
>     xSemaphoreHandle  xSemaphore;
>
>     portENTER_CRITICAL();
>     vSemaphoreCreateBinary( xSemaphore );
>
>   if(xSemaphore == NULL) // Check here for semaphore successfull creation
>     return NULL;
>
>     if(count == 0)    // Means it can't be taken
>     {
>         xSemaphoreTake(xSemaphore,1);
>     }
>     portEXIT_CRITICAL();
>
>     if( xSemaphore == NULL )
>     {
>         return NULL;    // TBD need assert  #piero# lwip debug msg
>     }
>     else
>     {
>         return xSemaphore;
>     }
> }
>
>
> /*-----------------------------------------------------------------------------------*/
> // Deallocates a semaphore
> void
> sys_sem_free(sys_sem_t sem)
> {
>     vQueueDelete( sem );
> }
>
>
>
> /*-----------------------------------------------------------------------------------*/
> // Signals a semaphore
> void
> sys_sem_signal(sys_sem_t sem)
> {
>     xSemaphoreGive( sem );
> }
>
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   Blocks the thread while waiting for the semaphore to be
>   signaled. If the "timeout" argument is non-zero, the thread should
>   only be blocked for the specified time (measured in
>   milliseconds).
>
>   If the timeout argument is non-zero, the return value is the number of
>   milliseconds spent waiting for the semaphore to be signaled. If the
>   semaphore wasn't signaled within the specified time, the return value is
>   SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
>   (i.e., it was already signaled), the function may return zero.
>
>   Notice that lwIP implements a function with a similar name,
>   sys_sem_wait(), that uses the sys_arch_sem_wait() function.
> */
> u32_t
> sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
> {
> portTickType StartTime, EndTime, Elapsed;
>
>     StartTime = xTaskGetTickCount();
>
>     if(    timeout != 0)
>     {
>         if( xSemaphoreTake( sem, timeout * portTICK_RATE_MS) == pdTRUE )
>         {
>             EndTime = xTaskGetTickCount();
>             Elapsed = EndTime - StartTime;
>             if( Elapsed == 0 )
>             {
>                 Elapsed = 1;
>             }
>             return (Elapsed); // return time blocked
>         }
>         else
>         {
>             return SYS_ARCH_TIMEOUT;
>         }
>     }
>     else // must block without a timeout
>     {
>         while( xSemaphoreTake( sem, LWIPARCH_NOTIMEOUTMS *
> portTICK_RATE_MS) != pdTRUE )
>         {
>             // loop for ever - call user function
>       LWIP_BLOCKWHILECALLBACK;
>         }
>         EndTime = xTaskGetTickCount();
>         Elapsed = EndTime - StartTime;
>         if( Elapsed == 0 )
>         {
>             Elapsed = 1;
>         }
>
>         return ( Elapsed ); // return time blocked
>     }
> }
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*  Creates an empty mailbox.
> Creates an empty mailbox for maximum "size" elements. Elements stored
> in mailboxes are pointers. You have to define macros "_MBOX_SIZE"
> in your lwipopts.h, or ignore this parameter in your implementation
> and use a default size.
> */
> /**
>  * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages
>  * The queue size value itself is platform-dependent, but is passed to
>  * sys_mbox_new() when tcpip_init is called.
>  * ----> MUST BE DEFINED in lwipopts.h, default value is 0 ---> mbox will
> create using
>  */
>
>
> sys_mbox_t
> sys_mbox_new(int size)
> {
>     xQueueHandle mbox;
>
>   size = (size) ? size : archMESG_QUEUE_LENGTH; // if size = 0, use
> costant
>     mbox = xQueueCreate( size, sizeof( void * ) );
>
>     return mbox;
> }
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   Deallocates a mailbox. If there are messages still present in the
>   mailbox when the mailbox is deallocated, it is an indication of a
>   programming error in lwIP and the developer should be notified.
> */
> void
> sys_mbox_free(sys_mbox_t mbox)
> {
>     if( uxQueueMessagesWaiting( mbox ) )
>     {
>         /* Line for breakpoint.  Should never break here! */
>         __asm ( "NOP" );
>     }
>
>     vQueueDelete( mbox );
> }
>
>
> /*-----------------------------------------------------------------------------------*/
> /* Posts the "msg" to the mailbox. This function have to block until
>    the "msg" is really posted.
> */
> void
> sys_mbox_post(sys_mbox_t mbox, void *data)
> {
>   if(mbox != NULL)
>   {
>       while (xQueueSend( mbox, &data, ( portTickType ) (
> archPOST_BLOCK_TIME_MS * portTICK_RATE_MS ) ) =! pdTRUE)
>       {
>         // loop for ever
>         // if task blocks here for a long time: error. External actions
> are needed!
>       }
>   }
> }
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /* Try to post the "msg" to the mailbox. Returns ERR_MEM if this one
>    is full, else, ERR_OK if the "msg" is posted.
> */
>
> err_t
> sys_mbox_trypost(sys_mbox_t mbox, void *msg)
> {
>   if(mbox != NULL)
>   {
>       // try post without timeout
>       if (xQueueSend( mbox, &data, ( portTickType ) 0 ) == pdTRUE)
>       {
>       return(ERR_OK);
>       }else
>       {
>         return(ERR_MEM);
>       }
>   }
> }
>
>
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   Blocks the thread until a message arrives in the mailbox, but does
>   not block the thread longer than "timeout" milliseconds (similar to
>   the sys_arch_sem_wait() function). The "msg" argument is a result
>   parameter that is set by the function (i.e., by doing "*msg =
>   ptr"). The "msg" parameter maybe NULL to indicate that the message
>   should be dropped.
>
>   The return values are the same as for the sys_arch_sem_wait() function:
>   Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
>   timeout.
>
>   Note that a function with a similar name, sys_mbox_fetch(), is
>   implemented by lwIP.
> */
> u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
> {
> void *dummyptr;
> portTickType StartTime, EndTime, Elapsed;
>
>     StartTime = xTaskGetTickCount();
>
>     if( msg == NULL )
>     {
>         msg = &dummyptr;
>     }
>
>     if(    timeout != 0 )
>     {
>         if(pdTRUE == xQueueReceive( mbox, &(*msg), timeout *
> portTICK_RATE_MS) )
>         {
>             EndTime = xTaskGetTickCount();
>             Elapsed = EndTime - StartTime;
>             if( Elapsed == 0 )
>             {
>                 Elapsed = 1;
>             }
>             return ( Elapsed );
>         }
>         else // timed out blocking for message
>         {
>             *msg = NULL;
>             return SYS_ARCH_TIMEOUT;
>         }
>     }
>     else // block forever for a message.
>     {
>         while( pdTRUE != xQueueReceive( mbox, &(*msg),
> LWIPARCH_NOTIMEOUTMS * portTICK_RATE_MS) )
>         {
>             // loop for ever - call user function
>       LWIP_BLOCKWHILECALLBACK;
>         }
>         EndTime = xTaskGetTickCount();
>         Elapsed = EndTime - StartTime;
>         if( Elapsed == 0 )
>         {
>             Elapsed = 1;
>         }
>         return ( Elapsed ); // return time blocked
>     }
> }
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   This is similar to sys_arch_mbox_fetch, however if a message is not
>   present in the mailbox, it immediately returns with the code
>   SYS_MBOX_EMPTY. On success 0 is returned.
>
>   To allow for efficient implementations, this can be defined as a
>   function-like macro in sys_arch.h instead of a normal function. For
>   example, a naive implementation could be:
>     #define sys_arch_mbox_tryfetch(mbox,msg) \
>       sys_arch_mbox_fetch(mbox,msg,1)
>   although this would introduce unnecessary delays.
> */
>
> u32_t
> sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg)
> {
> void *dummyptr;
>
>     if( msg == NULL )
>     {
>         msg = &dummyptr;
>     }
>
>   // try fetch without block
>     if(pdTRUE == xQueueReceive( mbox, &(*msg), 0) )
>     {
>         return ( 0 );
>     }
>     else // no blocking for message
>     {
>         return SYS_MBOX_EMPTY;
>     }
> }
>
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
>   each thread has a list of timeouts which is represented as a linked
>   list of sys_timeout structures. The sys_timeouts structure holds a
>   pointer to a linked list of timeouts. This function is called by
>   the lwIP timeout scheduler and must not return a NULL value.
>
>   In a single threaded sys_arch implementation, this function will
>   simply return a pointer to a global sys_timeouts variable stored in
>   the sys_arch module.
> */
> struct sys_timeouts *
> sys_arch_timeouts(void)
> {
> int i;
> xTaskHandle pid;
> struct timeoutlist *tl;
>
>     pid = xTaskGetCurrentTaskHandle( );
>
>     for(i = 0; i < nextthread; i++)
>     {
>         tl = &aTimeoutlist[i];
>         if(tl->pid == pid)
>         {
>             return &(tl->timeouts);
>         }
>     }
>
>     // if here: pid not found - return null_timeouts
>     return null_timeouts;
> }
>
>
>
>
> /*-----------------------------------------------------------------------------------*/
> /*
>   Starts a new thread named "name" with priority "prio" that will begin
> its
>   execution in the function "thread()". The "arg" argument will be passed
> as an
>   argument to the thread() function. The stack size to used for this
> thread is
>   the "stacksize" parameter. The id of the new thread is returned. Both
> the id
>   and the priority are system dependent.
> */
> sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void
> *arg, int stacksize, int prio)
> {
> xTaskHandle CreatedTask;
> int result;
>
>   // create task
>   result = xTaskCreate( thread, ( const signed portCHAR * const ) name,
> stacksize, arg, prio, &CreatedTask );
>
>     // For each task created, store the task handle (pid) in the timers
> array.
>     // This scheme doesn't allow for threads to be deleted
>     nextthread++;
>   if (nextthread == SYS_THREAD_MAX)
>     return(NULL); // not enough space for thread!!
>
>     aTimeoutlist[].pid = CreatedTask;
>
>     if(result == pdPASS)
>     {
>         return CreatedTask;
>     }
>     else
>     {
>         return NULL;
>     }
> }
>
> /*
>   This optional function does a "fast" critical region protection and
> returns
>   the previous protection level. This function is only called during very
> short
>   critical regions. An embedded system which supports ISR-based drivers
> might
>   want to implement this function by disabling interrupts. Task-based
> systems
>   might want to implement this by using a mutex or disabling tasking. This
>   function should support recursive calls from the same task or interrupt.
> In
>   other words, sys_arch_protect() could be called while already protected.
> In
>   that case the return value indicates that it is already protected.
>
>   sys_arch_protect() is only required if your port is supporting an
> operating
>   system.
> */
> sys_prot_t sys_arch_protect(void)
> {
>     vPortEnterCritical();
>     return 1;
> }
>
> /*
>   This optional function does a "fast" set of critical region protection
> to the
>   value specified by pval. See the documentation for sys_arch_protect()
> for
>   more information. This function is only required if your port is
> supporting
>   an operating system.
> */
> void sys_arch_unprotect(sys_prot_t pval)
> {
>     ( void ) pval;
>     vPortExitCritical();
> }
>
>
>
_______________________________________________
lwip-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/lwip-users

Reply via email to