CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

can i put delay after calling stacktask of TCP/IP?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCH poker
Guest







can i put delay after calling stacktask of TCP/IP?
PostPosted: Fri Jul 23, 2004 3:58 am     Reply with quote

Hi,
There, i am just doing a project on microchip tcp/ip protocol stack, for the whole protocol seems ok, but if i call some operating funcitons with delay after i routinely call StackTask function, the TCP/IP protocol stack seems not working at all, the MCU cannot get the data which sent out from the server (but the data did reach the receive PIN of my MCU), of course didnt response ACK back to the server. The TcpIsGetReady() function will never return TRUE value.

Anyone can help?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Jul 23, 2004 11:33 am     Reply with quote

You can ask this question here, but often you will get the best anwers when asking the question at the website of the creator of your product. For this TCP/IP stack that would be: http://forum.microchip.com/default.asp
Guest








PostPosted: Sat Jul 24, 2004 7:05 am     Reply with quote

How long is your delay ? In case of heavy network traffic, the 8019AS might get overrun.
PCH poker
Guest







PostPosted: Mon Jul 26, 2004 2:56 am     Reply with quote

Hi,
Guys, thanks for ur reply!

I know that the best way is that i design my application code in a "state machine" fashion, but the porblem is that my app seems quite complex to design in this cos there is one more terminal need to be communicated through one more modem. so i have to keep polling the modem and wait for the reply ... ... And the delay time at least has to be 20ms!
Ttelmah
Guest







PostPosted: Mon Jul 26, 2004 4:27 am     Reply with quote

PCH [spam] wrote:
Hi,
Guys, thanks for ur reply!

I know that the best way is that i design my application code in a "state machine" fashion, but the porblem is that my app seems quite complex to design in this cos there is one more terminal need to be communicated through one more modem. so i have to keep polling the modem and wait for the reply ... ... And the delay time at least has to be 20ms!

Di it as a multi-layer state machine, with a timer interrupt.
So you can have a 'main' state loop, which steps through the various functions needed, as fast as possible. One of these states, is 'poll_modem'. Inside this state, you have a second 'state' counter (pollstate), with the frst entry, sending the poll string, and resetting a timer, set to give 20mSec (or if you allready have a faster timer, set a 'counter', which decrements in this). The 'pollstate' then advances, and you go back to looping the main state machine. Then on each entry to the 'poll_modem' state, check if the timer has expired, and exit if not.
Once the timer reaches zero, you check if there has been a reply. If so, you advance to the next 'pollstate' entry, and start talking to the modem. If not, you set the pollstate back to zero, so that on the next loop, the transmission will retry.
With the combination of 'layered' state machines, hardware timers, and interrupt driven I/O buffering, you can have multiple tasks, relatively 'unaffected' by what else the system is doig (you have to be careful to keep the loop times short).

Best Wishes
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Tue Jul 27, 2004 3:58 am     Reply with quote

Hi,
Ttelmah, I have tried the way u have suggested, but seems quite complex due to the actual situation. One more obstacle is that the stack task of TCP/IP protocol which need to be called routinely is not a "pure state machine" as following:

Code:

void StackTask(void)
{
    static NODE_INFO remoteNode;
    static int16 dataCount;
    IP_ADDR tempLocalIP;
    union
    {
        int8 MACFrameType;
        int8 IPFrameType;
    } type;
    int1 lbContinue;
    lbContinue = TRUE;
    while( lbContinue )
    {
        lbContinue = FALSE;
        switch(smStack)
        {
        case SM_STACK_IDLE:
        case SM_STACK_MAC:
            if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) )
                break;
            lbContinue = TRUE;
            if ( type.MACFrameType == MAC_IP )
            {
                smStack = SM_STACK_IP;
            }
            else {
                MACDiscardRx();
            }
            break;
        case SM_STACK_IP:
            if ( IPGetHeader(&tempLocalIP, &remoteNode, &type.IPFrameType, &dataCount) )
            {
                lbContinue = TRUE;
                if ( type.IPFrameType == IP_PROT_TCP )
                {
                    smStack = SM_STACK_TCP;
                }
                else
                {
                    lbContinue = FALSE;
                    MACDiscardRx();
                    smStack = SM_STACK_IDLE;
                }
            }
            else
            {
                MACDiscardRx();
                smStack = SM_STACK_IDLE;
            }
            break;
        case SM_STACK_TCP:
            if ( TCPProcess(&remoteNode, dataCount) )
                smStack = SM_STACK_IDLE;
            lbContinue = FALSE;
            break;
        }

    }
    TCPTick();
}



