From 07be45af8065095f870ffc8c49a4f76c058651a7 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 25 Nov 2015 01:56:44 -0800 Subject: [PATCH] HAL: Increase safety during program termination. - Add an atexit hook to set global and watchdog to nullptr. - Add checks to HAL functions for these nullptrs (also good checks if they are called prior to HALInitialize). Change-Id: I138657e8279ed9289648a91c91091ea6a1eb5dcc --- hal/lib/Athena/HALAthena.cpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/hal/lib/Athena/HALAthena.cpp b/hal/lib/Athena/HALAthena.cpp index 378cb3db8e..b1ffcb1c20 100644 --- a/hal/lib/Athena/HALAthena.cpp +++ b/hal/lib/Athena/HALAthena.cpp @@ -9,6 +9,7 @@ #include "FRC_NetworkCommunication/UsageReporting.h" #include "FRC_NetworkCommunication/LoadOut.h" #include "FRC_NetworkCommunication/CANSessionMux.h" +#include #include #include #include @@ -19,8 +20,8 @@ const uint32_t dio_kNumSystems = tDIO::kNumSystems; const uint32_t interrupt_kNumSystems = tInterrupt::kNumSystems; const uint32_t kSystemClockTicksPerMicrosecond = 40; -static tGlobal *global; -static tSysWatchdog *watchdog; +static tGlobal *global = nullptr; +static tSysWatchdog *watchdog = nullptr; void* getPort(uint8_t pin) { @@ -152,6 +153,10 @@ const char* getHALErrorMessage(int32_t code) */ uint16_t getFPGAVersion(int32_t *status) { + if (!global) { + *status = NiFpga_Status_ResourceNotInitialized; + return 0; + } return global->readVersion(status); } @@ -165,6 +170,10 @@ uint16_t getFPGAVersion(int32_t *status) */ uint32_t getFPGARevision(int32_t *status) { + if (!global) { + *status = NiFpga_Status_ResourceNotInitialized; + return 0; + } return global->readRevision(status); } @@ -175,6 +184,10 @@ uint32_t getFPGARevision(int32_t *status) */ uint32_t getFPGATime(int32_t *status) { + if (!global) { + *status = NiFpga_Status_ResourceNotInitialized; + return 0; + } return global->readLocalTime(status); } @@ -184,6 +197,10 @@ uint32_t getFPGATime(int32_t *status) */ bool getFPGAButton(int32_t *status) { + if (!global) { + *status = NiFpga_Status_ResourceNotInitialized; + return false; + } return global->readUserButton(status); } @@ -195,14 +212,27 @@ int HALSetErrorData(const char *errors, int errorsLength, int wait_ms) bool HALGetSystemActive(int32_t *status) { + if (!watchdog) { + *status = NiFpga_Status_ResourceNotInitialized; + return false; + } return watchdog->readStatus_SystemActive(status); } bool HALGetBrownedOut(int32_t *status) { + if (!watchdog) { + *status = NiFpga_Status_ResourceNotInitialized; + return false; + } return !(watchdog->readStatus_PowerAlive(status)); } +static void HALCleanupAtExit() { + global = nullptr; + watchdog = nullptr; +} + /** * Call this to start up HAL. This is required for robot programs. */ @@ -222,6 +252,8 @@ int HALInitialize(int mode) global = tGlobal::create(&status); watchdog = tSysWatchdog::create(&status); + std::atexit(HALCleanupAtExit); + // Kill any previous robot programs std::fstream fs; // By making this both in/out, it won't give us an error if it doesnt exist