Suggestions and feedback on Coldfire Lite, part 2

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Suggestions and feedback on Coldfire Lite, part 2

2,752 Views
vier_kuifjes
Senior Contributor I

I already made a couple of modifications to ColdFire Lite in the past weeks that I consider improvements, and now I have made a couple more!

 

My current project (which is based on AN3518 by Eric Gregori) uses an HTTP client to download information from the internet and display it on an LCD screen.

 

All of this works fine, unless the HTTP server is off line or the IP address cannot be resolved by the CF Lite DNS client. If this happens, my application hangs in a loop somewhere in the CF Lite operating system.

 

So yesterday I took the time to figure out what was going on and what I could do to fix this. And I have found 2 fixes...

 

The first modification is done in the file dnsclnt.c. It appeared that the dns client always returns an IP addres, no matter wether the address could be resolved or not. Only, the returned IP address appears to be some memory pointer instead of an actual IP address when the URL is false.

I solved this by commenting out the line marked in red below and adding the green line:

 

static  int
dnc_lookup(char * name, struct dns_querys ** cacheentry)
{
   struct dns_querys * dns_entry;
   int      alias;

   /* look through the cache for the passed name */
   for(dns_entry = dns_qs; dns_entry; dns_entry = dns_entry->next)
   {
      if(strcmp(dns_entry->dns_names, name) == 0)
         break;

      if((dns_entry->he.h_name) &&
         (strcmp(dns_entry->he.h_name, name) == 0))
      {
         break;
      }
      for(alias = 0; alias < MAXDNSALIAS; alias++)
      {
         if((dns_entry->alist[alias]) &&
            (strcmp(dns_entry->alist[alias], name) == 0))
               goto found_name;
      }
   }

found_name:

   /* if not found, return error */
   if (dns_entry == NULL)
      return ENP_PARAM;

   /* else, prepare to return entry index */
   if (cacheentry != NULL)
      *cacheentry = dns_entry;

   /* if completed request, return success */
 //if (dns_entry->rcode != DNSRC_UNSET)
  if (dns_entry->rcode == DNSRC_OK)  /* MvdH : modification */
      return 0;

   /* incomplete request -- return pending or timed-out status */
   if (dns_entry->tries < dns_trys) /* still trying? */
      return ENP_SEND_PENDING;
   else
      return ENP_TIMEOUT;
}

(code sample based on CF Lite V3.2)

 

On to the second modification.

The second modification is located in the file tcpapi.c. The function m_connect uses a 'while' loop to give the system time to connect to the server. But it will NEVER exit this loop when the system cannot connect to that server. So I commented out that loop (red) and replaced it by another one (green), with a built-in time out of 30 seconds.This time out does require the use of an additional variable tmo to keep track of time.

 

int
m_connect(M_SOCK so, struct sockaddr_in * sin, M_CALLBACK(name))
{
   struct tcpcb * tp;
   int e = 0;
   unsigned long tmo;
:
:
:
:
   if(so->state & SS_NBIO)    /* if socket non-blocking, return now */
   {
      /* Socket may have blocked to connect in tcp_output() and then been
       * set to non-blocking in connect callback - e.g., FTP server does this.
       */
      if(so->state & SS_ISCONNECTED)
         goto rtn;

      /* fall to here if it's really in progress */
      e = so->error = EINPROGRESS;
      goto rtn;
   }
/////////////////////////////////////////////////////////////////////////////////////////////////////
// MvdH : the original version locked the system up when the destination
// doesn't exist
// Modified this to make the connection time out
   tmo = cticks + (30 * TPS);
   do
   {
      if (cticks > tmo) break;
      tk_yield();
   } while (so->state & SS_ISCONNECTING);
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*
   while(so->state & SS_ISCONNECTING)
   {
      tcp_sleep(so); //FSL give time to allow connection to complete
   }
*/
   if(so->state & SS_ISCONNECTED)
      e = 0;
   else
//      e = so->error;
      e = so->error = ETIMEDOUT;

rtn:
   UNLOCK_NET_RESOURCE(NET_RESID);
   return e;
}

(code sample based on CF Lite V3.2)

 

So far everything seems to work fine with these modifications. I have tested it with some false URLs and IP addresses. The false IP address connect attempt times out after 30 seconds; the false URL takes a bit more time but it does time out.

 

I hope this helps...

- Marc

Labels (1)
0 Kudos
Reply
11 Replies

1,038 Views
bkatt
Contributor IV

Regarding the tmo stuff, the way you are using cticks and tmo does not handle wrap around properly. The key point to remember is that there must be a modulo subtraction in the test:

 

unsigned long start_time;

...

start_time = cticks;

...

if (cticks - start_time > 30 * TPS)   /* 30 seconds have elapsed, even if cticks wrapped around. */

 

Also, access to cticks should be volatile (I think one of the coldfire lite updates got that). 

 

Yes, I realize 4 billion cticks is a long time, and similar cticks-related calculations are botched throughout coldfire lite, but the cost to do this right is essentially zero. In my stuff I use one of the 32 bit DMA timers as a free-running microsecond counter, which wraps around every 4295 seconds.

 

0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

Thanks for notifying me!

In fact, I did realize that, but I didn't care about it. Silly me, trying to improve things and ignoring this... But you are right, there's more of that kind of stuff in CF Lite, I actually copied it from another piece of CF Lite code!

 

Could you explain to me the "volatile" thing? This is one of the things in the C language that I don't understand what they do...

0 Kudos
Reply

1,038 Views
bkatt
Contributor IV

Marc VDH wrote:

 

Could you explain to me the "volatile" thing? This is one of the things in the C language that I don't understand what they do...


The C FAQ, 18.1.7 Type Qualifiers, has a good paragraph on volatile:

http://c-faq.com/~scs/cclass/int/sx4ga.html

Message Edited by bkatt on 2009-03-19 04:06 PM
0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

bkatt wrote:

 

The C FAQ, 18.1.7 Type Qualifiers, has a good paragraph on volatile:

http://c-faq.com/~scs/cclass/int/sx4ga.html


 

 

Very good information, thanks!

0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

Forgot to mark a couple of lines in the tcpapi.c code:

 

Near the end of the source, another line is commented out (red) and replaced by (green).

 

// e = so->error;
e = so->error = ETIMEDOUT;

 

 

 

0 Kudos
Reply

1,038 Views
Dave_at_Mot
Contributor III

Marc,

 

Very good info.  I'm also using the AN3518 code to do some remote client work.  I periodically do wget to send some postdata and get command info.  Works very nicely behind firewalls and such becuase it is all just standard HTTP on port 80.  

 

I did run into some difficulties with TCP source port numbering.  Seems some cable modems block port 1080 and and Coldfire lite sequences through this.  Take a look at the thread a few days back regarding the 5223X RNG. 

 

Dave

 

0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

That information you give there is very interesting also. I will apply those changes in my program.

Thanks!

0 Kudos
Reply

1,038 Views
J2MEJediMaster
Specialist I

Marc:

 

You may want to submit a service request on your changes,  flagging them as a feature request. Any improvements to the code are welcome, and if they are integrated into a future release, everyone else benefits. Thanks for your contributions.

 

---Tom

 

0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

Hello Tom,

 

I will do that.

I have checked the service request page but I cannot find a "feature request" option.

 

Can you point me there?

 

- Marc

 

0 Kudos
Reply

1,038 Views
J2MEJediMaster
Specialist I

Marc:

 

Glad to help. OK, on the first page of the SR entry process, choose Technical Request as the Category, and CodeWarrior as the Topic. Click Next. On the second page, enter the relevant information as to the platform ColdFire Lite executes on. You will have to enter CodeWarrior for ColdFire for the product. For the Root Cause entry, pick Feature Request. Then fill out the rest of the form. My only concern, upon closer study of the form, is that this request might be too CodeWarrior-oriented, rather than point up fixes for a support package. In that case, I would just go with the standard service request, and report the enhancements along with the fixes. Your choice. HTH.

 

---Tom

0 Kudos
Reply

1,038 Views
vier_kuifjes
Senior Contributor I

OK, thanks. I will put everything I have done sofar in a Word document and then send it to Freescale.

- Marc

 

0 Kudos
Reply