[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