Closed nobodyinperson closed 4 years ago
Hi @nobodyinperson,
Thank you very much for suggesting this class.
However, I'm not sure I completely get the use case.
From what I understood, this class allows exposing a shell to Serial
and Serial1
, but when a user interacts with Serial
, the output shows in Serial1
as well.
This seems really weird, doesn't it?
Best regards, Benoit
...but when a user interacts with Serial, the output shows in Serial1 as well
Exactly.
This seems really weird, doesn't it?
If you put it that way... probably yes :-)
A possibly cleaner implementation would be to have a command-line library that allows attaching multiple Stream
s independently (There aren't any. Every Arduino Shell library out there has flaws, the Shell library that I use also is very limited). But then each attached Stream
would need to have its own internal input buffer (to store argv
) which would need to be allocated dynamically or statically via a template argument for example. Assuming that only ever one CLI interface is used at a time, having Serial
interaction also show up in Serial1
shouldn't be so much of a problem an saves memory.
Maybe what this MultiStream
class does (namely gathering input from many other Stream
s and writing the same output to all Stream
s) can even be achived with a proper setup of ReadLoggingStream
and WriteLoggingStream
- though probably not in one object - but I couldn't really figure out how. The closes thing seems to be the LoggingStream
, but this doesn't read from the other Stream
, just writes, right?
If I were you, I would instantiate one shell per stream (which is exactly what happens when you open several SSH connections to the same server).
If one shell per stream is too consuming, I would use a Stream
pointer that I would point to the active stream.
Yes, but unfortunately the Shell library really only allows one global shell (It's plain C, so no classes or at least they chose to implmement it this way). I also tried others but it turned out to be the most stable CLI library (no dynamic allocation all over the place, thus no heap fragmentation) among them. Also, no other library seems to directly use Stream
s as input, unfortunately. Maybe it's time to write an own library...
This library is written in pure C in order to allow it to work in other microcontrollers/compilers that do not support C++.
I'm curious to know what platform they are talking about.
Anyway, why don't you keep a global Stream*
that you use in shell_reader() and shell_writer()?
I'm curious to know what platform they are talking about.
Maybe they don't like the Arduino framework that much, rather plain C AVR...
Anyway, why don't you keep a global Stream* that you use in shell_reader() and shell_writer()?
That's exactly what I'm doing. But this global Stream
is a MultiStream
as implemented above. And to this MultiStream
I attached both Serial
and a Stream
class that uses MQTT in the background to recieve user input and transmit shell output via WIFI. Like this I have a command-line interface both via Serial
and MQTT (together with ESP8266 OTA flashing one doesn't need a USB cable anymore then).
It works fine for me. But probably (as with all my suggestions/questions for your libraries :stuck_out_tongue_winking_eye:), this is too much of a corner case to be useful for others...
I'm afraid you're right: it's not a generic reusable solution.
Yes, a proper solution would be to fix the Shell libraries or write a proper one, not to write workaround code for existing shortcomings.
Thanks anyway!
Hi Benoit,
In one of my projects I let my µCs provide a command-line interface (based on the Shell library). At some point it turned out to be very useful to provide this cli via different channels, i.e. the USB
Serial
, maybe a differentSerial1
and even via MQTT. The best idea I could come up with to facilitate that was to implement a one-to-many and many-to-oneStream
gateway or valve - I called itMultiStream
for lack of a better term. ThisStream
subclass basicallywrite()
s andread()
s everything to and from multiple other registeredStream
s. In my case it makes it possible to have a command-line interface via both MQTT and USBSerial
simulataneously.I think something like this would make a wonderful addition to your
StreamUtils
library.Here is my (probably awful) implementation: