Using gdbserver on remote device w/ a single serial connection? - linux

I'm debugging an embedded application that runs in a Linux environment on a remote target. The only usable interface to the board is a single serial interface. Right now that's hooked up /bin/sh on init. I'm connecting with minicom, (re-)loading my application with lrzsz, and using printfs to get the job done.
I'd like to use gdbserver for more fine-grained debugging, but connectivity seems like a problem. Normally I'd connect over ethernet, but that's not available on this hardware. I understand gdbserver can run on a serial line, but right now my one comm port belongs to the shell.
Is there a good way to work around this restriction? Ideally I'd like to be able to run gdbserver and get back to a shell when I'm finished. I've tried starting gdbserver from the shell using the one available serial interface (/dev/ttyS0), then quitting minicom and starting GDB on my host, but it's messy & doesn't appear to work (even after setting remotebaud appropriately). Should that work? What's the sane thing to do in this situation?

How about the old-school solution? Use PPP to run IP networking over your serial line. You can then ssh (or even telnet) to your board, and connect to gdb at the same time. Given your circumstance, I'd recommend starting pppd manually to reduce the risk of locking yourself out through misconfiguration. The LDP link dates from 2000, but contains a lot of debugging advice.

Related

QEMU: USART communication between two MCUs (STM32)

I try to create two qemu instances and let them communicate via usart. the background is, that I want to emulate the communication while the boards aren't even finished but the code is already testable.
So the creating of two parallel qemu instances is no problem, but the communication between these two doesn't happen.
The way I thought it maybe could work is to extend the command line of the master device with -serial pty to bind the USART1 of the STM32 to an pty socket and after that binding the USART1 of the slave to the same pty. But obviously it doesn't work.
The code I use is already tested with two Olimex development boards so there have to be problems in the qemu setup.
Does anyone have tried something like this or can provide a different way to establish an emulated connection?
Use semihosting with unix pipes. I have implemented this approach and it works well. Only drawback is that there is no way in the semihosting spec to configure a file descriptor to be async, so it will always block when you do a read.

Ada GNAT.Serial_Communications behavior on Linux

I have an Ada program that communicates with an Intellibox Basic(a box that allows you to control trains) that is connected via USB.
Under Windows, I had to install a specific Serial driver (CP210x USB to UART Bridge VCP). With that driver I can communicate perfectly with the box. That means sending commands to the box.
Under Linux I'm communicating via /dev/ttyusb0 and I'm able to get messages from the box, but I can't send commands to the box. Nothing happens. I don't get an error or something.
Is the behavior of GNAT.SerialCommunication differently on Linux ? The program is the same. Do I have to setup certain things to get it to work on Linux ?
For example: A typical 2-byte command has the Command as the first Byte and the CRC check as the second one.
I had trouble with Serial_Communication at some point, where it turned out to be a problem with hardware-handshake being enabled in Linux. It's hard-coded in g-sercom.adb, look for "CRTSCTS". If your Intellibox does not use hardware handshake, Write() will block.
I believe I solved it by removing the CRTSCTS mask from the flags.

embedded linux, how to switch the use of the serial port at the push of a button?

I am a business programmer with a few years of Linux administration experience. I'm starting out in embedded Linux. Yesterday, we were discussing a new device design and I was asked a few questions I had no answers for.
The engineers want to have some push buttons on an electronic board with a serial port on it. The OS is Linux.
Normally, when a user will connect to the serial port, a protocol will answer him instead of a Linux login prompt. However, if he pushes a sequence of buttons on the device, a Linux prompt will answer him on the serial port instead.
The Linux driver to handle the push button interrupt handling aside, how can you switch the basic use of the serial port like that? Does anyone have a URL reference on how to do this? (preferably with some sample code)
Note: I proposed providing a nice menu on login for a given user, but no can do.
Thanks in advice for any suggestions.
Best regards,
Bert
The main problem is that the process that implements your device protocol is probably keeping the serial port open.
In this case you should probably:
Wait for the button event
Have the protocol process close the serial port - terminating that process completely might also do for you
Launch a *getty process - or whatever your embedded target uses to present a login prompt on the serial port
Restore the protocol process once you are done
EDIT:
In the steps above I assume the more common case where the process that controls the serial port (e.g. pppd) is not able to act as a getty substitute to provide a login prompt. It is also typically not the same process that provides telnet/SSH/whatever logins.
That said, it's quite possible on a customised embedded Linux system for a process to do more than one thing. In that case you have to configure or modify that process to switch operational modes when appropriate.
Without more information about your embedded target it's impossible to provide a more specific answer.
The getty process is usually started on serial ports to provide a login prompt by /sbin/init, which is configured in /etc/inittab.
init has the concept of "runlevels". Each runlevel defines a separate set of processes that init will keep running. One elegant way to implement this would be to design your "protocol" process so that it is started by init, in the same way as getty. You can then tell init to run your process in some runlevels, and getty in others, and have the pushbutton switch between runlevels. For example, your /etc/inittab might include:
T0:2:respawn:/sbin/getty -L ttyS0 9600 vt100
P0:345:respawn:/sbin/protocol ttyS0 9600
This will run your protocol command on the first serial port in runlevels 3, 4 and 5; but getty in runlevel 2.

