Martin Cowen (45)

Unit Testing Embedded C: Off-Target with CppUTest on Windows

The reasons for having unit tests in your projects are well-known and accepted; I'm not going to rehash them here. Whether you follow the school of thought that says you must write the tests first or your tests are written to prevent regressions and confirm that the implementation matches the design, you're going to need some unit tests. What I'm trying to do with unit tests is checking that complex logic matches the requirements, but I'm not necessarily interested in driver-level code or hardware-specific tests because the idea is to run them off-target. There needs to be as little friction as possible to you running the tests so that they get run frequently during the development process. Making them run as part of the build process means they don't get forgotten, but then they need to run fast to not…

Continue reading...

Building Embedded C Applications on Windows with GCC, CMake and Ninja

Most embedded C developers start writing their code on their microcontroller manufacturer's provided IDE - STM32CubeIDE, MPLAB X, TI Code Composer, NXP MCUXpresso, Segger Embedded Studio, Keil uVision, etc. The debugger support, peripheral setup tools and project structure support make this the right way to go, but at some point you should realise that these are not the best editors on the market and waiting for chip programming times makes your debugging cycle is slow. Although the manufacturer's IDE can be very capable, leveraging the power of Eclipse or NetBeans, there are many features of other editors like Visual Studio Code which make it preferable once your work moves away from the hardware-specific or register level debugging phases. VS Code is so much more customisable with themes, extendable with the extension marketplace and powerful with multi-pane, multi-window editing, as well…

Continue reading...

Using Finite State Machines to Implement Modal Applications

The ability to trace requirements through to implementation is an important property of commercial software development. As we know from the last 24 years of Agile, it's very rare to be able to obtain a complete, consistent and correct set of requirements at the start of the project, in practice they have to be continually refined during development. One of the common failings is to think only in terms of positive requirements - everything the product must do; and to forget the negative requirements - everything the product must not do. Very closely related is the problem arising from only specifying part of the logic, the default or happy path e.g. "when the button is pressed ..." and forgetting to specify the other part e.g. "when the button is released ...". It's not always obvious what the product should do…

Continue reading...

Countdown Timer for Children's Games: Firmware Design

In the first of these four blog posts on the firmware for the countdown timer, we'll look at the firmware layer design, the user interface functions and power consumption. The bargraph LEDs, buttons and switches are just GPIOs driven through my hardware independent driver layer, but there's more of interest in the seven segment display driver and speaker driver. Since there's no such peripheral as a seven segment display driver, at least not on this micro, I've had to write one. Driving the speaker with PWM proved slightly more difficult than you might expect, and there's some niceties around the sound that I wanted to include. We can't avoid main.c being generated by STM32CubeIDE and directly accessing the HAL, and it's the best place for the Wake pin callback, but we don't have to fall into the trap of putting…

Continue reading...

Countdown Timer for Children's Games: Hardware Design

The idea for this project was a simple countdown timer to be used by children for various games and activities where the user interface was designed to be as simple as possible; the display was clear from across the room and provided a sense of urgency, with a clear notification when the time was up. I started from the need for a large bright display, which meant using the largest economically available 7-segment LED modules. Starting a timer should be as simple as pressing a single button with a fixed function, so there is no time adjustment (up/down) facility which can be fiddly and non-obvious to use. Those often require long presses to get into a fast increment mode and are not consistent in how they accelerate. Choosing the time periods at the start of the project meant that the…

Continue reading...