← All selected work

Case study

One codebase for two product lines

Our onboard software was built for a modern computer. I ported it to an older generation of onboard computer with 512 MB of RAM and 1 GB of flash, which had been considered too small for it. That wasn't a recompile. I had to work out what the software really needed and cut the rest.

Context
Onboard platform port
Role
Porting, footprint reduction & target validation
Environment
Embedded Linux, older onboard computer
Focus
Memory, storage, runtime compatibility, stability

Context

Buses don't get replaced because the software moved on. An older computer that's already installed, wired and working can still be the right unit for a fleet. The question was whether our current software could run on it.

The company had two product lines on separate codebases. Porting the modern C++ stack (gcc 12) to the older computers would put one codebase on the whole fleet. It was the company's biggest technical challenge to date. The application stayed the same, with the driver touchscreen, passenger information, onboard services and the data behind them. It just had to fit in a much smaller box.

The problem

The older computer has less memory, less storage and an older Linux than the modern one. Dependencies that cost nothing on the modern unit suddenly mattered. I had to rethink startup time, display performance and recovery.

The obvious move is to keep the application as it is and squeeze the system around it. That tends to break somewhere. A runtime is missing, a library is too new, or the disk fills up the first time the device writes a log.

With 512 MB of RAM, every library has to earn its place.

Approach

I started by treating it as a size problem. I cut the application down to the screens, services and data paths a bus actually uses in service. Anything that was only there because the modern computer had room to spare got questioned.

Then I moved the older computer to TinyCore Linux and rebuilt the boot sequence, daemons and libraries around what it can handle, with stripped binaries. Where the display or startup code needed changes, I kept them below the application, so the modern computers kept behaving exactly as before.

Legacy platform constraints The onboard platform sits between a modern reference build and an older generation of onboard computer. Memory, storage, Linux userspace and the display stack constrain the port to the legacy target. Modern platform reference build Memory small working set no spare headroom Storage image + logs + data must fit the device Linux userspace older runtime fewer dependencies Display stack constrained graphics must stay responsive Onboard platform HMI + services + data one application, two targets Older computer port target port reference
The same application, constrained by the target. Memory, storage, userspace and display performance define the porting work.

What I built

  • A port of the onboard software to the older computer, from the same C++ codebase.
  • A TinyCore Linux base with a rebuilt boot sequence, daemons and libraries.
  • Display and startup changes for the smaller device.
  • Packaging that fits in 1 GB of flash, application and data included.
  • Testing on the real older unit as well as the modern one.

Choices I made

Measure the real machine

Everything feels cheap on a fast computer. So I started by measuring what the older one actually had in memory, storage, libraries and display speed, and designed for that.

Cut first, optimise later

The cheapest dependency is the one you don't ship. Removing libraries and features did more than tuning code that shouldn't have been running anyway.

Leave the screens alone

Drivers and passengers shouldn't notice that the hardware is older. The changes went into the layer under the application, and the interface code stayed the same.

Test on the real unit

Emulators and fast laptops help, but they won't give you a full disk, a slow display or an old kernel. The real unit is the only test that counts.

Where it ended up

One codebase now runs across the entire fleet, older computers included. Old hardware didn't mean freezing the product. It meant deciding what the software needs, what it can drop and where each change belongs.

Most of the work was close to the metal, in Linux, boot, libraries, packaging, memory and display. And most of the wins came from deleting things.