STM32 (3)

Unit Testing Embedded C: On-Target with minunit and Off-Target with MS Test

Generally, the advice on unit testing in embedded environments is to run your tests on the PC host rather than on the target device. Whilst I agree that this is the most productive arrangement, there are a variety of reasons for needing to test on the target which can be convincing in certain situation. The technique described here allows for both. Mike Long in his GOTO 2015 presentation Continuous Delivery for Embedded Systems says "Test on your host because that's fast - it's a really fast way to develop. But also test on the target because behaviour can change in different ways, different compilers, different hardware..." Niall Cooling in his talk at the EmbeddedOnlineConference 2020 "How agile is changing the face of embedded software development" says (at 46m) on the gap between testing on the host and the target Things like TDD really are based on testing in the host, and really that's fine but of course we are typically using host compilers like host GCC and of course we know that at the moment this is typically going to be an Intel based processor. So we are compiling for the underlying OS. And it is good for finding a…

Continue reading...

Eliminate Useless Timer Interrupts by Coalescing Timers

While learning about RTOSes, I came across the idea of Timer Coalescing which improves performance by eliminating unnecessary context switches. But there is no reason that this technique cannot be applied to bare metal firmware (without RTOS). To test out how well it works, I implemented it using a STM32F4 discovery board. I wanted to see the improvement factor in a typical use case, so I decided on running 8 software timers on a 1ms timer peripheral. The software timers count down to 0 then reload themselves. From previous experience, typical periods were chosen for these timers of 1000, 200, 125, 50, 18, 27, 40 and 600ms. (If they had a common factor of say 5ms, then it would make more sense to use that as the peripheral timer rate, but it restricts the flexibility for future changes.) TIM6 was chosen because we only need a Basic 16 bit timer in the STM32F4 architecture. It runs off APB1 at 42 MHz (HCLK at 168 MHz). Prescaler was set to 41, Counter Period ARR set to 1999 for 1ms and auto-reload preload set to Disable. TIM6 interrupts were enabled. Once all this is set up in the Device Configuration Tool, all…

Continue reading...

Improving frequency measurement performance by factor of three on STM32 by using DMA

This Youtube video by Controllers Tech shows how to use an STM32 to measure the frequency of an incoming rectangular wave using the input capture functionality of the timers. The code shown the video works but there are a few areas which could be improved, as I will now discuss. Then I make a performance improvement by using DMA instead of interrupts. The code is written using STM's HAL library which means that it does not have to handle the specific STM32's registers, which makes it more portable. However, HAL is still specific to the ARM and STM architecture, so you need to know what features are available in your internal peripherals to be able to write HAL function calls with the appropriate parameters. Initialising Global variables Controllers Tech declares a set of global variables at the top of main.c and initialises them to zero. Since we can rely on the C runtime to clear the RAM, this is unnecessary for globals and can use up code space and boot time. I would remove the initialisations unless it is thought likely that these lines would be moved into a function, making them local automatic variables, in which case they would need to be initialised.

Continue reading...