Category Archives: firmware

Working on the Console with the Raspberry Pi

The Raspberry Pi (I’m currently using the R Pi 3 Model B+) is a fantastic embedded Linux prototyping and development platform for hobbyists and tinkerers.

However, one of the thing that bugs me about it – by default, one can either hook it up to to a digital monitor or TV via HDMI (not ideal for developers, not for me at least!), or, much better, attach it to your local router via ethernet RJ45 cable and log in to it over ssh(1) from your laptop.

The Raspberry Pi 3 Model B: notice the power cable (bottom-rt) and ethernet RJ45 cable (top rt)

(My other pet grudge against  the R Pi is the completely closed bootloader; why can’t we just install and use U-Boot!?; can we? EDIT: yes we can indeed! The Yocto Project makes it easy to do…).

Another key point: for a long while I was using an inappropriate power supply and, for the lack of one, was destroying my (micro)SD cards! Using a proper “known to work” power supply for the R Pi is critical; I now use a “Elementz Engineers Guild 5V 3A USB to MicroUSB Charger for Raspberry Pi 3 Model B/RPi 2 Model B/B+/A+ (White)” power supply (purchased from Amazon India) and it works just great.

Why a Linux Console

So, while the ssh login is fine for most purposes, there are circumstances where there is no alternative but to have a Linux console device available right from boot up. Typical reasons include:

  • require access to the bootloader monitor or command line
  • kernel debug work (using KGDB or KDB, etc)
  • want  to work on kernel code within a console device (so that, for example, all printk’s appear immediately like printf’s)
  • … etc

How to do it

Essentially, to get a console, we require the old-style serial port and a simple RS-232 compatible ‘crossover’ cable – Tx<–>Rx :: target board <–> laptop serial port.

Only one problem: modern laptops (and even PCs) no longer have serial ports; now that’s not an earth-shaking point, we know this. So, of course, USB to the rescue: many USB-to-serial adapter cables exist, allowing us to relive the good ‘ol days! That’s exactly what I did – purchased and setup a nice, cheap and quite reliable little USB-to-serial cable; here are the gory details:

1. Purchased the “Imported USB To RS232 TTL UART PL2303HX Converter USB to COM Cable Adapter Module” from Amazon, India.

Imported USB To RS232 TTL UART PL2303HX Converter USB to COM Cable Adapter Module” from Amazon, India

2. Relevant technical info on amazon for the product:

“… Description:

Built in TTL COM PC PL2303HX Chip Standard USB type A male and TTL 4 Pin connector
Cable Length: Approx. 1m
Color: Black
Function: Serial communication Router or ADSL firmware upgrade GPS serial communication Hard drive firmware upgrade super terminal in use; Commonly used serial debugging tools All kinds of satellite machine for upgrading

Wiring:
Black cable-----GND 
Green cable-----TXD 
White cable-----RXD 
Red cable-------VCC 
Package includes: 1x USB to TTL Module"

The “Wiring” line above is what’s important to us..
IMP EDIT: I now realize that one should NOT use the 5V power line (usually the red wire) from the R Pi’s GPIO pin 2 (or 4); just connect the USB-to-serial cable to the R Pi device and the other (USB) end to the laptop/pc *without* connecting any power line. The R Pi has it’s own power after all…

3. For the Raspberry Pi boards, you must do this additional step:
If you want to use the UART console during booting on a Pi3 then you need to add the line `enable_uart=1` to config.txt [on the SDcard boot partition]. Also, you can use the normal UART pins for other functions without pinctrl getting in the way.”

4. So, lookup the R Pi’s GPIO header (particularly for the R Pi 3 as that’s what we’re using).

Useful ref: Interfacing hardware with the Raspberry Pi

R Pi 3 : GPIO Pinout ; image source

Connect the wires as follows (see the photo below as well):

RPi3 GPIO           USB<->RS232 TTL adapter
pin# (Func)         Color of wire (Func)
--------------     ------------------------
 2 (5V Vcc)          Red wire   (VCC)
 6 (GND)             Black wire (GND)
 8 (UART0 TX)        White wire (RXD)
10 (UART0 RX)        Green wire (TXD)

First attach the wires to the GPIO ensuring no power is applied to the R Pi device.
(As mentioned above): IMP EDIT: I now realize that one should probably NOT use the 5V power line from the R Pi’s GPIO pin 2 (or 4); just connect the USB-to-serial cable to the R Pi device and the other (USB) end to the laptop/pc *without* connecting any power line. The R Pi has it’s own power after all…

The USB-to-serial adapter’s three wires in the GPIO pins 6,8,10 of the R PI. DON’T attach the red power line!

[Above, an UPDATE: 17May21]
Another sketch showing how to connect the serial cable to the board;
Credit: https://ubs_csse.gitlab.io/secu_os/

5. Add a Linux console on the kernel command line:

Update: The Linux consoles on this device typically are:
– /dev/serial0 : soft link (same as) /dev/ttyS0
– /dev/serial1 : soft link (same as) /dev/ttyAMA0

(Backup /boot/cmdline.txt first and then)
Edit the /boot/cmdline.txt to have:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 console=ttyS0 root=PARTUUID=db8dd2db-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait 3

6. (Ref: RPi Serial Connection, eLinux)
6.1 Plug in the USB-to-serial adapter’s USB side to the PC/laptop. We do this first so that the host (laptop) kernel detects the device and assigns it a device node (via udev; typically, /dev/ttyUSB0). Can check this via dmesg: (on my host):

$ dmesg
[...]
[94933.835317] usb 1-1: new full-speed USB device number 8 using xhci_hcd
[94933.984283] usb 1-1: New USB device found, idVendor=067b, idProduct=2303, bcdDevice= 3.00
[94933.984294] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[94933.984302] usb 1-1: Product: USB-Serial Controller
[94933.984308] usb 1-1: Manufacturer: Prolific Technology Inc.
[94933.986152] pl2303 1-1:1.0: pl2303 converter detected
[94933.987003] usb 1-1: pl2303 converter now attached to ttyUSB0

6.2 On the PC/laptop, in a terminal window run a terminal emulator app – typically, screen or minicom (there are other choices as well, though am happy with minicom).

6.3 Setup the terminal emulator serial parameters correctly:
115200 8N1, Hardware and Software Flow Control Off.
For minicom: Ensure your login belongs to the ‘dialout’ group:

(One-time):
sudo usermod -a -G dialout username
sudo minicom -b 115200 -o -D <Port_Name>
; where Port_Name is usually /dev/ttyUSB0

If all okay, you should see the login (agetty) prompt from the Raspberry Pi (and, if you did it fast enough, the console printk’s from the kernel as it boots). Login defaults for Raspbian: username: pi, default pswd: raspberry.

minicom terminal emulator, with R Pi

Tips:

Advice to a Young Firmware Developer – by Jack Ganssle; and Assembly

I hope Jack Ganssle forgives my directly copying his content; the only reason I do so is that these thoughts of his are precious and I wish for more of us to read and appreciate them. (The discussion is definitely biased towards firmware/embedded developers that work primarily on a hardware platform using ‘C’ as the language. Just a small part of Jack’s excellent Embedded Muse newsletter is shown below; do check out the full article and subscribe to his newsletter). 

 

Directly copied from here: The Embedded Muse, Issue #362 by jack Ganssle, 19 Nov 2018.

Advice to a Young Firmware Developer

… Learn, in detail, how a computer works. You should be able to draw a detailed block diagram of one. Even if you have no interest in the hardware, it’s impossible to understand assembly language and other important aspects of creating firmware without understanding program counters, registers, busses and the like.

Learn an assembly language. Write real programs in it, and make them work. Absent a grounding in assembly much of the operation of a computer will be mysterious. In real life you’ll have to delve into the assembly at least occasionally, at least to work on the startup code, and to find some classes of bugs.

A recent article in IEEE Spectrum surveyed language use and C didn’t even make the cut. Java, Javascript, HMTL and Python were ranked as the most in-demand languages in the USA. Yet around 70% of firmware people work in C. C++ makes up another 20%. For better or worse, all of the other embedded languages are in the noise. Master C, pointers and all. (Rust is increasingly popular, yet, despite the hype, has under a 1% share in the embedded space).

But do learn some other languages. Python can be useful for scripting. Ada gives a discipline I wish more had.

Work in a cross-development environment with an embedded target board. It’s very different from using Visual Studio.

Get comfortable with a Linux shell. With sed, awk, and a hundred other tools you can do incredible things without writing any code.

Take the time to think through what you’re building. It’s tempting to start coding early. Design is critically important. Remember the old saying: “if you think good design is expensive, consider the cost of bad design.”

Monitor your bug rates. Forever. Skip this and you’ll never know two things: if you’re improving, and how you compare to the industry. We all think we’re great developers, but metrics can be a cold shower.

Always be on the prowl for tools. Some are free, others expensive, but great tools will make you more productive and less error-prone. These change all the time so figure on constantly refining your toolbox.

Did you know the average firmware person reads one technical book a year? Yet this field evolves at the pace of Moore’s Law. Constantly study software engineering. We do have a Body of Knowledge. Every year new ideas appear. Some are brilliant, others whacky, but they all make you think.

Learn about the hardware. At least get a general understanding. An engineer who can use an oscilloscope and logic analyzer for troubleshooting code is a valuable addition to a software team. Digital and analog hardware is cool and fascinating. …”


[Added on 24Feb2020]
Again, I couldn’t resist copy-pasting! … a well thought out answer on Quora to the question:
What are some things about coding that you learned from good programmers around you?
Here’s the full answer (by Håkon Hapnes Strand):

  1. Don’t be a lazy bastard. Do things the right way even if it’s a lot of work.
  2. Don’t give up on something just because you’re stuck. You’ll figure it out eventually.
  3. Always track down the root cause of a bug. If a bug just “goes away”, it hasn’t. If you can’t explain what fixed the bug, it isn’t.
  4. Write unit tests. It may seem unnecessary and a like lot of work, but it will help you in the long run. See point 1.
  5. Best practices are best practices for a reason. Don’t assume that your approach is better just because it’s what you’re used to.
  6. Make sure everything is reproducible. That includes data and infrastructure.
  7. If it’s not in version control, it doesn’t exist. (See point 6)
  8. Always abstract where it’s needed. Never abstract where it’s not needed.
  9. Think before you code.

So, okay, that’s the part of the article(s) I wanted to show.

Learning Assembly Language – Resources

How does one just learn assembly language then? Well, there are resources of course that help – books, online articles; here’s a few: