Skip to content

Commit

Permalink
Heartbeat Refactor (#1325)
Browse files Browse the repository at this point in the history
### Changelist 
<!-- Give a list of the changes covered in this PR. This will help both
you and the reviewer keep this PR within scope. -->
- Changed structure of heartbeat monitor config. (see
`firmware/shared/src/app/app_heartbeatMonitorBoard.h`)
- Gives sturcture towards future app level refactor

### Testing Done
<!-- Outline the testing that was done to demonstrate the changes are
solid. This could be unit tests, integration tests, testing on the car,
etc. Include relevant code snippets, screenshots, etc as needed. -->
- fixed tests for all boards
- adapted shared heartbeat monitor to new structure

### Resolved Tickets
<!-- Link any tickets that this PR resolves. -->
  • Loading branch information
Lucien950 authored Dec 29, 2024
1 parent 1341a41 commit 6939b2d
Show file tree
Hide file tree
Showing 41 changed files with 418 additions and 1,043 deletions.
12 changes: 8 additions & 4 deletions firmware/cmake/shared.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ set(SHARED_EMBEDDED_DIR_CPP "${SHARED_DIR}/srcpp")
set(SHARED_APP_INCLUDE_DIR_CPP "${SHARED_EMBEDDED_DIR_CPP}/app")
set(SHARED_IO_INCLUDE_DIR_CPP "${SHARED_EMBEDDED_DIR_CPP}/io")
set(SHARED_HW_INCLUDE_DIR_CPP "${SHARED_EMBEDDED_DIR_CPP}/hw")
# code sources
file(GLOB_RECURSE SHARED_APP_SRCS "${SHARED_APP_INCLUDE_DIR}/*.c")
file(GLOB_RECURSE SHARED_IO_SRCS "${SHARED_IO_INCLUDE_DIR}/*.c")
file(GLOB_RECURSE SHARED_HW_SRCS "${SHARED_HW_INCLUDE_DIR}/*.c")

# Test Utils
set(SHARED_TEST_UTILS_INCLUDE_DIRS "${SHARED_DIR}/test_utils")
Expand Down Expand Up @@ -69,13 +73,13 @@ endfunction()
function(jsoncan_library BOARD CAR JSONCAN_DIR)
jsoncan_sources(
${BOARD}
"${JSONCAN_DIR}"
${JSONCAN_DIR}
FALSE
${CAR}
)
add_library(
"${CAR}_${BOARD}_jsoncan" STATIC
"${CAN_SRCS}"
"${CAR}_${BOARD}_jsoncan" INTERFACE
)
target_include_directories("${CAR}_${BOARD}_jsoncan" PUBLIC "${CAN_INCLUDE_DIRS}")
target_sources("${CAR}_${BOARD}_jsoncan" INTERFACE ${CAN_SRCS})
target_include_directories("${CAR}_${BOARD}_jsoncan" INTERFACE "${CAN_INCLUDE_DIRS}")
endfunction()
7 changes: 3 additions & 4 deletions firmware/cmake/tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function(compile_gtest_executable
target_compile_options(${TEST_EXECUTABLE_NAME}
PUBLIC
-Wall
-g3
)
target_link_libraries(${TEST_EXECUTABLE_NAME} gtest_main)
add_test(NAME ${TEST_EXECUTABLE_NAME}
Expand Down Expand Up @@ -61,9 +60,9 @@ function(create_fake_library

add_library(${LIB_NAME} STATIC ${FAKE_SRCS})
target_compile_options(${LIB_NAME}
PUBLIC
-Wall
-g3
PUBLIC
-Wall
-g3
)
target_include_directories(${LIB_NAME}
PUBLIC
Expand Down
3 changes: 3 additions & 0 deletions firmware/logfs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
message("")
message("⚙️ Configuring LogFS")

set(LOGFS_INCLUDE_DIRS
"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
Expand Down
1 change: 1 addition & 0 deletions firmware/quadruna/BMS/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ list(APPEND APP_SRCS
"${SHARED_APP_INCLUDE_DIR}/app_timer.c"
"${SHARED_APP_INCLUDE_DIR}/app_math.c"
"${SHARED_APP_INCLUDE_DIR}/app_heartbeatMonitor.c"
"${SHARED_APP_INCLUDE_DIR}/app_heartbeatBoard.c"
"${SHARED_APP_INCLUDE_DIR}/app_shdnLoopNode.c"
)
set(APP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/app" "${SHARED_APP_INCLUDE_DIR}" "${SHARED_APP_INCLUDE_QUADRUNA_DIR}")
Expand Down
1 change: 0 additions & 1 deletion firmware/quadruna/BMS/src/app/app_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <stdint.h>
#include "io_faultLatch.h"
#include "io_thermistors.h"
#include "app_heartbeatMonitor.h"
#include "app_timer.h"

typedef struct
Expand Down
20 changes: 20 additions & 0 deletions firmware/quadruna/BMS/src/app/app_heartbeatMonitors.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "app_heartbeatMonitors.h"
#include "app_canRx.h"
#include "app_canAlerts.h"
#include "app_canTx.h"

static HeartbeatBoard heartbeat_boards[1] = {
// vc
{
.getter = app_canRx_VC_Heartbeat_get,
.resetter = app_canRx_VC_Heartbeat_update,
.fault_setter = app_canAlerts_BMS_Warning_MissingVCHeartbeat_set,
.fault_getter = app_canAlerts_BMS_Warning_MissingVCHeartbeat_get,
.timeout_ms = 200,
}
};

HeartbeatMonitor hb_monitor = { .boards = heartbeat_boards,
.board_count = 1,
.block_faults = false,
.own_heartbeat = app_canTx_BMS_Heartbeat_set };
5 changes: 5 additions & 0 deletions firmware/quadruna/BMS/src/app/app_heartbeatMonitors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "app_heartbeatMonitor.h"

extern HeartbeatMonitor hb_monitor;
7 changes: 3 additions & 4 deletions firmware/quadruna/BMS/src/app/states/app_allStates.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "states/app_allStates.h"
#include "states/app_faultState.h"
#include "app_utils.h"
#include "app_thermistors.h"
#include "app_accumulator.h"
#include "app_tractiveSystem.h"
#include "app_imd.h"
Expand All @@ -11,6 +9,7 @@
#include "io_faultLatch.h"
#include "io_airs.h"
#include "io_bspdTest.h"
#include "app_heartbeatMonitors.h"

// Num of cycles for voltage and cell temperature values to settle
#define NUM_CYCLES_TO_SETTLE (30U)
Expand Down Expand Up @@ -55,8 +54,8 @@ bool app_allStates_runOnTick100Hz(void)
{
app_canTx_BMS_Heartbeat_set(true);

app_heartbeatMonitor_checkIn();
app_heartbeatMonitor_broadcastFaults();
app_heartbeatMonitor_checkIn(&hb_monitor);
app_heartbeatMonitor_broadcastFaults(&hb_monitor);

const bool balancing_enabled = app_canRx_Debug_CellBalancingRequest_get();

Expand Down
4 changes: 2 additions & 2 deletions firmware/quadruna/BMS/src/app/states/app_initState.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "states/app_allStates.h"
#include "app_utils.h"
#include "app_imd.h"
#include "app_soc.h"
#include "io_faultLatch.h"
#include "io_airs.h"
#include "app_inverterOnState.h"
#include "app_heartbeatMonitors.h"

#define TS_DISCHARGED_THRESHOLD_V (10.0f)

Expand Down Expand Up @@ -45,7 +45,7 @@ static void initStateRunOnTick100Hz(void)
{
const bool air_negative_closed = io_airs_isNegativeClosed();
const bool ts_discharged = app_tractiveSystem_getVoltage() < TS_DISCHARGED_THRESHOLD_V;
const bool missing_hb = app_heartbeatMonitor_isSendingMissingHeartbeatFault();
const bool missing_hb = app_heartbeatMonitor_isSendingMissingHeartbeatFault(&hb_monitor);

if (air_negative_closed && ts_discharged)
{
Expand Down
39 changes: 0 additions & 39 deletions firmware/quadruna/BMS/src/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,41 +211,6 @@ static const GlobalsConfig globals_config = { .bms_ok_latch = &bms_ok_latch,
.imd_ok_latch = &imd_ok_latch,
.bspd_ok_latch = &bspd_ok_latch };

// config for heartbeat monitor (can funcs and flags)
// BMS relies on VC
static const bool heartbeatMonitorChecklist[HEARTBEAT_BOARD_COUNT] = {
[BMS_HEARTBEAT_BOARD] = false, [VC_HEARTBEAT_BOARD] = true, [RSM_HEARTBEAT_BOARD] = false,
[FSM_HEARTBEAT_BOARD] = false, [DIM_HEARTBEAT_BOARD] = false, [CRIT_HEARTBEAT_BOARD] = false
};

// heartbeatGetters - get heartbeat signals from other boards
static bool (*const heartbeatGetters[HEARTBEAT_BOARD_COUNT])(void) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canRx_VC_Heartbeat_get,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatUpdaters - update local CAN table with heartbeat status
static void (*const heartbeatUpdaters[HEARTBEAT_BOARD_COUNT])(bool) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canRx_VC_Heartbeat_update,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatFaultSetters - broadcast heartbeat faults over CAN
static void (*const heartbeatFaultSetters[HEARTBEAT_BOARD_COUNT])(bool) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canAlerts_BMS_Warning_MissingVCHeartbeat_set,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatFaultGetters - gets fault statuses over CAN
static bool (*const heartbeatFaultGetters[HEARTBEAT_BOARD_COUNT])(void) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canAlerts_BMS_Warning_MissingVCHeartbeat_get,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

const Gpio *id_to_gpio[] = { [BMS_GpioNetName_ACCEL_BRAKE_OK_3V3] = &accel_brake_ok_pin,
[BMS_GpioNetName_AIR_P_EN] = &airs_config.air_p_gpio,
[BMS_GpioNetName_AUX_TSENSE_MUX0] = &thermistors_config.mux_0_gpio,
Expand Down Expand Up @@ -335,10 +300,6 @@ void tasks_init(void)
app_globals_init(&globals_config);
app_stateMachine_init(app_initState_get());

app_heartbeatMonitor_init(
heartbeatMonitorChecklist, heartbeatGetters, heartbeatUpdaters, &app_canTx_BMS_Heartbeat_set,
heartbeatFaultSetters, heartbeatFaultGetters);

// broadcast commit info
app_canTx_BMS_Hash_set(GIT_COMMIT_HASH);
app_canTx_BMS_Clean_set(GIT_COMMIT_CLEAN);
Expand Down
48 changes: 4 additions & 44 deletions firmware/quadruna/BMS/test/test_bmsBaseStateMachineTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <gtest/gtest.h>
#include "test_baseStateMachineTest.h"

#include "fake_io_time.hpp"
#include "fake_io_led.hpp"
#include "fake_io_airs.hpp"
#include "fake_io_sd.hpp"
Expand All @@ -21,7 +20,7 @@ extern "C"
#include "app_canRx.h"
#include "app_canAlerts.h"
#include "app_canUtils.h"
#include "app_heartbeatMonitor.h"
#include "app_heartbeatMonitors.h"
#include "app_stateMachine.h"
#include "app_utils.h"
#include "states/app_initState.h"
Expand All @@ -48,9 +47,9 @@ class BmsBaseStateMachineTest : public BaseStateMachineTest
app_canTx_init();
app_canRx_init();

app_heartbeatMonitor_init(
heartbeatMonitorChecklist, heartbeatGetters, heartbeatUpdaters, &app_canTx_BMS_Heartbeat_set,
heartbeatFaultSetters, heartbeatFaultGetters);
// Disable heartbeat monitor in the nominal case. To use representative heartbeat behavior,
// re-enable the heartbeat monitor.
app_heartbeatMonitor_blockFaults(&hb_monitor, true);

app_accumulator_init();
app_tractiveSystem_init();
Expand All @@ -76,10 +75,6 @@ class BmsBaseStateMachineTest : public BaseStateMachineTest

// Default to starting the state machine in the `init` state
app_stateMachine_init(app_initState_get());

// Disable heartbeat monitor in the nominal case. To use representative heartbeat behavior,
// re-enable the heartbeat monitor.
app_heartbeatMonitor_blockFaults(true);
}

void TearDown() override
Expand Down Expand Up @@ -121,41 +116,6 @@ class BmsBaseStateMachineTest : public BaseStateMachineTest
const FaultLatch imd_ok_latch = {};
const FaultLatch bspd_ok_latch = {};

// config for heartbeat monitor (can funcs and flags)
// BMS relies on VC
bool heartbeatMonitorChecklist[HEARTBEAT_BOARD_COUNT] = {
[BMS_HEARTBEAT_BOARD] = false, [VC_HEARTBEAT_BOARD] = true, [RSM_HEARTBEAT_BOARD] = false,
[FSM_HEARTBEAT_BOARD] = false, [DIM_HEARTBEAT_BOARD] = false, [CRIT_HEARTBEAT_BOARD] = false
};

// heartbeatGetters - get heartbeat signals from other boards
bool (*heartbeatGetters[HEARTBEAT_BOARD_COUNT])() = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canRx_VC_Heartbeat_get,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatUpdaters - update local CAN table with heartbeat status
void (*heartbeatUpdaters[HEARTBEAT_BOARD_COUNT])(bool) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canRx_VC_Heartbeat_update,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatFaultSetters - broadcast heartbeat faults over CAN
void (*heartbeatFaultSetters[HEARTBEAT_BOARD_COUNT])(bool) = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canAlerts_BMS_Warning_MissingVCHeartbeat_set,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

// heartbeatFaultGetters - gets fault statuses over CAN
bool (*heartbeatFaultGetters[HEARTBEAT_BOARD_COUNT])() = {
[BMS_HEARTBEAT_BOARD] = NULL, [VC_HEARTBEAT_BOARD] = app_canAlerts_BMS_Warning_MissingVCHeartbeat_get,
[RSM_HEARTBEAT_BOARD] = NULL, [FSM_HEARTBEAT_BOARD] = NULL,
[DIM_HEARTBEAT_BOARD] = NULL, [CRIT_HEARTBEAT_BOARD] = NULL
};

const GlobalsConfig globals_config = {
.bms_ok_latch = &bms_ok_latch,
.imd_ok_latch = &imd_ok_latch,
Expand Down
3 changes: 2 additions & 1 deletion firmware/quadruna/BMS/test/test_faults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,8 @@ TEST_F(BmsFaultTest, check_state_transition_fault_state_precharge_fault)
fake_io_airs_isNegativeClosed_returns(true);
app_canRx_Debug_StartCharging_update(false);
LetTimePass(210U);
ASSERT_EQ(app_prechargeState_get(), app_stateMachine_getCurrentState());
ASSERT_EQ(app_prechargeState_get(), app_stateMachine_getCurrentState())
<< "Given " << app_stateMachine_getCurrentState()->name << ", expected to be precharge state";
ASSERT_FALSE(app_canAlerts_BMS_Fault_PrechargeFailure_get());

// 3.8V nominal cell voltage * total # of cells to give estimate of nominal pack voltage
Expand Down
12 changes: 6 additions & 6 deletions firmware/quadruna/BMS/test/test_imd.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class ImdTest : public testing::Test
}
};

static void test_imd_setImdCondition(ImdConditionName condition_name)
static void test_imd_setImdCondition(const ImdConditionName condition_name)
{
const float mapping[NUM_OF_IMD_CONDITIONS] = {
[IMD_CONDITION_SHORT_CIRCUIT] = 0.0f, [IMD_CONDITION_NORMAL] = 10.0f,
[IMD_CONDITION_UNDERVOLTAGE_DETECTED] = 20.0f, [IMD_CONDITION_SST] = 30.0f,
[IMD_CONDITION_DEVICE_ERROR] = 40.0f, [IMD_CONDITION_GROUND_FAULT] = 50.0f,
const std::map<ImdConditionName, float> mapping{
{ IMD_CONDITION_SHORT_CIRCUIT, 0.0f }, { IMD_CONDITION_NORMAL, 10.0f },
{ IMD_CONDITION_UNDERVOLTAGE_DETECTED, 20.0f }, { IMD_CONDITION_SST, 30.0f },
{ IMD_CONDITION_DEVICE_ERROR, 40.0f }, { IMD_CONDITION_GROUND_FAULT, 50.0f }
};

fake_io_imd_getFrequency_returns(mapping[condition_name]);
fake_io_imd_getFrequency_returns(mapping.at(condition_name));
ASSERT_EQ(condition_name, app_imd_getCondition().name);
}
2 changes: 1 addition & 1 deletion firmware/quadruna/BMS/test/test_stateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ TEST_F(BmsStateMachineTest, no_charger_connected_missing_hb_init_state)
{
SetInitialState(app_initState_get());
fake_io_airs_isNegativeClosed_returns(true);
app_heartbeatMonitor_blockFaults(false);
app_heartbeatMonitor_blockFaults(&hb_monitor, false);
app_canRx_VC_Heartbeat_update(false);

LetTimePass(500U);
Expand Down
1 change: 1 addition & 0 deletions firmware/quadruna/CRIT/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ file(GLOB_RECURSE APP_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/app/*.c")
list(APPEND APP_SRCS
"${SHARED_APP_INCLUDE_DIR}/app_stateMachine.c"
"${SHARED_APP_INCLUDE_DIR}/app_heartbeatMonitor.c"
"${SHARED_APP_INCLUDE_DIR}/app_heartbeatBoard.c"
"${SHARED_APP_INCLUDE_DIR}/app_rangeCheck.c"
"${SHARED_APP_INCLUDE_DIR}/app_signal.c"
"${SHARED_APP_INCLUDE_DIR}/app_timer.c"
Expand Down
37 changes: 37 additions & 0 deletions firmware/quadruna/CRIT/src/app/app_heartbeatMonitors.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "app_heartbeatMonitors.h"

#include "app_canTx.h"
#include "app_canRx.h"
#include "app_canAlerts.h"

static HeartbeatBoard heartbeat_boards[4] = {
// bms
{ .getter = app_canRx_BMS_Heartbeat_get,
.resetter = app_canRx_BMS_Heartbeat_update,
.fault_setter = app_canAlerts_CRIT_Fault_MissingBMSHeartbeat_set,
.fault_getter = app_canAlerts_CRIT_Fault_MissingBMSHeartbeat_get,
.timeout_ms = 200 },
// vc
{ .getter = app_canRx_VC_Heartbeat_get,
.resetter = app_canRx_VC_Heartbeat_update,
.fault_setter = app_canAlerts_CRIT_Fault_MissingVCHeartbeat_set,
.fault_getter = app_canAlerts_CRIT_Fault_MissingVCHeartbeat_get,
.timeout_ms = 200 },
// rsm
{ .getter = app_canRx_RSM_Heartbeat_get,
.resetter = app_canRx_RSM_Heartbeat_update,
.fault_setter = app_canAlerts_CRIT_Fault_MissingRSMHeartbeat_set,
.fault_getter = app_canAlerts_CRIT_Fault_MissingRSMHeartbeat_get,
.timeout_ms = 200 },
// fsm
{ .getter = app_canRx_FSM_Heartbeat_get,
.resetter = app_canRx_FSM_Heartbeat_update,
.fault_setter = app_canAlerts_CRIT_Fault_MissingFSMHeartbeat_set,
.fault_getter = app_canAlerts_CRIT_Fault_MissingFSMHeartbeat_get,
.timeout_ms = 200 }
};

HeartbeatMonitor hb_monitor = { .boards = heartbeat_boards,
.board_count = 4,
.block_faults = false,
.own_heartbeat = app_canTx_CRIT_Heartbeat_set };
5 changes: 5 additions & 0 deletions firmware/quadruna/CRIT/src/app/app_heartbeatMonitors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include "app_heartbeatMonitor.h"

extern HeartbeatMonitor hb_monitor;
6 changes: 3 additions & 3 deletions firmware/quadruna/CRIT/src/app/app_mainState.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "app_mainState.h"
#include "app_driveMode.h"
#include "app_shdnLoop.h"
#include "app_heartbeatMonitor.h"
#include "app_leds.h"
#include "app_switches.h"
#include "app_heartbeatMonitors.h"

static void mainStateRunOnTick100Hz(void)
{
Expand All @@ -13,8 +13,8 @@ static void mainStateRunOnTick100Hz(void)

app_shdnLoop_broadcast();

app_heartbeatMonitor_checkIn();
app_heartbeatMonitor_broadcastFaults();
app_heartbeatMonitor_checkIn(&hb_monitor);
app_heartbeatMonitor_broadcastFaults(&hb_monitor);
}

static void mainStateRunOnEntry(void) {}
Expand Down
Loading

0 comments on commit 6939b2d

Please sign in to comment.