Notes / Firmware Design & Quality
Unit testing: verifying firmware without hardware
Logic that does not depend on hardware (PID, parsers, state machines) is tested on a PC. Unity, mocks and testable structure.
What to test
Pure logic that does not touch hardware: filters, PID, CRC, protocol parsers, state machines, unit conversions. Finding bugs in these on the board takes several times longer.
Unity example
void test_crc16_known_value(void) {
const uint8_t s[] = "123456789";
TEST_ASSERT_EQUAL_HEX16(0x4B37, crc16_modbus(s, 9));
}
void test_parser_rejects_bad_crc(void) {
feed(bad_packet, sizeof bad_packet);
TEST_ASSERT_FALSE(packet_ready());
}
Build and run with gcc on the PC, and run automatically on every commit in CI (GitHub Actions and the like).
RoadmapSee where this note sits in Firmware Design & Quality→How to cut the hardware dependency
- Separate logic from the HAL with a layered structure
- Swap hardware functions for fakes (mocks/stubs):
adc_read()returns the value the test set up - Tools such as CMock and fff generate fake functions from headers automatically
Good tests
- Boundary values: 0, the maximum, just before overflow
- Abnormal input: corrupted packets, out-of-range values
- One test checks one thing
In the V-model, unit testing is the verification stage paired with detailed design.