diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 00000000..f5c3c91f --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,23 @@ +name: Build and Test + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Configure and build with CMake + run: | + mkdir build + cd build + cmake .. + cmake --build . + + - name: Run unit tests + run: | + cd build + ./Software/test/Debug/events_test.exe diff --git a/.gitignore b/.gitignore index ea25fe55..c32db3bf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,8 @@ # Ignore any files in the build folder Software/build/ +# Ignore CMake build folder +build/ + +# Ignore unit tests *.exe \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..142d28c3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) + +project(BatteryEmulator) + +add_subdirectory(Software/src/devboard/utils) +add_subdirectory(Software/test) diff --git a/Software/src/devboard/utils/CMakeLists.txt b/Software/src/devboard/utils/CMakeLists.txt new file mode 100644 index 00000000..bded7cb0 --- /dev/null +++ b/Software/src/devboard/utils/CMakeLists.txt @@ -0,0 +1 @@ +# add_library(utils_library events.cpp) diff --git a/Software/src/devboard/utils/events.cpp b/Software/src/devboard/utils/events.cpp index 2157290c..06963830 100644 --- a/Software/src/devboard/utils/events.cpp +++ b/Software/src/devboard/utils/events.cpp @@ -14,9 +14,10 @@ static EVENTS_STRUCT_TYPE entries[EVENT_NOF_EVENTS]; static unsigned long previous_millis = 0; static uint32_t time_seconds = 0; static uint8_t total_led_color = GREEN; +static char event_message[256]; /* Local function prototypes */ -static void print_event_message(EVENTS_ENUM_TYPE event); +static void set_event_message(EVENTS_ENUM_TYPE event); static void update_led_color(EVENTS_ENUM_TYPE event); /* Exported functions */ @@ -42,7 +43,10 @@ void set_event(EVENTS_ENUM_TYPE event, uint8_t data) { entries[event].timestamp = time_seconds; entries[event].data = data; entries[event].occurences++; - print_event_message(event); + set_event_message(event); +#ifdef DEBUG_VIA_USB + Serial.println(event_message); +#endif } void update_event_timestamps(void) { @@ -58,69 +62,75 @@ static void update_led_color(EVENTS_ENUM_TYPE event) { total_led_color = (total_led_color == RED) ? RED : entries[event].led_color; } -static void print_event_message(EVENTS_ENUM_TYPE event) { -#ifndef DEBUG_VIA_USB - return; -#else +static void set_event_message(EVENTS_ENUM_TYPE event) { switch (event) { case EVENT_CAN_FAILURE: - Serial.println("No CAN communication detected for 60s. Shutting down battery control."); + snprintf(event_message, sizeof(event_message), + "No CAN communication detected for 60s. Shutting down battery control."); break; case EVENT_CAN_WARNING: - Serial.println("ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"); + snprintf(event_message, sizeof(event_message), + "ERROR: High amount of corrupted CAN messages detected. Check CAN wire shielding!"); break; case EVENT_WATER_INGRESS: - Serial.println("Water leakage inside battery detected. Operation halted. Inspect battery!"); + snprintf(event_message, sizeof(event_message), + "Water leakage inside battery detected. Operation halted. Inspect battery!"); break; case EVENT_12V_LOW: - Serial.println( - "12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); + snprintf(event_message, sizeof(event_message), + "12V battery source below required voltage to safely close contactors. Inspect the supply/battery!"); break; case EVENT_SOC_PLAUSIBILITY_ERROR: - Serial.println("ERROR: SOC% reported by battery not plausible. Restart battery!"); + snprintf(event_message, sizeof(event_message), "ERROR: SOC% reported by battery not plausible. Restart battery!"); break; case EVENT_KWH_PLAUSIBILITY_ERROR: - Serial.println("Warning: kWh remaining reported by battery not plausible. Battery needs cycling."); + snprintf(event_message, sizeof(event_message), + "Warning: kWh remaining reported by battery not plausible. Battery needs cycling."); break; case EVENT_BATTERY_CHG_STOP_REQ: - Serial.println("ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"); + snprintf(event_message, sizeof(event_message), + "ERROR: Battery raised caution indicator AND requested charge stop. Inspect battery status!"); break; case EVENT_BATTERY_DISCHG_STOP_REQ: - Serial.println("ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!"); + snprintf(event_message, sizeof(event_message), + "ERROR: Battery raised caution indicator AND requested discharge stop. Inspect battery status!"); break; case EVENT_BATTERY_CHG_DISCHG_STOP_REQ: - Serial.println( - "ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!"); + snprintf(event_message, sizeof(event_message), + "ERROR: Battery raised caution indicator AND requested charge/discharge stop. Inspect battery status!"); break; case EVENT_LOW_SOH: - Serial.println( + snprintf( + event_message, sizeof(event_message), "ERROR: State of health critically low. Battery internal resistance too high to continue. Recycle battery."); break; case EVENT_HVIL_FAILURE: - Serial.println( - "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be " - "disabled!"); + snprintf(event_message, sizeof(event_message), + "ERROR: Battery interlock loop broken. Check that high voltage connectors are seated. Battery will be " + "disabled!"); break; case EVENT_INTERNAL_OPEN_FAULT: - Serial.println("ERROR: High voltage cable removed while battery running. Opening contactors!"); + snprintf(event_message, sizeof(event_message), + "ERROR: High voltage cable removed while battery running. Opening contactors!"); break; case EVENT_CELL_UNDER_VOLTAGE: - Serial.println("ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); + snprintf(event_message, sizeof(event_message), + "ERROR: CELL UNDERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); break; case EVENT_CELL_OVER_VOLTAGE: - Serial.println("ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); + snprintf(event_message, sizeof(event_message), + "ERROR: CELL OVERVOLTAGE!!! Stopping battery charging and discharging. Inspect battery!"); break; case EVENT_CELL_DEVIATION_HIGH: - Serial.println("ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); + snprintf(event_message, sizeof(event_message), "ERROR: HIGH CELL DEVIATION!!! Inspect battery!"); break; case EVENT_UNKNOWN_EVENT_SET: - Serial.println("An unknown event was set! Review your code!"); + snprintf(event_message, sizeof(event_message), "An unknown event was set! Review your code!"); break; case EVENT_DUMMY: - Serial.println("The dummy event was set!"); + snprintf(event_message, sizeof(event_message), "The dummy event was set!"); // Don't change this event message! break; default: break; } -#endif } diff --git a/Software/src/devboard/utils/events.h b/Software/src/devboard/utils/events.h index 89573535..58abb58e 100644 --- a/Software/src/devboard/utils/events.h +++ b/Software/src/devboard/utils/events.h @@ -5,6 +5,8 @@ #include #endif +#include + typedef enum { EVENT_CAN_FAILURE = 0u, EVENT_CAN_WARNING, diff --git a/Software/src/devboard/utils/events_test.cpp b/Software/src/devboard/utils/events_test.cpp index cb893252..6678db2d 100644 --- a/Software/src/devboard/utils/events_test.cpp +++ b/Software/src/devboard/utils/events_test.cpp @@ -3,6 +3,11 @@ #include "events.cpp" +/* Helper functions */ +static void reset_event_msg(void) { + snprintf(event_message, sizeof(event_message), ""); +} + TEST(init_events_test) { init_events(); @@ -62,4 +67,12 @@ TEST(set_event_test) { ASSERT_EQ(entries[EVENT_CELL_OVER_VOLTAGE].timestamp, 345); } +TEST(event_message_test) { + reset_event_msg(); + + set_event(EVENT_DUMMY, 0); // Set dummy event with no data + + ASSERT_STREQ("The dummy event was set!", event_message); +} + TEST_MAIN(); diff --git a/Software/test/CMakeLists.txt b/Software/test/CMakeLists.txt new file mode 100644 index 00000000..30d2430d --- /dev/null +++ b/Software/test/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(events_test ../src/devboard/utils/events_test.cpp test_lib.cpp) + +target_compile_definitions(events_test PRIVATE UNIT_TEST) + +target_link_libraries(events_test) # Link to the library from devboard/utils