lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] threading....


From: Christiaan Simons
Subject: Re: [lwip-users] threading....
Date: Fri, 17 Sep 2004 17:40:00 +0200

On Fri, 2004-09-17 at 15:09, Eric Shufro wrote:

> Main() initializes the OS and creates 2 tasks. 1 called AppStartTask, and
> another which is the CS8900 interrupt handler. :
> 
>     OSInit();
> 
>     sys_init();
>     mem_init();
>     memp_init();
>     pbuf_init();
>      
>     printf("System initialized.\n\x0a");
> 
>     sys_thread_new(AppStartTask,  AppStartTask,  TASK_START_PRIO);
>     sys_thread_new(ServiceCS8900, ServiceCS8900 ,TASK_START_PRIO); 
> 

You may not create tasks with equal priority in uCOS...

>     EnableInterrupts;

Interrupt enable is done after OSTickISRInit() !!

>     OSStart();                              
> 
> //----------------------------------------------------------------------
> 
> AppStartTask initializes LWIP and the system ticker and blinks and LED
> indefinitely like so:
> 
> As you can see, AppStartTask initializes / creates yet another task, the
> TCPIP_Thread().
> 
> struct ip_addr ipaddr, netmask, gw;
> sys_sem_t sem;
> struct netif *pstNetif;
> 
>   (void)p_arg; 
>   
>   OSTickISR_Init();               
> 
>   sem = sys_sem_new(0);  
>   tcpip_init(tcpip_init_done, &sem);
>   sys_sem_wait(sem);
>   sys_sem_free(sem);
>   printf("TCP/IP initialized.\n\x0a");
>   
>   netif_init();
> 
>   IP4_ADDR(&gw, 192,168,0,1);
>   IP4_ADDR(&ipaddr, 192,168,0,103);
>   IP4_ADDR(&netmask, 255,255,255,0);
> 
>   pstNetif = netif_add(&pstNetif, &ipaddr, &netmask, &gw, NULL,        
>   cs8900if_init, ip_input);
>   LWIP_ASSERT("TaskStart: netif_add error, pstNetif != 0\n", pstNetif != 0);
>   netif_set_default(pstNetif);
> 
>   printf("netif initialized, toggling led now\n\x0a");
>   while (TRUE) 
>   {
>       LED_Toggle(4);
>       OSTimeDly(OS_TICKS_PER_SEC);
>   }
> 
> //----------------------------------------------------------------------
> 
> Additionally, when an interrupt occurs, the ISR disables the CS8900
> interrupt pin, and posts a semaphore to the CS8900 interrupt hander which
> runs, re-enables interrupts, and then pends again when complete.
> 
>   INT16U isq_data;         
>   extern struct netif *pstNetif;
>   
>   cs8900sem = sys_sem_new(0);             
>    
>    printf("CS8900 Interrupt Handler starting...\n");
>    
>    while(1)
>    {
>       printf("interrupt handler now asleep\n\x0a");
>       sys_sem_wait(cs8900sem);
>       printf("interrupt handler now awake\n\x0a");
>                    
>       do
>       {
>          isq_data = IORead(CS8900_ISQ) >> 8;
>                          
>          switch(isq_data & 0x3f)
>          {
>             case 0x00:        //isq is empty. exit.
>                break;
>             case 0x04:        //receieve event
> cs8900if_input(&pstNetif);
>                break;
>             case 0x08:                //transmit event
>                break;
>             case 0x0C:                //buffer event  
>                break;
>             case 0x10:                //receiver miss event              
>                  break;
>             case 0x12:                //transmit collision event
>                break;
>             default:
> 
>                break;
>          } 
>       }while(isq_data != 0);        
>       
>       INTCR = 0x40;                       //re-enable interrupts      
> 

Is this really the interrupt mask, or just the pin?
You should mask the interrupt registers only.

> So anyway, with this scheme, it seems that there could be problems when the
> ISR handler is reading in a packet, and if the stack wanted to write one at
> the same time. So, the threads need to be synchronized with another
> semaphore to block even the arp routine from sending an arp response when
> the interrupt handler is running..
> 
> I believe that could be part of the reason why the system is crashing?? Im
> not completely sure yet.

This is possible yes. You can protect
your do while loop with a  semaphore,
or preferably a mutex. Also lock the mutex
from the other task before entering the critical code.

Also allways check the uCOS return values (assert() them)
since they give clear indication of whats happening.
(it worked for me in the past)

> 
> Additionally, where in this model would I call the lwip timers?
> 
> Should that be done from one of the existing threads, or put all the timers
> into 1 new thread and use the OSTimeDelay() - Which wouldn't exactly work
> since a delay of 1 second would cause the finer timers to not get called..
> 

You could try using hw timers, or alternatively you
could try Leon's uCOS Alarms extension.
(http://www.esrac.ele.tue.nl/~leon/ucos/)

I would just group all lwip background stuff
(including cs8900 driver and timers) into one task.

Otherwise you'll end up with a lot of task switching
overhead for your network functionality.

Bye,

Christiaan.


The information contained in this communication is confidential and is intended 
solely for the use of the individual or entity to whom it is addressed. Axon 
Digital Design Group is neither liable for the proper nor for the complete 
transmission of the information contained in this communication nor for any 
delay in its receipt. Axon Digital Design Group does not guarantee that the 
integrity of this communication has been maintained nor that the communication 
is free of viruses, interceptions or interference. If you are not the intended 
recipient of this communication, you are hereby notified that reading, 
disseminating, distributing or copying this message is strictly prohibited. In 
that case please return the communication to the sender and delete and destroy 
all copies. In carrying out its engagements, Axon Digital Design Group applies 
general terms and conditions, which contain a clause that limits its liability. 
A copy of these terms and conditions is available on request free of charge.







reply via email to

[Prev in Thread] Current Thread [Next in Thread]