Show Posts
Pages: [1]
1  Using Arduino / Interfacing w/ Software on the Computer / Re: Arduino Ethernet standard connection protocols ( to answer a few questions ) on: March 07, 2011, 04:54:18 am
I just read some of the older posts in this thread.  There's nothing wrong with sending raw binary over a TCP connection.  The Arduino library doesn't prevent it (in fact, has nothing to do with it either way).
2  Using Arduino / Interfacing w/ Software on the Computer / Re: Arduino Ethernet standard connection protocols ( to answer a few questions ) on: March 07, 2011, 03:47:08 am
Um.  The code checked in (that will be available at the next release) is a little bit different.  It returns 0 for closed connection and -1 for no data available.  So I'm not sure I cam recommend that you use this version of the code.   Look at issue 416: http://code.google.com/p/arduino/issues/detail?id=416

Maybe you should grab the checked-in version and use that.

Well.  There's a problem with that also.  I believe there's a bug that breaks the original Client::read().  I just commented on that in the issue.  Sigh.  That's the problem with using the latest stuff.  If you want to get thing going sooner rather than later, drop me a note and I'll try to give you something that works.
3  Using Arduino / Interfacing w/ Software on the Computer / Re: Arduino Ethernet standard connection protocols ( to answer a few questions ) on: March 05, 2011, 06:10:20 pm
I think I submitted my patch to Google Code and it's in.  I don't know because I've been busy with other things and haven't played with my Arduino lately.  I'll look into the status.
4  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Multibyte Ethernet Client::read() on: January 04, 2011, 10:21:11 pm
Thanks.  You might want to add this to the Google Code issue for this feature: http://code.google.com/p/arduino/issues/detail?id=416&q=read%20stream

However, I think everything you pointed out may already have been done.
5  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Multibyte Ethernet Client::read() on: December 30, 2010, 02:32:20 pm
Well.  It returns the number for bytes read.  Returning 0 for reading 0 bytes is consistent with that.

Also, see "man 2 read" on any Linux/Unix machine: "On success, the number of bytes read is returned (zero indicates end of file)..."  OK.  I know Client::read() doesn't have to be consistent with Unix read(), but it does indicate that's the sensible thing to do.

Client::read(void) returns -1 because 0 is a valid return value, which is the behavior of Unix getchar(), also following the same design necessities.
6  Forum 2005-2010 (read only) / Bugs & Suggestions / Multibyte Ethernet Client::read() on: December 30, 2010, 06:26:02 am
The single-byte Client::read() function in the Ethernet module is horrendously expensive.  It seems to be able to read less than 3k bytes per second.  Since there's already a multibyte write() function, it makes sense to also have a multibyte read().  Patch follows:


--- Client.h#   2010-10-02 13:17:42.000000000 -0700
+++ Client.h    2010-12-30 01:24:31.000000000 -0800
@@ -17,6 +17,7 @@
   virtual void write(const uint8_t *buf, size_t size);
   virtual int available();
   virtual int read();
+  virtual size_t read(uint8_t *buf, size_t size);
   virtual int peek();
   virtual void flush();
   void stop();


--- Client.cpp# 2010-10-02 13:17:42.000000000 -0700
+++ Client.cpp  2010-12-30 03:14:40.000000000 -0800
@@ -83,6 +83,18 @@
   return b;
 }

+size_t Client::read(uint8_t *buf, size_t size) {
+  size_t av = available();
+  if (size > av) {
+    size = av;
+  }
+  if (size == 0) {
+    return 0;
+  }
+  recv(_sock, buf, size);
+  return size;
+}
+
 int Client::peek() {
   uint8_t b;
   if (!available())
7  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: digitalWriteFast, digitalReadFast, pinModeFast etc on: October 25, 2010, 09:46:29 pm
__AVR_ATmega2560__ is not defined?  That seems to be the only way for the mega256 code to be the same as the not-mega code.
8  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: digitalWriteFast, digitalReadFast, pinModeFast etc on: September 09, 2010, 02:28:26 am
jrraines wrote:
Quote
the only place I used the ? trigrams was in digitalReadFast. I need it there because it yields a value I can assign to a variable. Bill Westfield had to explain that to me. see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266983837/1
I see.

The advantage of using ?: in a macro instead of an if statement is that it keeps the expansion an expression.  Since the macro call looks like a function call, which is syntactically an expression, it's better when the expansion is also an expression.  This also means any trailing semicolon behaves correctly.

Sometimes, you need to cast one of the branches into a void, when the other branch is a function that returns void.  For example, in (c) ? f() : g(), if f() returns void but g() doesn't, then write it as (c) ? f() : (void) g().  (Yes, then the whole expression returns void and can only be used in a statement context, for side effects only, which is also the correct behavior.)

So, basically, ?: is better than an if statement in a macro, if it's possible.  Now, gcc also has the ({...}) syntax,, so pretty much any macro can be written with ?smiley-small  On the other hand, why not just use an inline function, which doesn't evaluate arguments more than once?
9  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: digitalWriteFast, digitalReadFast, pinModeFast etc on: September 08, 2010, 08:32:56 pm
westfw wrote:
Quote
I didn't think you could meaningfully use __builtin_constant_p in inline functions?
That's a good point, but it turns out that it does work.  I was too lazy to look up the documentation to see whether it's defined behavior though.  I just tried this:

Code:
static int
g(int n)
{
   return n * 10;
}

static inline int
f(int n)
{
   if (__builtin_constant_p(n))
      return n + 10;
   return g(n);
}

int
main(int argc, char **argv)
{
   return f(10);
}

and got this (with avr-gcc -O -S):

Code:
...
main:
/* prologue: frame size=0 */
        ldi r28,lo8(__stack - 0)
        ldi r29,hi8(__stack - 0)
        out __SP_H__,r29
        out __SP_L__,r28
/* prologue end (size=4) */
        ldi r24,lo8(20)
        ldi r25,hi8(20)
/* epilogue: frame size=0 */
        rjmp exit
...

Not the most elegant test program but I was in a bit of a hurry.
10  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: digitalWriteFast, digitalReadFast, pinModeFast etc on: September 08, 2010, 01:22:52 pm
jrraines wrote
Quote
earlier on this forum item, on 5/16, Paul said Quote:
Quote
I'd like to point out this macro approach is not my preferred coding style for this optimization.  I did it this way because David said he didn't like the verbose inline function approach I originally posted.  Indeed that way is much larger, but it has the advantage of not touching any pin when an illegal pin number is given as the input.  This macro, as currently implemented, will always write to some pin even if the pin number is too large.
This is only your second post and you seem to know a trick for getting rid of ';' in macros that I do not. I still feel very much like a newcomer to a lot of this stuff.
Well.  I've been writing C code for a long time, but only playing with the Arduino for a little bit.  And I cop to joining the thread late and not having read all the messages.

It surprises me that the inline function "is much larger".  I assume he means the generated code is bigger.  My experience with gcc is that inline functions are quite efficient, and the little test code I just tried confirmed that avr-gcc is not different.  Of course, digitalWriteFast.h is much more complex than my test.  Maybe I'll try to convert it to inline functions later.

Also, I think the macros that use if statements can also use the ?: conditional expression.  Is that also for better generated code?

Again, sorry if this has all been gone through before.
11  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: digitalWriteFast, digitalReadFast, pinModeFast etc on: September 08, 2010, 03:20:16 am
How about wrapping the macros in the standard do { ... } while (0) so the expansion will absorb a trailing semicolon?  Or better, use gcc inline functions.
12  Forum 2005-2010 (read only) / Bugs & Suggestions / Bug in Ethernet/Server.cpp on: September 07, 2010, 03:26:27 am
There's a bug in Ethernet/Server.cpp that causes very short client connections to be missed, which in turn leaves the connection state around and eventually preventing new connections from being established.

This is the patch:

[size=12]--- Server.cpp# 2010-09-03 16:43:28.000000000 -0700
+++ Server.cpp  2010-09-07 00:50:54.000000000 -0700
@@ -55,7 +55,8 @@
   for (int sock = 0; sock < MAX_SOCK_NUM; sock++) {
     Client client(sock);
     if (EthernetClass::_server_port[sock] == _port &&
-      client.status() == SnSR::ESTABLISHED) {
+        (client.status() == SnSR::ESTABLISHED ||
+         client.status() == SnSR::CLOSE_WAIT)) {
       if (client.available()) {
         // XXX: don't always pick the lowest numbered socket.
         return client;[/size]


What happens is that if a client connects, sends a small amount of data, and disconnects all before Server::available() is called, then client.status() is left in CLOSE_WAIT and available() never returns the connection.

Also, I think a client that connects and disconnects without sending any data should also be recognized as a valid connection.  After all, no data is also information.  I'll look into a fix (in both accept() and available()), but that one is an incompatible change (such connections are currently ignored so existing programs may not be equipped to handle it), so I'm not sure it's a good idea to do now.
Pages: [1]