Ceedling Temperature Sensor Project
An imagined temperature sensor accessory with ADC, timer, and USART subsystems — firmware organized in embedded C layers.
This example project illustrates:
- CMock mocks for isolating hardware and peripheral modules under test
- Custom Unity assertions for project-specific data types, defined in
test/support/ - Subdirectory test organization with ADC tests grouped in their own subfolder
- Integration tests alongside unit tests (
TestTimerIntegrated.c,TestUsartIntegrated.c) - Per-file symbol definitions via the
:definesmatcher section inproject.yml - Per-file compiler flags via the
:flagssection inproject.yml - Test preprocessor enabled for all files (
:use_test_preprocessor: :all) - Optional add-ons via mixins:
gcovplugin coverage reporting- Custom assertion activation for more detailed failure messages.
This project implements the Model-Conductor-Hardware design pattern:
- Model modules manage state and logic
- Hardware modules abstract hardware interfaces
- Conductors link the two together and service them
Mocks generated by CMock isolate each components for unit testing, and example integration tests demonstrate exercising cross-module and integrated behavior.
This project is test-suite only (no release build).
Project Structure
temp_sensor/
├── project.yml # Ceedling configuration
├── mixin/ # Optional add-on configuration
│ ├── add_gcov.yml # Enables gcov coverage collection and reporting
│ └── add_unity_helper.yml # Enables custom assertions for project-specific types
├── src/
│ ├── Main.c/.h # Application entry point
│ ├── Executor.c/.h # Task execution loop
│ ├── TaskScheduler.c/.h # Cooperative task scheduler
│ ├── Model.c/.h # Application data model
│ ├── TemperatureFilter.c/.h
│ ├── Adc*.c/.h # ADC conductor, hardware, and model layers
│ ├── Timer*.c/.h # Timer conductor, hardware, and model layers
│ ├── Usart*.c/.h # USART conductor, hardware, and model layers
│ ├── IntrinsicsWrapper.c/.h
│ ├── Types.h # Shared type definitions
│ └── calculators/ # Calculation utilities
│ ├── TemperatureCalculator.c/.h
│ └── UsartBaudRateRegisterCalculator.c/.h
└── test/
├── Test*.c # Unit and integration tests
├── adc/ # ADC subsystem tests
│ └── TestAdc*.c
└── support/ # Custom assertion helpers (not executed as tests)
├── UnityHelper.c # More assertion failure details than the default comparison
└── UnityHelper.h
Running the Tests
Run all unit and integration tests:
Run a single test file:
Run all tests matching a pattern:
Optional Mixins
Coverage with gcov
Collect and report test coverage (requires gcov and gcovr):
Custom Unity assertions
The project defines a custom assertion for EXAMPLE_STRUCT_T in
test/support/UnityHelper.h. It is conditionally compiled and activated
by the add_unity_helper mixin, which adds the required define and
registers the helper with CMock: