We run the same code on P2 and Photon
P2 is extremely slow takes 24-25 ms to run this code, while Photon takes 0 ms.
Firmwares:
Photon 1: 2.1.0
P2: 5.1.0
You have not specified the baud rate in your code, and I am not sure what the default is, but the 3-4 ms, just to print out some data looks incredibly slow.
25 milliseconds is very, very slow. If you are getting that with my sample code that would be an issue.
However 3 - 4 milliseconds doesn’t seem that bad. That’s what I was referring to as probably not a high priority.
The USB drivers are completely different between the STM32F205 and the RTL8217D. It’s hard to say where the slowdown is occurring, but if it’s in the Realtek SDK, then there is little that could be done. If it’s in the interface between Device OS and the Realtek SDK, then possibly something could be optimized.
I’m not saying that we won’t fix it, I’m just indicating on the list of priorities, USB serial speed is not a priority so it’s less likely to be fixed immediately.
I think I see why there is a speed difference. On the STM32, there’s a ring buffer between the USB serial calls and the actual USB hardware. It’s instantaneous because it goes into the buffer and goes to the USB host asynchronously. It’s not actually faster, it just returns faster.
On the RTL8721D it actually sends the data to USB before returning.
The easiest workaround if you don’t want to block is just wrap the USB serial with ring buffer.
I was mistaken. There is a buffer in the RTL8721D CDC driver. So it should not take 3-4 milliseconds (or more).
However, using the library with the external buffer definitely makes writes much faster, so now I’m not sure what the cause of the slowdown is. But the library would be a reasonable workaround until the actual problem is found.
I was wondering if there has been any updates on this issue?
Comparing the serial output between Photon 2 and Photon 1, I still get a > 20 fold slow down in Photon 2 vs 1 with > 5ms compared to ~250 µs (details below) for a log message. I'm assuming this is still the same buffer issues you explained in this thread and was hoping there might be a way for solving this more generally, Or if not, could you kindly point out a good way to use your solution with the SerialLogHandler (recommend instead of Serial in the particle docs)? Note on context: running a stepper motor at a range of speeds up to pretty fast rates (requiring ~1 step / ms) which used to be no problem but now the Serial debug messages cause the stepper to skip.
Thank you for all your help!
Photon 2 (firmware v. 5.6.0):
0000010907 [app] INFO: log message took 5563 microseconds
0000011913 [app] INFO: log message took 5723 microseconds
0000012918 [app] INFO: log message took 5370 microseconds
0000013924 [app] INFO: log message took 5310 microseconds
0000014929 [app] INFO: log message took 5520 microseconds
Photon 1 (firmware v. 2.3.1):
0000008089 [app] INFO: log message took 220 microseconds
0000009090 [app] INFO: log message took 225 microseconds
0000010090 [app] INFO: log message took 220 microseconds
0000011090 [app] INFO: log message took 261 microseconds
0000012090 [app] INFO: log message took 220 microseconds
Generated with this slightly adapted version of your code:
SerialLogHandler is but one of many things that could block the main application thread for a period of time.
You should run your timing-sensitive stepper motor code from a worker thread if you can use 1 millisecond time scheduling. Faster than that would be tricky because it would require interrupts, but there isn't a good way to use hardware timers on the P2/Photon 2 at this time. Also the relatively slow speed of the GPIO could be an issue.
Thank you so much for the quick response! Tried a worker thread for the stepper but the 1ms scheduling is not fast enough to allow for different speeds at the high end (e.g. one that needs a step every 1.4 ms skips). I think the GPIO should be fast enough (a few µs) not to be an issue. I read through the Threading explainer | Firmware | Particle details and came away with the conclusion that without interrupts my best option is to keep the stepper in main app thread and put everything else in worker threads but would love suggestions for better approaches.
I would look at how the NeoPixel library works. Instead of trying to precisely time the pulses, which is kind of impossible on the RTL872x, it uses the SPI peripheral to do it in hardware. You load up a buffer with the digital values to write out and the hardware streams out the bits with precise timing without using bit-level interrupts or timing loops.