Modern Embedded Software – case study, GPS LapTimer device. Chapter 1

“Modern” approach to embedded software.
I have reached the stage where it would be good to be able to monitor the progress of the track riding. I have a choice: pay for a commercial device, or develop something of my own, from components I already have.
Since my treasure box contains an epapier module with ESP32, I have a GPS module and an accelerometer rolling around somewhere, and I have a battery for the whole thing, I decided to assemble something of my own. This is also a good opportunity to improve on my embedded systems programming skills.

Let’s try to complete laptimer components:

  • ePaper LilyGo T5 version 2.3 with a 2.13” display, no backlight, no touch layer. Instead, it has an SD card reader, battery charger, one button and ESP32 on board
  • The GPS module is a Chinese clone of the uBlox M10, without a compass (unfortunately), with the ability to sample up to 25Hz
  • The battery is a 1000mAh polymer battery, should last for a full day of driving
  • GY-521 accelerometer – MPU-6050 equivalent
  • The case will be printed on a 3D printer

Project conception

  • One button to setup start/stop GPS position for lap counting
  • Display with data:
    • Current lap time
    • Last lap time
    • Best lap time
    • Worst lap time
    • Graphic indicator, whatever the current lat is better or worse than previous
    • Lean angle, both current and max in a session
    • Max G value during acceleration/braking/cornering in a session
  • Settings menu:
    • Accelerometer calibration for lean angle measurement, after installing device on motorcycle
    • Track select: big or small to handle proper crossing line width
  • Storage of telemetric data on SD card:
    • Timestamp
    • GPS location
    • Velocity
    • Lap time
    • Lean angle
    • Summary for lap and session:
      • Best time
      • Worst time
      • Average time
      • Maximum value of lean angle
      • Maximum G acceleration value
      • Maximum G braking value
      • Maximum G cornering value
      • Session time
      • Lap counter

Software

So far, every embedded software project I’ve done has been fairly simple, because it has done relatively simple things.
This project, is designed to do several things at one time, plus it should be ready for development and present scientific value for me. So let’s abandon the Superloop architecture and learn something new.

The biggest issues I see with the traditional Superloop approach are:

  • Spaghetti – every programmer’s nightmare, i.e. mixing everything up
  • Concurrency – performing multiple tasks “simultaneously”, in the case of “large” computers, today there is no problem, each core can execute a separate thread, however, single-core microprocessors (yes, I know ESP32 has two cores), must somehow pretend multithreading

So, how can embedded programming be approached to eliminate issues?
Looking back in the history of software, especially operating systems, problems very quickly emerged and with them – solutions.

RTOS (real-time operating system, RTOS), an operating system that was developed to meet the requirements imposed, in time to perform the desired operations. This is roughly the ’60s of the last century. This is when Rate-monotonic scheduling (RMS) was developed. It is a method of optimal scheduling in RTOS. It is used to schedule periodic tasks without synchronization between them. Very quickly, it was found to be not enough. Around the ’80s, RTOS began to be written so that communication between threads was possible and that they used the same range of shared data. This approach to RTOS required access coordination. This is because it enforces competitiveness in accessing and modifying data, in such a way that the data remains consistent and in a predictable state. Any synchronization of threads is time-consuming for the processor.

You can approach this in a completely different way, using Events. That is, Event-Driven Programming. Cloud programmers, you probably know something 😉 The first operating systems using Event-Driven Programming were further back in the ’80s. It really started at the time of the entry of the first GUIs, when we needed to synchronize mouse, keyboard and other input hardware with UI elements. There was a similar problem with synchronizing asynchronous network processes.

What the Event Driven Programming is?

EDP, relies on a simple Event handler loop, which is the only one that enforces blocking synchronization.
It boils down to encapsulating threads so that they don’t share anything. The only communication between them is the exchange of messages through asynchronous Events.

State Machine

The second important component of the application, is the State Machine. This allows us to at least get rid of some of the spaghetti code. The traditional state machine, is a description of the states that occur in the application and the transitions between them.