Electronic – firmware testing methods

8051firmwaresiliconlabsstm32testing

This is my first question here from the community 🙂

So I have inherited some bad embedded code, the whole firmware is a messy spaghetti state-machine that has an infinite number of states! and it is so messy that no one dares to touch it because testing it would take months (we don't have any automated testing systems)! so practically code maintenance is almost impossible.

The devices are used in Automation, they are responsible to measure few analogue signals and do calculations to estimate some physical qualities. We have three different types of devices that they even send data to each other and a state of one may impact other devices behaviour.

The hardware is based on SiliconLabs 8051 series. The compiler is Keil uVision with the C51 compiler.

I want to change this sticky situation and organise the code by introducing hardware abstraction layers and modularising the code to smaller chunks.

In order to achieve this goal, I personally think that we need to develop a test bench for devices that I can test them after refactoring and code cleaning. So the idea is to use another microcontroller (STM32) to fake the PCB's or MCU's inputs to simulate the actual environment that the device should work in. Since the behaviour of different devices has an impact on others, I think we have to have a test bench that represents a network of devices so we can also do integration testing.

I have been looking around the web and reading about ways to help me test this messy code, but I haven't found any other way of doing so.

What do you think? is there any other approach that I can take? or do you have any suggestions? how would you handle this situation?

Thanks!

EDIT:

Thank you everyone for your comments and replies!

So The firmware is tightly coupled and there are hardware dependencies and global variables everywhere, the firmware has more than 12,000 lines of code. The main issue here is that even the regression testing involves a hideous and time-consuming 100% manual process that requires the tester to have lots of physical interactions with the device itself and may take more than a day or two!

So I'm looking for a way to test (regression testing for now) the current firmware running on the MCU without the need to refactor and/or changing the code since even a small change in the FW requires intensive manual testing. My understanding is that by having a black-box test rig, that emulates the real environment for the device we can test the FW much quicker and even automate the process. Most of our devices have very limited inputs (like 3 analogue input, and 5 digital I/Os) and the main output is CAN messages that can be processed easily.

Another reason to invest in a HIL test rig is that it will help me to simulate scenarios involving other sub-systems (Integration testing). For instance, there are some ancient bugs in the FW CAN Bus networking that are really hard to identify without monitoring every device and being able to track which one of the devices on the network and during which condition is messing with the network.

Currently, if we want to validify FW we have to install it in an actual environment, collect the data for months ( 2-6 months!!) and analyse the data to validify the device's behaviour. Then you'd find out that there is a bug somewhere (it might even be caused by another device on the network) that is impacting the data you've collected!! Next, you have to do the same process again for another few months :(. I would prefer to automate these process to some extend, so we can at least catch the bugs and issues before installing the device in the real environment.

Best Answer

it is so messy that no one dares to touch it because testing it would take months

Same boat. Don't touch it unless you have to for a hotfix.

I want to change this sticky situation and organise the code by introducing hardware abstraction layers

You will run into the problem that 8051 is not designed to run C, it has very little of everything and the cost of abstraction is too high, especially in a mature product. You probably can't get a chip with more memory since you're at architecture limit.
You're probably also running into a lot of optimization hacks that destroy any last readability the C had.

What you can do however, is extract to inline functions and macros which you can then run in a mockup scenario. You emulate all the requisites for it to compile and then you can test your functions. This is a lot of work to do retroactively.

Some functions you probably can't test due to the side effects. This is a design flaw. You can't "fix" that cheaply.

Tech debt is real, and it's expensive. Don't make a mess again.


Note that depending on the compiler 8051 is often used in big-ending mode, this could make testing difficult depending on the micro-optimizations used in the code.


On your edit:
Sound like you're still looking to test only the software, but you don't want to take the hardware out of the loop. So you're going to mock the chip environment instead of the chip itself. Result can be equal, just a little bit more work.
Even the act of modifying the code to compile in vanilla gnu C can uncover bugs.