from the above, the while loop seems not absolutely breaks, it has to wait until the whole cycle "MAC --- IP --- TCP" finish, then it will break. so if i use a timer interrupt with 10us to call the stacktask, still not working!

Any good idea? (or can this stacktask be changed into "pure state machine"?)
Thanks!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Jul 27, 2004 6:15 am     Reply with quote

Quote:
so if i use a timer interrupt with 10us to call the stacktask, still not working!


I believe you missed his point. He was trying to say to do something like this:

Code:


// define a 2 second timeout value
#define MODEM_CMD_TIMEOUT   ((TICK)TICK_SECOND * (TICK)2)

typedef enum _SM_MODEM
{
    SM_MODEM_IDLE,
    SM_MODEM_TRANSMIT,
    SM_MODEM_WAIT,
} SM_MODEM;
static SM_MODEM smModem;

void ModemTask(void)
{

  static TICK startTick;
  TICK diffTicks;
  TICK tick;

  switch (smModem)
  {
    case SM_MODEM_IDLE:
      break;
    case SM_MODEM_TRANSMIT:
      // Send Modem Command
     SendSomeModemCommand();
      smModem = SM_MODEM_WAIT;
      // Get the current tick count
      startTick = TickGet();
      break;
    case SM_MODEM_WAIT:

      tick = TickGet();
      // Calculate timeout value
      diffTicks = TickGetDiff(tick, startTick);

      // If timeout has not occured, do not do anything.
      if ( diffTicks >= MODEM_CMD_TIMEOUT)
      {
       // Handle the timeout
        if ( CommandSendGood )
          smModem = SM_MODEM_IDLE;
        else
          smModem = SM_MODEM_TRANSMIT;

     }
      break;
    default:
  }
}
   
void main(void)
{
  InitEverything();
     
  while(1)
  {
     /*
      * This task performs normal stack task including checking
      * for incoming packet, type of packet and calling
      * appropriate stack entity to process it.
      */
     StackTask();

     /*
      * This is a TCP application.  It listens to TCP port 80
      * with one or more sockets and responds to remote requests.
      */
     HTTPServer();

     FTPServer();

     /*
      * This is a SMTP application.  It sends an email after
      * a call to SMTPSend_Mail_To()
      */
     SMTPClient();

     /*
      * In future, as new TCP/IP applications are written, it
      * will be added here as new tasks.
      */

     /*
      * Add your application speicifc tasks here.
      */
     ProcessIO();

     ModemTask();

     /*
      * For DHCP information, display how many times we have renewed the IP
      * configuration since last reset.
      */
     if ( DHCPBindCount != myDHCPBindCount )
     {
       DisplayIPValue(&AppConfig.MyIPAddr, TRUE);
       myDHCPBindCount = DHCPBindCount;
     }
  }
}
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Tue Jul 27, 2004 7:36 pm     Reply with quote

Hi,
Mark, thanks for ur reply!
The problem is that the following part at least i need 20 ms time's delay(due to the complexity of my i/o application).
Quote:

/*
* In future, as new TCP/IP applications are written, it
* will be added here as new tasks.
*/

/*
* Add your application speicifc tasks here.
*/
ProcessIO();

ModemTask();


but the StackTask() event not allow me one ms delay!
So for my situation, got any suggestion?

Thanx!
Guest








PostPosted: Tue Jul 27, 2004 8:05 pm     Reply with quote

I modified TCP/IP Lean's procedure as:

