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