Skip to content

Commit 12fc08d

Browse files
authored
Fix/watchdog fix (#9)
* (fix) making test better and making clear singleton for watchdog impl * (fix) ignoring linter issue and fixing typo
1 parent 47d3357 commit 12fc08d

File tree

9 files changed

+89
-137
lines changed

9 files changed

+89
-137
lines changed

include/VCR_Constants.h

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,49 @@ const int ADC1_CS = 11; // MCP3208. ADC1 in VCR schematic. Used for extra thermi
1616
/* -------------------------------------------------- */
1717

1818
/* Channels on adc_0 */
19-
const int GLV_SENSE_CHANNEL = 0;
20-
const int CURRENT_SENSE_CHANNEL = 1;
21-
const int REFERENCE_SENSE_CHANNEL = 2;
22-
const int RL_LOADCELL_CHANNEL = 3;
23-
const int RR_LOADCELL_CHANNEL = 4;
24-
const int RL_SUS_POT_CHANNEL = 5;
25-
const int RR_SUS_POT_CHANNEL = 6;
19+
constexpr int GLV_SENSE_CHANNEL = 0;
20+
constexpr int CURRENT_SENSE_CHANNEL = 1;
21+
constexpr int REFERENCE_SENSE_CHANNEL = 2;
22+
constexpr int RL_LOADCELL_CHANNEL = 3;
23+
constexpr int RR_LOADCELL_CHANNEL = 4;
24+
constexpr int RL_SUS_POT_CHANNEL = 5;
25+
constexpr int RR_SUS_POT_CHANNEL = 6;
2626
// const int UNUSED_CHANNEL = 7;
2727

2828
/* Channels on ADC_1 */
29-
const int THERMISTOR_0 = 0;
30-
const int THERMISTOR_1 = 1;
31-
const int THERMISTOR_2 = 2;
32-
const int THERMISTOR_3 = 3;
33-
const int THERMISTOR_4 = 4;
34-
const int THERMISTOR_5 = 5;
35-
const int THERMISTOR_6 = 6;
36-
const int THERMISTOR_7 = 7;
29+
constexpr int THERMISTOR_0 = 0;
30+
constexpr int THERMISTOR_1 = 1;
31+
constexpr int THERMISTOR_2 = 2;
32+
constexpr int THERMISTOR_3 = 3;
33+
constexpr int THERMISTOR_4 = 4;
34+
constexpr int THERMISTOR_5 = 5;
35+
constexpr int THERMISTOR_6 = 6;
36+
constexpr int THERMISTOR_7 = 7;
3737

3838
/* Scaling and offset */
39-
const float GLV_SENSE_SCALE = (float)(24.0/((2.77149877/3.3)*4096.0)); //unsure about the multiplication by 4.0865
40-
const int GLV_SENSE_OFFSET = 0; //No offset for GLV
41-
const float CURRENT_SENSE_SCALE = (float)(24/((2.77149877/3.3)*4096)); //unsure about the multiplication by 4.0865
42-
const int CURRENT_SENSE_OFFSET = 0; //No offset for CURRENT_SENSE
43-
const float REFERENCE_SENSE_SCALE = (float)(24/((2.77149877/3.3)*4096)); //unsure about the multiplication by 4.0865
44-
const int REFERENCE_SENSE_OFFSET = 0; //No offset for REFERENCE_SENSE
39+
constexpr float GLV_SENSE_SCALE = (float)(24.0/((2.77149877/3.3)*4096.0)); //unsure about the multiplication by 4.0865
40+
constexpr int GLV_SENSE_OFFSET = 0; //No offset for GLV
41+
constexpr float CURRENT_SENSE_SCALE = (float)(24/((2.77149877/3.3)*4096)); //unsure about the multiplication by 4.0865
42+
constexpr int CURRENT_SENSE_OFFSET = 0; //No offset for CURRENT_SENSE
43+
constexpr float REFERENCE_SENSE_SCALE = (float)(24/((2.77149877/3.3)*4096)); //unsure about the multiplication by 4.0865
44+
constexpr int REFERENCE_SENSE_OFFSET = 0; //No offset for REFERENCE_SENSE
4545

4646
//Values are from the old MCU rev15
47-
const float RL_LOADCELL_SCALE = 0.1149f;
48-
const float RL_LOADCELL_OFFSET = 13.526f / RL_LOADCELL_SCALE;
49-
const float RR_LOADCELL_SCALE = 0.118f;
50-
const float RR_LOADCELL_OFFSET = 25.721f / RR_LOADCELL_SCALE;
47+
constexpr float RL_LOADCELL_SCALE = 0.1149f;
48+
constexpr float RL_LOADCELL_OFFSET = 13.526f / RL_LOADCELL_SCALE;
49+
constexpr float RR_LOADCELL_SCALE = 0.118f;
50+
constexpr float RR_LOADCELL_OFFSET = 25.721f / RR_LOADCELL_SCALE;
5151

5252
//does not matter that much
53-
const float RL_SUS_POT_SCALE = 1;
54-
const int RL_SUS_POT_OFFSET = 1;
55-
const float RR_SUS_POT_SCALE = 1;
56-
const int RR_SUS_POT_OFFSET = 1;
57-
58-
const int WATCHDOG_PIN = 36;
53+
constexpr float RL_SUS_POT_SCALE = 1;
54+
constexpr int RL_SUS_POT_OFFSET = 1;
55+
constexpr float RR_SUS_POT_SCALE = 1;
56+
constexpr int RR_SUS_POT_OFFSET = 1;
5957

58+
constexpr int WATCHDOG_PIN = 36;
6059

60+
namespace default_system_params
61+
{
62+
constexpr unsigned long KICK_INTERVAL_MS = 10UL;
63+
}
6164
#endif /* VCR_CONSTANTS */

include/VCR_Globals.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,5 @@ constexpr unsigned int channels_within_mcp_adc = 8;
1919
extern MCP_ADC<channels_within_mcp_adc> adc_0; // MCP3208. ADC0 in VCR schematic. Used for valuable telem data.
2020
extern MCP_ADC<channels_within_mcp_adc> adc_1; // MCP3208. ADC1 in VCR schematic. Used for extra thermistors or extra sensors while testing.
2121

22-
/* Watchdog pin */
23-
extern const int watchdog_pin;
2422

2523
#endif /* VCR_GLOBALS */
Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,39 @@
11
#ifndef WATCHDOG_SYSTEM_H
22
#define WATCHDOG_SYSTEM_H
33

4+
#include <etl/singleton.h>
45

56
/**
67
* This class controls the boolean _watchdog_state, but does not directly control the watchdog.
78
* WatchdogSystem provides functionality to initialize, monitor, and "kick" the watchdog to prevent system resets.
89
*
910
* NOTE: To ensure system responsiveness, WatchdogSystem requires periodic updates by calling the `get_watchdog_state()` method.
10-
* This toggles the _watchdog_state (if the interval has passed) and returns the new state, which must then be sent to the watchdog.
11-
* If this is not done within the `WATCHDOG_KICK_INTERVAL`, it assumes the system is unresponsive and may trigger a reset. The singleton design ensures
12-
* only one instance manages the watchdog, which will help mantain consistency and control.
13-
*
11+
* This toggles the _watchdog_state (if the interval has passed) and returns the new state, which must then be sent to the watchdog.
1412
*/
1513

16-
const unsigned long WATCHDOG_KICK_INTERVAL = 10; // milliseconds
1714

1815
class WatchdogSystem
1916
{
17+
public:
18+
19+
WatchdogSystem(const unsigned long kick_interval_ms = 10UL) : _watchdog_time(0), _watchdog_state(false), _watchdog_kick_interval(kick_interval_ms) {};
2020
private:
2121

2222
/*Private constructor*/
23-
WatchdogSystem() : _watchdog_time(0), _watchdog_state(false) {};
2423

2524
/* Watchdog last kicked time */
2625
unsigned long _watchdog_time;
27-
28-
/* Watchdog output state */
2926
bool _watchdog_state;
27+
unsigned long _watchdog_kick_interval;
28+
/* Watchdog output state */
3029

3130
public:
3231

33-
/*Getter to return the instance and make a new one if it hasn't been made yet*/
34-
static WatchdogSystem& getInstance()
35-
{
36-
static WatchdogSystem instance;
37-
return instance;
38-
}
39-
40-
/*Prevent copying*/
41-
WatchdogSystem(const WatchdogSystem&) = delete;
42-
43-
/*Prevent Assignment*/
44-
WatchdogSystem& operator= (const WatchdogSystem&) = delete;
45-
4632
/* Get/update watchdog state */
4733
bool get_watchdog_state(unsigned long curr_millis);
4834

4935
};
5036

37+
using WatchdogInstance = etl::singleton<WatchdogSystem>;
38+
5139
#endif /* WATCHDOG_SYSTEM_H */

lib/systems/src/WatchdogSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
bool WatchdogSystem::get_watchdog_state(unsigned long curr_millis)
66
{
77

8-
if ((curr_millis - _watchdog_time) > WATCHDOG_KICK_INTERVAL) {
8+
if ((curr_millis - _watchdog_time) > _watchdog_kick_interval) {
99
_watchdog_state = !_watchdog_state;
1010
_watchdog_time = curr_millis;
1111
}

platformio.ini

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ lib_deps_shared =
1111
https://github.com/hytech-racing/shared_firmware_types.git
1212
https://github.com/ssilverman/QNEthernet#v0.26.0
1313
https://github.com/hytech-racing/HT_SCHED
14-
14+
Embedded Template Library@^20.39.4
1515
; Teensy41 Environment. This environment is the primary environment for uploading code to the car.
1616
; * Build to verify the on-car software.
1717
; * UPLOAD to compile and upload on-car software.
@@ -26,11 +26,8 @@ build_unflags = -std=gnu++11
2626
build_flags =
2727
-std=c++17
2828
-D TEENSY_OPT_SMALLEST_CODE
29-
check_src_filters =
30-
+<include/*>
31-
+<lib/*>
32-
+<src/*>
33-
-<src/old_main.cpp>
29+
30+
3431
platform = teensy
3532
board = teensy41
3633
framework = arduino
@@ -50,9 +47,13 @@ lib_deps =
5047
[env:test_systems_env]
5148
platform = native
5249
test_framework = googletest
50+
; test_build_src = yes
5351
build_src_filter =
54-
-<**/*.c>
55-
-<**/*.cpp>
52+
-<VCR_Globals.cpp>
53+
-<VCR_Tasks.cpp>
54+
-<main.cpp>
55+
+<VCR_Constants.cpp>
56+
+<../test/test_systems/test_systems.cpp>
5657
build_unflags = -std=gnu++11
5758
build_flags =
5859
-std=c++17
@@ -62,4 +63,5 @@ lib_ignore =
6263
test_ignore=
6364
test_interfaces*
6465
lib_deps =
66+
google/googletest@^1.15.2
6567
${common.lib_deps_shared}

prepush.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
set -o pipefail
3+
pio run -e teensy41
4+
pio test -e test_systems_env
5+
pio check -e teensy41 --fail-on-defect high

src/VCR_Globals.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ VCRSystemData_s system_data;
1313

1414
/* ADC setup */
1515
MCP_ADC<channels_within_mcp_adc> adc_0 = MCP_ADC<8>(ADC0_CS); // MCP3208. ADC0 in VCR schematic. Used for valuable telem data.
16-
MCP_ADC<channels_within_mcp_adc> adc_1 = MCP_ADC<8>(ADC1_CS); // MCP3208. ADC1 in VCR schematic. Used for extra thermistors or extra sensors while testing.
16+
MCP_ADC<channels_within_mcp_adc> adc_1 = MCP_ADC<8>(ADC1_CS); // MCP3208. ADC1 in VCR schematic. Used for extra thermistors or extra sensors while testing.

src/VCR_Tasks.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
#include "VCR_Globals.h"
1616
#include "VehicleStateMachine.h"
1717

18-
19-
2018
bool init_read_adc0_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo)
2119
{
2220

@@ -52,8 +50,6 @@ bool run_read_adc0_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo&
5250

5351
HT_TASK::Task read_adc0_task = HT_TASK::Task(init_read_adc0_task, run_read_adc0_task, 10, 1000UL); // 1000us is 1kHz //NOLINT
5452

55-
56-
5753
bool run_tick_state_machine_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo)
5854
{
5955
VehicleStateMachine::getInstance().tick_state_machine(sysMicros / 1000, system_data); // tick function requires millis //NOLINT
@@ -62,8 +58,6 @@ bool run_tick_state_machine_task(const unsigned long& sysMicros, const HT_TASK::
6258

6359
HT_TASK::Task tick_state_machine_task = HT_TASK::Task(HT_TASK::DUMMY_FUNCTION, run_tick_state_machine_task, 2); // Idle (constant-update) task //NOLINT
6460

65-
66-
6761
bool init_read_adc1_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo)
6862
{
6963
/* NOLINTBEGIN */ // Thermistor channels are for testing purposes only, the pin numbers 0-7 are acceptable "magic numbers".
@@ -94,8 +88,6 @@ bool run_read_adc1_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo&
9488

9589
HT_TASK::Task read_adc1_task = HT_TASK::Task(init_read_adc1_task, run_read_adc1_task, 10, 40000UL); // 20000us is 25Hz //NOLINT
9690

97-
98-
9991
bool run_update_buzzer_controller_task(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo)
10092
{
10193

@@ -107,10 +99,16 @@ bool run_update_buzzer_controller_task(const unsigned long& sysMicros, const HT_
10799
HT_TASK::Task update_buzzer_controller_task = HT_TASK::Task(HT_TASK::DUMMY_FUNCTION, run_update_buzzer_controller_task, 10, 20000UL); // 20000us is 50hz //NOLINT
108100

109101

102+
bool create_watchdog(const unsigned long & sysMicros, const HT_TASK::TaskInfo &task_info)
103+
{
104+
WatchdogInstance::create(default_system_params::KICK_INTERVAL_MS); // this has issues for some reason with clang-tidy // NOLINT
105+
return true;
106+
}
110107

111108
bool run_kick_watchdog(const unsigned long& sysMicros, const HT_TASK::TaskInfo& taskInfo)
112109
{
113-
digitalWrite(WATCHDOG_PIN, WatchdogSystem::getInstance().get_watchdog_state(sysMicros / 1000)); //NOLINT
110+
digitalWrite(WATCHDOG_PIN, WatchdogInstance::instance().get_watchdog_state(sysMicros / 1000));
114111
return true;
115112
}
116-
HT_TASK::Task kick_watchdog_task = HT_TASK::Task(HT_TASK::DUMMY_FUNCTION, run_kick_watchdog, 3, 2000UL); // 2000us is 500hz //NOLINT
113+
114+
HT_TASK::Task kick_watchdog_task = HT_TASK::Task(create_watchdog, run_kick_watchdog, 3, 2000UL); // 2000us is 500hz // NOLINT

test/test_systems/test_watchdog.h

Lines changed: 21 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,29 @@
22
#include "gtest/gtest.h"
33
#include "WatchdogSystem.h"
44

5-
WatchdogSystem &watchdog = WatchdogSystem::getInstance();
6-
int time_var = 0; // starting time
7-
int time_arb = 2500; // arbitrary number greater than 2000
5+
#include "VCR_Constants.h"
86

9-
//Test case where time is 0 millisecs
10-
TEST (WatchdogSystemTesting, initial_state) {
11-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
12-
}
7+
TEST(WatchdogSystemTesting, test_watchdog) {
8+
WatchdogInstance::create(10);
139

14-
//Test consecutive steps
15-
TEST (WatchdogSystemTesting, next_state1) {
16-
time_var += 1; // time_var = 1
17-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
18-
}
19-
TEST (WatchdogSystemTesting, next_state2) {
20-
time_var += 1; // time_var = 2
21-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
22-
}
23-
TEST (WatchdogSystemTesting, next_state3) {
24-
time_var += 1; // time_var = 3
25-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
26-
}
27-
TEST (WatchdogSystemTesting, next_state4) {
28-
time_var += 1; // time_var = 4
29-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
30-
}
31-
TEST (WatchdogSystemTesting, next_state5) {
32-
time_var += 1; // time_var = 5
33-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
34-
}
35-
TEST (WatchdogSystemTesting, next_state6) {
36-
time_var += 1; // time_var = 6
37-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
38-
}
39-
TEST (WatchdogSystemTesting, next_state7) {
40-
time_var += 1; // time_var = 7
41-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
42-
}
43-
TEST (WatchdogSystemTesting, next_state8) {
44-
time_var += 1; // time_var = 8
45-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
46-
}
47-
TEST (WatchdogSystemTesting, next_state9) {
48-
time_var += 1; // time_var = 9
49-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
50-
}
51-
TEST (WatchdogSystemTesting, next_state10) {
52-
time_var += 1; // time_var = 10
53-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), false);
54-
}
55-
TEST (WatchdogSystemTesting, next_state11) {
56-
time_var += 1; // time_var = 11
57-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), true);
58-
}
59-
TEST (WatchdogSystemTesting, next_state12) {
60-
time_var += 1; // time_var = 12
61-
ASSERT_EQ(watchdog.get_watchdog_state(time_var), true);
62-
}
10+
WatchdogSystem &watchdog = WatchdogInstance::instance();
11+
const int time_var = 0; // starting time
12+
const int time_arb = 2500; // arbitrary number greater than 2000
6313

64-
//Test an arbituary time above 10 millisecs from previous time
65-
TEST (WatchdogSystemTesting, instance_state1) {
66-
ASSERT_EQ(watchdog.get_watchdog_state(time_arb), false);
67-
}
14+
const int end_time = 13;
6815

69-
//Test second arbituary time above 10 millisecs from previous time
70-
TEST (WatchdogSystemTesting, instance_state2) {
16+
for(int time = 0; time < end_time; time++)
17+
{
18+
if(time <= 10)
19+
{
20+
ASSERT_EQ(watchdog.get_watchdog_state(time), false);
21+
} else {
22+
ASSERT_EQ(watchdog.get_watchdog_state(time), true);
23+
}
24+
}
25+
26+
ASSERT_EQ(watchdog.get_watchdog_state(time_arb), false);
27+
28+
//Test an arbituary time above 1000 millisecs from previous time
7129
ASSERT_EQ(watchdog.get_watchdog_state(time_arb + 1000), true);
72-
}
30+
}

0 commit comments

Comments
 (0)