[lldb-dev] Serial port support in LLDB

Michał Górny via lldb-dev lldb-dev at lists.llvm.org
Wed Oct 6 05:59:25 PDT 2021


On Wed, 2021-10-06 at 14:32 +0200, Pavel Labath wrote:
> Thanks for the nice summary Michał. I've found it very helpful.
> 
> The thing I am missing from this proposal is how would those settings 
> translate into actual termios calls? Like, who would be responsible 
> reading those settings and acting on them? Currently we have some tty 
> code in ConnectionFileDescriptorPosix (in the Host library) but I think 
> a bit too low-level for that (I don't think the host library knows 
> anything about "settings"). I am also not sure if a class called 
> "ConnectionFileDescriptor" is really the best place for this.
> 
> On 05/10/2021 11:21, Michał Górny via lldb-dev wrote:
> > Hi, everyone.
> > 
> > I'm working on improving LLDB's feature parity with GDB.  As part of
> > this, I'm working on bettering LLDB's serial port support.  Since serial
> > ports are not that common these days, I've been asked to explain a bit
> > what I'd like to do.
> > 
> > 
> > At this point, LLDB (client) has minimal support for serial port
> > debugging.  You can use a command like:
> > 
> >      process connect file:///dev/ttyS0
> > 
> > to connect via the GDB Remote Protocol over a serial port.  However,
> > the client hardcodes serial transmission parameters (I'll explain
> > below).  I haven't been able to find an option to bind lldb-server to a
> > serial port.
> > 
> > I'd like to fix the both limitations, i.e. make it possible to configure
> > serial port parameters and add support for serial port in lldb-server.
> > 
> > 
> > The RS-232 standard is quite open ended, so I'm going to focus on 8250-
> > compatible serial port with DB-9 connector below (i.e. the kind found
> > in home PCs).  However, I'm going to skip the gory details and just
> > focus on the high-level problem.
> > 
> > The exact protocol used to transmit data over the serial port is
> > configurable to some degree.  However, there is no support for
> > autoconfiguration, so both ends have to be configured the same.
> > The synchronization support is also minimal.
> > 
> > The important hardware parameters that can be configured are:
> > 
> > - baud rate, i.e. data transmission speed that implies the sampling
> >    rate.  The higher the baud rate, the shorter individual bits are
> >    in the transmitted signal.  If baud rate is missynced, then
> >    the receiver will get wrong bit sequences.
> > 
> > - number of data bits (5-8) in the frame, lower values meaning that
> >    the characters sent are being truncated.  For binary data transfers,
> >    8 data bits must be used.
> I believe gdb-remote protocol is compatible with 7-bit connections, 
> though we would need to make sure lldb refrains from using some packets. 
> Should I take it this is not an avenue you wish to pursue?

No, I don't think that there's a good reason to pursue it.  GDB itself
doesn't support 7-bit connections (i.e. forces 8 bits unconditionally),
so I doubt that there's a point in doing that.

> 
> > 
> > - parity used to verify frame correctness.  The parity bit is optional,
> >    and can be configured to use odd or even parity.  Additionally, Linux
> >    supports sending constant 0 or 1 as parity bit.
> > 
> > - number of stop bits (1 or 1.5/2) in the frame.  The use of more than
> >    one stop bit is apparently a relict that was supposed to give
> >    the receiver more time for processing.  I think this one isn't
> >    strictly necessary nowadays.
> Gotta love those half-bits.

Fortunately, 8250 support half-bits only with 5-bit data frames, so we
can forget about them entirely ;-).

> 
> > 
> > - flow control (none, software, hardware).  This is basically used by
> >    the receiver to inform the sender that it's got its buffer full
> >    and the sender must stop transmitting.  Software flow control used
> >    in-band signaling, so it's not suitable for binary protocols.
> >    Hardware flow control uses control lines.
> > 
> > Of course, there is more to serial ports than just that but for LLDB's
> > purposes, this should be sufficient.
> > 
> > 
> > The POSIX and win32 API for serial ports are quite similar in design.
> > In the POSIX API, you have to open a character device corresponding to
> > the serial port, while in win32 API a special path \\.\COMn.  In both
> > cases, reads and writes effect the transmission.  Both systems also have
> > a dedicated API to configure the serial transmission parameters
> > (ioctl/termios on POSIX [1], DCB on win32 [2]).  Note that I haven't
> > tried the win32 API, just looked it up.
> > 
> > The POSIX serial ports are a teletype (tty) devices just like virtual
> > consoles used by terminal emulators.  This makes it easy to use a serial
> > port as a remote terminal for other system.  This also adds a bunch of
> > configuration options related to input/output processing and special
> > behavior.  When a serial port is going to be used for non-console
> > purposes, these flags have to be disabled (i.e. the tty is set to 'raw'
> > mode).
> > 
> > 
> > The rough idea is that after opening the serial port, we need to set its
> > parameters to match the other end.  For this to work, I need to replace
> > LLDB's hardwired parameters with some way of specifying this.  I think
> > the cleanest way of doing this (and following GDB's example) would be to
> > add a new set of configuration variables to specify:
> > 
> > a. the baud rate used
> > 
> > b. the parity kind used
> > 
> > c. the number of stop bits
> > 
> > d. whether to use hardware flow control
> > 
> > I'm thinking of creating a new setting group for this, maybe
> > 'host.serial'.  When connecting to a serial port, LLDB would set its
> > parameters based on the settings from this group.
> > 
> > That said, I can't think of a really clean way of making this
> > configurable on lldb-server's end but I guess adding more command-line
> > parameters should suffice.
> > 
> > WDYT?
> 
> Let me try to make a counterproposal.
> 
> Since the serial parameters are a property of a specific connection, and 
> one could theoretically have be debugging multiple processes with 
> different connection parameters, having a (global) setting for them does 
> not seem ideal. And since lldb already has a history of using made up 
> urls (unix-connect://, tcp://), I am wondering if we couldn't/shouldn't 
> invent a new url scheme for this. So like instead of file:///dev/ttyS0, 
> one would use a new scheme (say serial:// to connect), and we would 
> somehow encode the connection parameters into the url. For example, this 
> could look something like
>    serial://[PARODD,STOP1,B19200]/dev/ttyS0
> This connection string could be passed to both lldb and lldb-server 
> without any new arguments. Implementation-wise this url could be 
> detected at a fairly high level, and would cause us to instantiate a new 
> class which would handle the serial connection.

I don't have a strong opinion either way.  I suppose this would be
a little easier to implement, though I'd prefer using something more
classically URL-ish, i.e.:

  serial:///dev/ttyS0?baud=115200&parity=odd...

or:

  serial:///dev/ttyS0,baud=115200,parity=odd...

I suppose it would prevent weird paths but I don't think we need to
account for weird paths for ttys (and if we did, we should probably
urlencode them anyway).

-- 
Best regards,
Michał Górny




More information about the lldb-dev mailing list