Go Down

Topic: Data loss when sending to native USB port (SerialUSB) (Read 9 times) previous topic - next topic

PeterVH

Quote
Update: PeterVH, I tried your fix without the guard but I can't get it to work reliably. It works for 100KB or so, then corruption, then nothing.


I can confirm the behavior. I had only tested with an 8KB file. With an 170K file I have corruption too: it goes well for some time but then each  byte gets sent several times.

I don't understand. I also tried with replacing the guard code with:
Code: [Select]

irqflags_t flags = cpu_irq_save();
... body of accept ...
cpu_irq_restore(flags);

The idea was instead of avoiding the isr to enter the routine, to avoid an isr alltogether by disabling interrupts. It does not work either.

The good thing is that I can also confirm the version in github works ok (tested with a 170KB file).

I will do tests with ArduinoISP also.


stimmer

#11
Feb 02, 2013, 06:03 pm Last Edit: Feb 02, 2013, 06:52 pm by stimmer Reason: 1
Fasten your seatbelts 8)

I have been trying to debug and simplify the code, and also add in multi-byte reads. The (modified) loopback test now runs at 4.3 MB/s (that's about 45 million baud). My 888888888-byte test passes through in about 3 min 30 sec. I also added in some code to control the LEDs. I did this by removing the troublesome ringbuffer code and using UDD_ calls directly (My reasoning was, since there is 2 banks of USB fifo for buffering, why do we need more?)

I do seem to be getting occasional errors but only about once every several gigabytes, which makes it hard to debug as I don't know if it's a problem with the code or the cable or with the way I am testing it. Testing so far indicates it is a problem with transmission (SerialUSB.write())

The new loopback test with multi-byte read looks like this:
Code: [Select]
void setup() {
 Serial.begin(115200);
 SerialUSB.begin(0);
}
int s=0;
int t=0;
void loop() {
 int l;
 byte b[2048]; // 512 might be enough
 if(l=SerialUSB.available()){
   l=SerialUSB.read(b,l);
   SerialUSB.write(b,l);
   s+=l;
 }
 if((millis()-t) > 1000){t=millis();Serial.println(s);}
}


I've attached the three changed USB files as there are many changes.

The way I am testing on linux is as follows:
Code: [Select]

seq 99999999 >o1
stty -F /dev/ttyACM1 sane raw -iexten -echo -echoe -echok -echoctl -echoke -onlcr min 1
time cat o1 >/dev/ttyACM1 & cat /dev/ttyACM1 >o2
# ctrl-c when it is finished
cmp o1 o2

I've also tested with gtkterm (which has been 100% reliable)

Please test thoroughly! I am especially interested to see if removing the ringbuffer causes performance degradation in any situation - I haven't found anything yet which runs slower despite having less buffering. Also I am unable to test on Windows or Mac.

selfonlypath

Hi Stimmer,

Would it be possible for you to make the same test but on Programming Port USB ?

Thank you, Albert

stimmer

Albert: not really - programming port serial doesn't have a direct multi-byte read, it is too slow to need one. And an 888888888 byte test would take over 21 hours to run :)

If you need a programming port loopback sketch use MultiSerialMega and connect pins 18 and 19. As for the 16u2 firmware it is almost the same as the Uno firmware and I have tested that to death 2 years ago - it can be tested by uploading Blink and linking pins 0 and 1.

selfonlypath

Ok Stimmer I see now but I'm confused, in other threads there were issues with USB routines, are there just on native USB ?

As i've reported when moving an arduino MEGA code to arduino DUE, the USB link between Java running on my MacBook air and DUE would never work, in that case i was using USB programing port.

Maybe it would help someone makes clear thread on USB programming port and USB native port, different type of issues, have they been solved in new IDE...

I'm lost now  :~

Go Up