if ( got_TCP_ACK_from_remote_SERVER ) ProcessIO();

It works fine even if ProcessIO() takes 2000 msec !

Otherwise, if ProcessIO() is called everytime in the while() loop and it takes 30 msec, then the RTL8019 will for sure got overrun due to the heavy traffic on the Ethernet.
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Wed Jul 28, 2004 3:16 am     Reply with quote

Hi,
Thanks for ur reply!
How do u set the flag of "got_TCP_ACK_from_remote_SERVER"?
Is it according to smState == TCP_SYN_RCVD ?

Rgds!
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Wed Jul 28, 2004 3:30 am     Reply with quote

Hi,
It is so nice, it really works!


Many many thanx! Laughing
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Wed Jul 28, 2004 4:38 am     Reply with quote

Hi,
Sorry, it seems not working again!

Seems the condition never get TRUE if i use smState==TCP_SYN_RCVD.

Any more suggestion?
Thx!
Guest








PostPosted: Wed Jul 28, 2004 6:55 am     Reply with quote

puppie7777 wrote:
Hi,
Sorry, it seems not working again!

Seems the condition never get TRUE if i use smState==TCP_SYN_RCVD.

Any more suggestion?
Thx!


You should check TCP_SYN_ACK_RCVD_from_remote_server.

I am using Iosoft's code written in CCS, let's try to start from the very beginning.

1. Normallly the StackTask(), checking for incoming packet, has to be called every 10 msec or less. However, ProcessIO() needs 100 msec.

2. Your PIC is the TCP_client, it send out a TCP_SYN to the remote server as the first step to establish communication.

3. The remote TCP_server (say, a PC) received the TCP_SYN, and replied with a TCP_SYN_ACK.

4. Your PIC got this TCP_SYN_ACK from the remote server, now, it is time to do the time consuming job ProcessIO(), 100 ms, 500 ms what ever. The NIC (RTL8019AS) might got overrun during this period by some other incoming or broadcasting message, that's ok, your PIC got the SYN_ACK from remote server, and the remote server will wait for your PIC to reply, it can wait for up to serval seconds (depends on the timeout setup of the server, typically 3 ~ 60 sec ?).

5. When ProcessIO() is completed, the while(1) loop goes back to StackTask(), it should reset RTL8019 if necessary (in case of overrun), then send out the message collected by ProcessIO() to the remote server.

That's how it works for me.

What needs to be checked is the flag of TCP_SYN_ACK_RCVD_from_remote_server, then it is the time to do ProcessIO(). I don't know if Microchip's TCP/IP stack has this flag, it should, otherwise it will be a big defect.

Best wishes
Guest








PostPosted: Wed Jul 28, 2004 7:30 am     Reply with quote

Based on AN833, page 46, there are two possible timing for ProcessIO(), try this:

Code:

case SM_CONNECT_WAIT:

   // Wait for connection ... <-- waiting for SYN_ACK from remote server !

   if ( TCPIsConnected (tcp_Socket) )
   {
      smState = SM_CONNECTED;

      ProcessIO();  // do it here, when SYN_ACK is just received
   }
   return;

case SM_CONNECTED:

   ProcessIO();  // or, do it here, right before sending data out

   // Send data
   ...
   // Disconnect
   TCPDisconnect( tcp_Socket );


Best wishes[/code]
puppie7777



Joined: 09 Jun 2004
Posts: 25
Location: Monterey, CA

View user's profile Send private message

PostPosted: Wed Jul 28, 2004 7:36 pm     Reply with quote

Hi,
So many thanx for ur reply!
As u said:
Quote:

1. Normallly the StackTask(), checking for incoming packet, has to be called every 10 msec or less. However, ProcessIO() needs 100 msec.

But for my case, i use the ported tcp/ip from microchip to ccs, the stackTask() even not allow me 2ms delay! is there any problem with the tcp/ip protocol stack? (i have made some changes on the code) if i didn't put any delay it will work fine, based on ur experience what is the most possible reason?

Thx & Rgds!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group