GCC Code Coverage Report


Directory: ./
File: firmware/controllers/sensors/core/sensor.h
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 76.5% 13 0 17
Functions: 77.8% 7 0 9
Branches: 100.0% 1 0 1
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 /**
2 * @file sensor.h
3 * @brief Base class for sensors. Inherit this class to implement a new type of sensor.
4 *
5 * This file defines the basis for all sensor inputs to the ECU, and provides a registry
6 * so that consumers may be agnostic to how each sensor may work.
7 *
8 * HOW TO ADD A NEW SENSOR TYPE:
9 *
10 * 1. Add an entry to the enum in sensor_type.h. Be sure to add it ABOVE the placeholder
11 * at the end of the list.
12 *
13 * 2. In the init/sensor folder, create/modify logic to create an instance of the new sensor,
14 * configure it if necessary, and call its Register() function if it should be enabled.
15 * See init_fluid_pressure.cpp for a minimal example.
16 *
17 * 3. Consume the new sensor with Sensor::get(SensorType::MyNewSensor)
18 *
19 * Providers:
20 * Instantiate a subclass of Sensor, and implement the Get() function.
21 * Call Register() to install the new sensor in the registry, preparing it for use.
22 *
23 * Mocking:
24 * The sensor table supports mocking each sensors value. Call Sensor::SetMockValue to
25 * set a mock value for a particular sensor, and Sensor::ResetMockValue or
26 * Sensor::ResetAllMocks to reset one or all stored mock values.
27 *
28 * Composite Sensors:
29 * Some sensors may be implemented as composite sensors, ie sensors that depend on other
30 * sensors to determine their reading. For example, the throttle pedal may have a pair of
31 * potentiometers that provide redundancy for the pedal's position. Each one may be its
32 * own sensor, then with one "master" sensors that combines the results of the others, and
33 * provides validation of whether the readings agree.
34 *
35 * @date September 12, 2019
36 * @author Matthew Kennedy, (c) 2019
37 */
38
39 #pragma once
40
41 #include "sensor_type.h"
42 #include <rusefi/expected.h>
43
44 #include <cstddef>
45
46 using SensorResult = expected<float>;
47
48 // Fwd declare - nobody outside of Sensor.cpp needs to see inside this type
49 class SensorRegistryEntry;
50
51 class Sensor {
52 public:
53 // Register this sensor in the sensor registry.
54 // Returns true if registration succeeded, or false if
55 // another sensor of the same type is already registered.
56 bool Register();
57
58 // Print information about this sensor
59 virtual void showInfo(const char* sensorName) const = 0;
60
61 // Print information about all sensors
62 static void showAllSensorInfo();
63
64 // Print information about a particular sensor
65 static void showInfo(SensorType type);
66
67 // Remove all sensors from the sensor registry - tread carefully if you use this outside of a unit test
68 static void resetRegistry();
69
70 /*
71 * Static helper for sensor lookup
72 */
73 static const Sensor *getSensorOfType(SensorType type);
74
75 /*
76 * Get a reading from the specified sensor.
77 */
78 static SensorResult get(SensorType type);
79
80 /*
81 * Get a reading from the specified sensor, or zero if unavailable.
82 */
83 29395800 static float getOrZero(SensorType type) {
84
1/1
✓ Branch 2 taken 29395800 times.
29395800 return Sensor::get(type).value_or(0);
85 }
86
87 /*
88 * Get a raw (unconverted) value from the sensor, if available.
89 */
90 static float getRaw(SensorType type);
91
92 /*
93 * Get whether a sensor is redundant (a composite of multiple other sensors that can check consistency between them)
94 */
95 static bool isRedundant(SensorType type);
96
97 /*
98 * Query whether there is a sensor of a particular type currently registered.
99 */
100 static bool hasSensor(SensorType type);
101
102 /*
103 * Mock a value for a particular sensor.
104 */
105 static void setMockValue(SensorType type, float value, bool mockRedundant = false);
106
107
108 static void setInvalidMockValue(SensorType type);
109
110 /*
111 * Reset mock for a particular sensor.
112 */
113 static void resetMockValue(SensorType type);
114
115 /*
116 * Reset mocking for all sensors.
117 */
118 static void resetAllMocks();
119
120 /*
121 * Inhibit sensor timeouts. Used if you're doing something that will block sensor updates, such as
122 * erasing flash memory (which stalls the CPU on some MCUs)
123 */
124 static void inhibitTimeouts(bool inhibit);
125
126 /*
127 * Get a friendly name for the sensor.
128 * For example, CLT, IAT, Throttle Position 2, etc.
129 */
130 116 const char* getSensorName() const { return getSensorName(m_type); }
131 static const char* getSensorName(SensorType type);
132
133 // Retrieve the current reading from the sensor.
134 //
135 // Override this in a particular sensor's implementation. As reading sensors is in many hot paths,
136 // it is unwise to synchronously read the sensor or do anything otherwise costly here. At the most,
137 // this should be field lookup and simple math.
138 virtual SensorResult get() const = 0;
139
140 // Retrieve whether the sensor is present. Some sensors may be registered but not present, i.e. if initialization failed.
141 619432 virtual bool hasSensor() const {
142 619432 return true;
143 }
144
145 /*
146 * Get an unconverted value from the sensor, if available.
147 */
148 virtual float getRaw() const {
149 return 0;
150 }
151
152 /*
153 * Get whether this sensor is redundant (backed by multiple other sensors)
154 */
155 virtual bool isRedundant() const {
156 // By default sensors are not redundant
157 return false;
158 }
159
160 void unregister();
161
162 30 SensorType type() const {
163 30 return m_type;
164 }
165
166 protected:
167 // Protected constructor - only subclasses call this
168 1522 explicit Sensor(SensorType type)
169 1522 : m_type(type) {}
170
171 static bool s_inhibitSensorTimeouts;
172
173 private:
174 const SensorType m_type;
175
176 // Get this sensor's index in the list
177 1539 constexpr size_t getIndex() {
178 1539 return getIndex(m_type);
179 }
180
181 // Get the index in the list for a sensor of particular type
182 52444516 static constexpr size_t getIndex(SensorType type) {
183 52444516 return static_cast<size_t>(type);
184 }
185
186 /*
187 * Static helper for sensor lookup
188 */
189 static SensorRegistryEntry *getEntryForType(SensorType type);
190 };
191
192 SensorType findSensorTypeByName(const char *name);
193