Arduino Due SerialUSB bug on monitor close/USB unplug
drianMC opened this issue · 6 comments
Hi all,
I'm trying to develop an application where the arduino Due is continuously working (always powered), and I can connect to it using the native USB, so I can get data about the process. I have found unexpected behavior of the Due board when it is unplugged, or the serial port is closed.
For the following test I have used this Arduino Code. With this one two different problems are observed.
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
SerialUSB.begin(115200);
}
void loop() {
SerialUSB.print("H");
SerialUSB.print("e");
SerialUSB.print("y");
SerialUSB.print(" ");
SerialUSB.print(":");
SerialUSB.println(")");
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(200); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(200); // wait for a second
}
I have found this issues
->If Serial monitor is closed while sending data through the native USB (SerialUSB) the main loop gets freezed, until the serial monitor is opened again. (With the test code, it can be observed that the led stops blinking).
->If unplugged the Native USB while sending data (and keep powered with the other USB), when a new monitor is opened, the received data order is changed. How can it be? The data order gets changed, and while unplugged the led stops blinking.
I also found a post where one of the bugs is mentioned:
https://forum.arduino.cc/index.php?topic=560839.0
As Sanworks_J explains this problem only appears when the computer used as serial monitor is Windows 10. I have check both problems in Linux, and in this case the board works correctly.
I have followed this Steps to in the second issue.
-->Connect both the programming USB (just for power, no data) and Native USB.
--> Upload the sketch to the board, and open the serial monitor, native USB. (Data received correctly).
--> While serial monitor is opened, unplug the Native USB (while powered with the other USB)
--> Plug the Native USB again. Close the monitor opened before(because it is stopped).
--> Open a new serial monitor, and the received data from that moment the data order is wrong.
Since that moment, the received messages are as follows.
)eH y):H
ye:
)eH y):H
ye:
When it should be:
Hey :)
Hey :)
Hey :)
I have made this test in different PCs and with different Arduino Due boards, with the same results in Win10. When used Linux it doesn't happen, but the program gets stopped when unplugged the USB, this problem remains in Linux.
Any possible solution to this issue?
Thanks in advance.
+1, I have this issue too:
->If Serial monitor is closed while sending data through the native USB (SerialUSB) the main loop gets freezed, until the serial monitor is opened again. (With the test code, it can be observed that the led stops blinking).
Using Arduino Due and Windows 10
What if you set timeout by SerialUSB.setTimeout()?
After some time I have been trying again to find the reason of this issue.
What if you set timeout by SerialUSB.setTimeout()?
I didn´t notice any change using that function, seems not to affect to this issue.
Using the VisualMicro for debugging, I found that the blocking function is UDD_Send, in the "uotghs_device.c" file.
The first part of the function can the modified by adding a time limit to the while loop, this doesn´t solve the real problem, but at least doesn´t freeze the main loop.
uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len)
{
const uint8_t *ptr_src = data;
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
uint32_t i;
uint32_t beginTime =GetTickCount(); //<-- Added
TRACE_UOTGHS_DEVICE(printf("=> UDD_Send (1): ep=%lu ul_send_fifo_ptr=%lu len=%lu\r\n", ep, ul_send_fifo_ptr[ep], len);)
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_TXINI )) {
if( (millis()-beginTime)>5 ){ //<-- Added
break; //<-- Added
} //<-- Added
}
...
}
With this timeOut the USB can be unplugged while sending data via USB without suffering a lock.
This file is found in the following folder:
[Disk]:\Users[UserName]\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12\system\libsam\source\uotghs_device.c
This file had to be included as "Source Files" in Visual Studio project to be used. When using the Arduino IDE it seems like the other file was used. I would appreciate if someone could explain me how to make the Arduino IDE to use this modified file, as I only achieved to make it work with the Visual Sutio, referencing the file as a source file.
I would appreciate if someone could explain me how to make the Arduino IDE to use this modified file, as I only achieved to make it work with the Visual Sutio, referencing the file as a source file.
You need to rebuild the libsam_sam3x8e_gcc_rel.a object file found in the .arduino15/packages/arduino/hardware/sam/1.6.12/variants/arduino_due_x ( or equivalent location on your machine )
On a mac I go to .arduino15/packages/arduino/hardware/sam/1.6.12/system/libsam/build_gcc then ensure that the ARM_GCC_TOOLCHAIN is set to .arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/ ( or equivalent location on your machine ) then make clean, make which should rebuild that object for you.
Great job, Thank you!
I hope this patch will be accepted although it seems to me the Due code has not been maintained for a long time.
https://forum.arduino.cc/t/serialusb-can-block-upon-write-has-no-availableforwrite-method/415576/8
Thanks @tinoest for the explanation about rebuilding the object file. I am having some issues trying to rebuild the object.
As I am using millis(), it seems not to be able to make the file, it can be used with the sketch compilation, but not for the build of the sam object itself. It might be changed for another timeOut method like the one used in the thread shared by @iddq , just attempt times, not limited by time.