-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
High CPU load #112
Comments
Sidenote: I tried to replace the serial-monitor.exe with my own application (written in C#). But it is not loaded at all. Why? golang magic? |
Hi @holgerlembke, thanks for the bug report, and sorry I didn't have the time to look at this yet.
It's a plain executable it should start normally... |
Certainly there should be some sort of win equivalent to Linux select() which can check for traffic. What I have done in anything in my own Linux code (in C), is to do a check with select() with a zero timeout, and if no data, a 1mS sleep() (or other processing for single thread, in which case both have to fail for the sleep()), which always lowered the CPU to nearly zero, and never lost any data, since it can handle 1mS of burst in a single gulp, even at very high speeds. |
no need to hurry, it is not that important. Just revisited my code... Fixed some very stupid errors, now it is loaded. I think I will spend some time of the weekend with recreating that thing in c#. |
@xxxajk I have no clue about golang, but I would expect a read-function from stdio to pass it to the OS and that should let it wait with zero load. Isn't that so? |
Unsure, but I do know that in order to make programs not eat cycles on linux in C, that using select and sleep on fails was able for some code that I wrote back in about 1995 running on a 386sx totally fine, even when the data was streaming in from 10baseT bidirectionally to/from high-speed UART. Never wrote anything in golang either, but then I'm kind of a control freak when it comes to what's actually running on the CPU, to the point that I have mixed C and ASM a lot... |
Hi @holgerlembke.
I'm not sure I understand what you mean by "select a different board type". Do you mean that you are only selecting a different board from Arduino IDE's Tools > Board menu, without changing the Tools > Port menu selection? If yes, please tell us which exact Tools > Board menu item you have selected when the fault occurs, and which exact Tools > Board menu item you have selected when the fault does not occur. Or do you mean that you connect a different board to your computer and select that board and port instead of the board and port of the ESP8266-based board? If yes, please tell us exactly which board you are using when the fault occurs, and which one you are using when the fault does not occur. |
I just rechecked it and my observation was wrong. Whatever board I select, load is there. I edited the bug report. |
Thanks for the clarification. Please tell us which USB to serial bridge chip your Arduino board has. This is a black chip near the USB socket. The chip will usually be identified by writing on the top. This might say something like "WCH CH340G" or "SILABS CP2102". Examples: WCH CH340There are some boards on the market that have a USB chip with the same IC package as the WCH CH340, and which are identified by the computer as a CH340. However, these chips don't have the "WCH CH340C ..." labeling like you see on the chip in the picture above: Silicon Labs CP2102If it isn't clear, alternatively you can provide the link to where you bought the board from and we'll see if we can determine the chip from the product listing. |
Device manager says CH340. Chips says CH340C. Just added a board with a cp9102. It does NOT show the high load.
|
Is your board running a sketch that causes it to produce serial output? Note that the ROM bootloader of the ESP8266 produces output on startup or reset, so in cases where either the sketch code or electrical conditions (e.g., insufficient power supply) causes the board to continuously crash/reset, it is also possible that the board can produce continuous serial output even if there isn't anything in the sketch code that explicitly does so. In this case, you should see the output in the Arduino IDE Serial Monitor if you select "74880" from the baud rate menu in the Serial Monitor panel (the bootloader uses this baud rate even if the sketch is configured for a different rate). |
This
produces the load. |
If you press and hold the reset button on the board with the CH340 (or ground the RST pin if your board doesn't have a reset button), does the high |
Soooo. This is a "very early", "just after finishing it", "I'm happy", look at the problem response. https://github.com/holgerlembke/serial-monitor is a working rewrite in C# of the serial-monitor. It works, at least I see incoming and outgoing stuff. Internal error handling might not be satisfying. And there is no load. |
I've been able to reproduce the bug with an esp8266 d1-mini clone. It seems that the CH340 driver does not honor the timeout set on the serial port (that should be infinity), instead returns from the I've reproduced the problem with a minimal example in go: package main
import (
"fmt"
"io"
"os"
"go.bug.st/serial"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: term <PORT>")
os.Exit(1)
}
portname := os.Args[1]
port, err := serial.Open(portname, &serial.Mode{
BaudRate: 9600,
DataBits: 8,
Parity: serial.NoParity,
StopBits: 1,
InitialStatusBits: &serial.ModemOutputBits{
RTS: true,
DTR: true,
},
})
if err != nil {
fmt.Println("Error:", err)
os.Exit(2)
}
buff := make([]byte, 1024)
for {
n, err := port.Read(buff)
fmt.Println(">>", n, err)
if err == io.EOF {
break
} else if err != nil {
fmt.Println("Error:", err)
os.Exit(0)
} else if n > 0 {
fmt.Println("READ:", buff[:n])
}
}
} That prints:
Interestingly, I'm not able to reproduce the problem with python
Cool! Nice work on that ;-) This makes me particularly happy because:
|
Nice finding with the CH340. At least in .NET 6/8s System.IO.Ports everything looks fine and event driven, no wait needed. As usual, the TCP connection is not event driven, so I ended up with some sleep(). What makes it more complicated is no real good way to monitor the disconnect/connect of the USB port (other than digging deep into the hardware event system, I do not wanted to do...). And I get no exception. Another miracle for another day. More confusing, I find this log:
It is a simple user interaction sequence: open serial monitor and click upload. So disconnect, compile (:17-:32) and reconnect. Every time the "RR:Start" indicates a serial-monitor-process is started. I have no idea, why I see those short hello-describe-quit sequences. Especially at the beginning, just two of those cycles until it starts with real connection phase. I feel innocent, I do always the same stuff. :) Most annoying (Ok, I'm used to that stuff, and it is not so bad) is the complication, that stdin.Read() is a blocking call and there is no async way to do it with stdin. So it needs an extra thread to monitor just stdin.Read()... |
And another log.
Originally I wanted to test the hibernate-problem (after wake up from hibernate, the IDE thinks the serial port is connected, but it does not show any incoming data. It needs a close+open cyclus to start logging again.) So, as you see, serial-monitor is closed at 21:55:44 and never opened again. So at least that explains that. It is not the serial-monitor, it is the IDE forgetting something. More confusing are the duplicate lines at 21:55:04 etc. It seems like two versions are started. And then, at 21:55:04.884 the IDE starts the real setup ending in an connection. Reason might be that I have 3 IDE instances open. So the "i did not click on that"-IDEs still try to get the serial params... All in all this seem superfluous because the DESCRIBE answer content is static. But I'm not the designer. There might be reasons. So in case, I'm just reporting this. |
I think it's the IDE that is querying the list of parameters supported from the monitor. |
Back to the CH340 I think I found the reason of the issue, this is the patch I prepared for the serial library in golang with a bit of explanation, it really looks like a bug in the CH340. |
Here are some test builds (at the bottom of the page): |
This upgrade should fix high CPU load with the CH340. #112
This upgrade should fix high CPU load with the CH340. #112
Thanks for the work! I'll stay with my C# solution, because it catches the esp exception on the fly and passes them instantly to ESPEDfGK |
The |
Oh, that reminds me to mention, that I have a 0.10.0, 0.11.0, 0.12.0, 0.13.0 and 0.14.1. Each of it with 3.5 MB going up... |
You can remove the old ones |
Describe the problem
When opening the serial monitor, serial-monitor.exe creates a relatively high CPU load.
It seems to be related to a certain board type: esp8266 (3.1.2 https://arduino.esp8266.com/stable/package_esp8266com_index.json).
If I select a different board type, the load is gone.Something is pumping data, as far as I can see, there is a thread continuously moving data.
To reproduce
(see above)
Expected behavior
(see above)
serial-monitor version
0.14.1
Operating system
Windows
Operating system version
10.0.19045.5487
Additional context
Discussion: https://groups.google.com/a/arduino.cc/g/developers/c/PqosKNzu2GU
Issue checklist
The text was updated successfully, but these errors were encountered: