Filed under RaspberryPi

Fix USB Serial Console on Raspberry Pi for Yosemite

My favorite way to talk with Raspberry Pi devices is using the PL2303 based USB Serial cable from Adafruit. The convenience of not needing a monitor or keyboard, as well as not needing a network connection for SSH, is significant as I often want to work with my devices in varied environments, and have several devices deployed “in the wild” where other options would be very inconvenient.

The Problem

Unfortunately this functionality recently stopped working for me. A number of variables had changed; I had upgraded my laptop to OS X 10.10 (Yosemite), I was using a new USB Serial cable I hadn’t used previously, and I was using a Model B+ Raspberry Pi which I hadn’t worked with before. As anyone who’s done much debugging will be all top familiar with, having this many variables change creates a nightmare for debugging, particularly as I had no available hardware to put any of the variables back to a known-good state.

After a lot of digital multi-metering and loopback testing I was convinced the Raspberry Pi was functioning correctly, so I was able to turn my focus to the USB serial adapter itself. I had used these cables successfully in the past, so I had faith in the concept, but for some reason when I attempted to use one using screen (screen /dev/cu.PL2303-00001014 115200) with my Raspberry Pi I merely received a blank screen with a blinking cursor.

When I installed the drivers for the PL2303, I had followed a link from this page in Adafruit’s article on using the cable to a package installer. Returning a saw a large amount of discussion around issues with using the drivers on Yosemite, with a number of suggestions for fixing the issue. I tried all of the suggested fixes, removing and reinstalling the driver using the supplied package several times, without positive results. At some point during the process I discovered that as long as the cable was connected during boot it would function properly, but as soon as it was removed and replugged into a USB port while the computer was running it would give me the black screen, and the following errors would show in my dmesg log:

➜  ~  cat dmesg | grep PL2303
nl_bjaelectronics_driver_PL2303(0xffffff801da83200)::dequeueDataGated - INTERRUPTED
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::allocateResources failed - no fpInterface.
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::start Allocate resources failed
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::CheckSerialState - StartSerial failed
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set
nl_bjaelectronics_driver_PL2303(0xffffff801d55d800)::enqueueDataGated fTerminate set

The Solution

Finally I decided to try giving up on the package installer and going to the manufacturers driver page here. Fortunately the manufacturer now actually supplies it’s own package installer. I removed the existing install of the driver using these steps:

  1. Disconnect the USB cable from the computer
  2. Run these commands:
    sudo kextunload /System/Library/Extensions/osx-pl2303.kext
    sudo rm -r /System/Library/Extensions/osx-pl2303.kext
  3. Remove any instances of “USB Serial Controller …” from Network Preferences.

I then used the installer from the above link to prolific’s website, and then rebooted.

The device identifier changed from it’s previous value of /dev/cu.PL2303-00001014 to a more intuitive /dev/cu.usbserial, but more importantly I was able to consistently connect to my Raspberry Pi, even without the cable connected during my laptops boot:

➜  ~  screen /dev/cu.usbserial 115200
 
 
Raspbian GNU/Linux 7 raspberrypi ttyAMA0
 
raspberrypi login:
Tagged , , , , , , , , ,

Serial Port Sees Kernel Sequence But No Login Prompt In Raspbian

I just finished fighting a battle debugging the serial console on the raspberry pi. I was able to see the kernel boot sequence, so I was confident there were no pin-out issues, but following the kernel sequence I wasn’t being presented with a login prompt:

TLDR;

If you have this problem, first check that the following line is present and uncommented in your /etc/inittab file:

#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

If you’ve installed upstart on your Raspberry Pi, you must add the following file to /etc/init

/etc/init/ttyAMA0.conf

# ttyAMA0 - getty
#
# This service maintains a getty on ttyAMA0 from the point the system is
# started until it is shut down again.
 
start on runlevel [23] and not-container
 
stop on runlevel [!23]
 
respawn
exec /sbin/getty -L ttyAMA0 115200 vt100

THE DETAILS

I have a project that’s going to require me to configure the wifi on a Raspberry Pi in place. This made me nervous, as the only interface I would have available into the device was through WiFi, so a mistake in configuration would effectively brick the device.

Looking for a safer solution I stumbled upon the Adafruit USB to TTL cable. This cable allows you to access the serial terminal available through the pins on the Raspberry Pi header directly from the USB port of a computer without the need of other serial to usb converters. This is due to the embedded PL2303 chip in the cable that performs the conversion.

After following the instructions in this guide on Adafruit’s site, I was able to see the linux kernel boot sequence in a terminal on my mac:

...
[    9.614251] usbcore: registered new interface driver snd-usb-audio
[    9.716471] ieee80211 phy0: rt2x00_set_rt: Info - RT chipset 5390, rev 0502 detected
[   10.572707] FAT-fs (mmcblk0p5): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[   11.397452] ieee80211 phy0: rt2x00_set_rf: Info - RF chipset 5370 detected
[   11.567387] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup
[   11.903032] usbcore: registered new interface driver rt2800usb
[   12.114566] init: failsafe main process (292) killed by TERM signal
[   13.929262] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
[   13.986951] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.29
[   14.741621] init: udev-fallback-graphics main process (414) terminated with status 1

Unfortunately, after this I was supposed to see a login prompt, and no amount of waiting was seeing one appear. I logged into the Raspberry Pi, and did a quick ‘ps aux | grep getty’ to look for the getty process that is supposed to create the console on the serial port. The default getty processes were present, but I should have seen a process using the device ttyAMA0, and it wasn’t present:

pi@raspberrypi ~ $ ps aux | grep getty
root       664  0.0  0.1   3744   804 tty4     Ss+  02:03   0:00 /sbin/getty -8 38400 tty4
root       666  0.0  0.1   3744   804 tty5     Ss+  02:03   0:00 /sbin/getty -8 38400 tty5
root       671  0.0  0.1   3744   804 tty2     Ss+  02:03   0:00 /sbin/getty -8 38400 tty2
root       672  0.0  0.1   3744   804 tty3     Ss+  02:03   0:00 /sbin/getty -8 38400 tty3
root       674  0.0  0.1   3744   804 tty6     Ss+  02:03   0:00 /sbin/getty -8 38400 tty6
root       980  0.0  0.1   3744   804 tty1     Ss+  02:03   0:00 /sbin/getty -8 38400 tty1
pi        1912  0.0  0.1   3520   796 pts/0    S+   02:21   0:00 grep --color=auto getty

I started doing some digging, and all the relevant threads I could find kept on telling you to ensure that the relevant line used to launch getty on the serial port was uncommented like this:

/etc/inittab

# /sbin/getty invocations for the runlevels.
...
 
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

No matter how many times I checked, that last line was uncommented in my file, but my login prompt continued to fail to appear.

After lots of beating my head against the wall, I finally realized that earlier in setting up the environment I had installed Upstart on my installation of Raspbian. Upstart replaces the inittab script, and instead uses .conf files located at /etc/init. Looking at the .conf files, there was no file to start the getty process I needed for the serial port.

I added the following to /etc/init/ttyAMA0.conf:

# ttyAMA0 - getty
#
# This service maintains a getty on ttyAMA0 from the point the system is
# started until it is shut down again.
 
start on runlevel [23] and not-container
 
stop on runlevel [!23]
 
respawn
exec /sbin/getty -L ttyAMA0 115200 vt100

With this new .conf file in place I rebooted my pi, and a login prompt like the following:

...
[   13.771014] ieee80211 phy0: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
[   13.844754] ieee80211 phy0: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.29
[   14.282944] init: udev-fallback-graphics main process (405) terminated with status 1
��
Debian GNU/Linux 7 raspberrypi ttyAMA0
 
raspberrypi login:

Finally my serial login was working!

Tagged , , , , , , , , ,