Software serial port loopback on linux

Currently I need to develop some program that will communicate with cisco devices over serial line. I want to build testing environment on my development linux machine. So, I found dynamips cisco emulator. This emulator can provide interface via serial line with '-U /dev/ttyS0' option. Well, this causes dynamips to open hardware serial port and communicate via it. I'm able to connect to this hardware serial port from another linux machine with serial client like minicom.
However, since i'm using virtualbox for both linux machines, I link serial ports via virtualbox ability to forward serial port to named pipe. This scheme seems to be working, but very redunant. I'm looking for a method to run dynamips and minicom on a single linux machine.
I found that pseudo-terminals could be useful in my case. But I've tried to run dynamips with '-U /dev/ptmx' and then connect with minicom to created /dev/pts/... port and vice versa. In both cases I've got input/output error on both sides.
Unfortunately, modern pseudo-terminals aren't that easy. After opening the master with posix_openpt() or open("/dev/ptmx"), you must call grantpt() and unlockpt() on the master FD before it and its corresponding slave device are usable. (The openpty() etc. utility functions simplify this.)
As a workaround, the ever handy socat may be of use.
# terminal 1
socat pty:link=$PWD/pts unix-l:$PWD/ptm-pipe &
dynamips -U $PWD/pts
# terminal 2
socat unix:$PWD/ptm-pipe -

Get two Linux (virtual) boxes talking over a serial port

What is the best way to setup one Linux box to listen on its serial port for incoming connections? I've done a lot of googling but I can't find the right combination of commands to actually get them to talk!
My main objective is to provide a serial interface to running instances of kvm/qemu VMs. They currently only have a VNC interface (they are on headless servers, no X). I can get the VM to create a serial device by starting it with the -serial file: flag, but how to talk to it, is a whole other problem. Both boxes are running Ubuntu 8.04.
The Linux Serial HOWTO has a lot of detailed information about serial communication in general. The more-specific Linux Remote Serial Console HOWTO is what you're really looking for if you want to be able to log into your virtualized systems using the serial port as if you were at the console. As Hein indicated, you'll need a null modem cable and need to run minicom on the remote terminal.
The Linux console is used in two ways, each of which must be configured separately for serial use. You can configure the kernel to copy its messages over the serial port, which is occasionally interesting for watching the system boot and nearly indispensable if you're doing kernel debugging. (This requires kernel support and updating the boot parameters so the kernel knows you want serial output; see chapter 5 of the second howto.) You're probably more interested in logging in via the serial port, which requires running getty on the serial port after boot (just like your system already runs getty on the virtual terminals after boot), which is described in detail in chapter 6 of the howto.
I assume you connect the two serial ports using a "null modem" cable.
Use a program like minicom to talk to remote system -- you probably need to set up the communication parameters and possibly turn off hardware flow control (if your cable doesn't have the flow-control lines connected).
Say you're doing this on /dev/tty1.
in the shell
chown *youruser* /dev/tty1
then in a Perl script called example.pl
open PORT, "</dev/tty1" || die "Can't open port: $!";
while (defined ($_ = <PORT>))
{
do_something($_);
}
close PORT;
Obviously there is more to do if you want this to start automatically, and respawn on error, and so on. But the basic idea is to read from the serial port like a file.

Resources