Ground Embedded KO Subscribe

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.

GROUND EMBEDDED · NOTEFirmware Design & Quality 04Unit testing 1volatile uint32_t *ODR 2 = (uint32_t*)0x40020014; 3*ODR |= (1u << 5); 4while (1) { 5 if (flag) toggle(); 6}

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

Test codeLogic under testInterfacefunction pointers · headerReal driver or a fake
With a thin boundary between logic and hardware, a fake can be plugged in for testing on a PC.
  • 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.

FREE PDFGet the 3 free ebooksIf you want to keep reading this topic as one book: BLDC motor control, serial communication and sensors at book length. PDFs are in Korean.Get them free →