Martin Cowen (44)

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 as being frequently updated that it is not really comparable to what the chip manufacturers' can offer. I've spent many development hours working in VS Code, using as an editor, saving the files then alt-tabbing over to the manufacturer's IDE to build, program, run, debug and step through. I know that this process is perfectly usable but it would be…

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 when logical states change back to their default, when conditions revert to normal or when users cancel operations, causing developers to make assumptions and resulting in a major source of bugs. The requirements always start life as a text document but once these start to become understood by the developers, we can translate them into diagrams. In larger and regulated…

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 our application logic in int main(void). Instead, we just call app_init() in the user code initialisation section, and app_run() in the while(1) loop, and let the app_main.c module handle the application layer. This structure allows it to be tested on the host without hardware problems getting in the way. board_config defines all the IO pins and peripheral register mappings so…

Continue reading...

Countdown Timer for Children's Games: Hardware Design

The idea for this project was a simple countdown timer to be used for various children's 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 front panel could be labelled. Seven periods covered the desired range of 10 seconds to 15 minutes and left one button to be used for cancel, making a nicely symmetrical 4 buttons arrangement down either side. A coloured bargraph display was designed to give a sense of what proportion of the original time has elapsed and how much remains, using 10%…

Continue reading...

Comment Driven Development for low-level design before coding

When trying to write code samples in front of someone else, for example during an interview, it's a good idea to start by writing down the steps required before converting those to code. Instead of writing them down just as a list, format them as comments with blank lines in between to make filling out the code easier. int main(void) { // fizz buzz example: // test integers in range 0 to 100 // print fizzbuzz if divisible by 3 and 5 // print fizz if divisible by 3 only // print buzz if divisible by 5 only // if none of the above conditions, just print the number } It's much easier to debug the algorithm or design by rearranging and changing those comment lines than by changing the code once you're committed to all the details - variable names and types, function names and signatures all need to be kept in sync. It allows you to explain your thinking out loud to others and yourself before you get into the implementation phase. Many practicing coders recognize that this is a good idea "I realized that's what I do in job interviews... I already do this but only in…

Continue reading...