|
|
View previous topic :: View next topic |
Author |
Message |
PCH poker Guest
|
can i put delay after calling stacktask of TCP/IP? |
Posted: Fri Jul 23, 2004 3:58 am |
|
|
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
|
|
Posted: Fri Jul 23, 2004 11:33 am |
|
|
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
|
|
Posted: Sat Jul 24, 2004 7:05 am |
|
|
How long is your delay ? In case of heavy network traffic, the 8019AS might get overrun. |
|
|
PCH poker Guest
|
|
Posted: Mon Jul 26, 2004 2:56 am |
|
|
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
|
|
Posted: Mon Jul 26, 2004 4:27 am |
|
|
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
|
|
Posted: Tue Jul 27, 2004 3:58 am |
|
|
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
|
|
Posted: Tue Jul 27, 2004 6:15 am |
|
|
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
|
|
Posted: Tue Jul 27, 2004 7:36 pm |
|
|
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
|
|
Posted: Tue Jul 27, 2004 8:05 pm |
|
|
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
|
|
Posted: Wed Jul 28, 2004 3:16 am |
|
|
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
|
|
Posted: Wed Jul 28, 2004 3:30 am |
|
|
Hi,
It is so nice, it really works!
Many many thanx! |
|
|
puppie7777
Joined: 09 Jun 2004 Posts: 25 Location: Monterey, CA
|
|
Posted: Wed Jul 28, 2004 4:38 am |
|
|
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
|
|
Posted: Wed Jul 28, 2004 6:55 am |
|
|
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
|
|
Posted: Wed Jul 28, 2004 7:30 am |
|
|
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
|
|
Posted: Wed Jul 28, 2004 7:36 pm |
|
|
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! |
|
|
|
|
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
|