diff --git a/firmware/controllers/can/can.h b/firmware/controllers/can/can.h index 6492fcdb90..e3f5a3c303 100644 --- a/firmware/controllers/can/can.h +++ b/firmware/controllers/can/can.h @@ -7,7 +7,11 @@ #pragma once +#if EFI_UNIT_TEST +#include "can_mocks.h" +#else #include "hal.h" +#endif // EFI_UNIT_TEST #include "periodic_thread_controller.h" diff --git a/firmware/util/containers/fifo_buffer.h b/firmware/util/containers/fifo_buffer.h index f411873578..7a80f6d22c 100644 --- a/firmware/util/containers/fifo_buffer.h +++ b/firmware/util/containers/fifo_buffer.h @@ -15,6 +15,10 @@ #include "cyclic_buffer.h" +#if EFI_UNIT_TEST +#include "global.h" +#endif // EFI_UNIT_TEST + // todo: this is not a thread-safe version! template class fifo_buffer : public cyclic_buffer { @@ -92,7 +96,9 @@ template class fifo_buffer_sync : public fifo_buffer { public: fifo_buffer_sync() { +#if !EFI_UNIT_TEST osalThreadQueueObjectInit(&q_waiting); +#endif // EFI_UNIT_TEST } bool put(T item) override { @@ -116,7 +122,8 @@ public: } bool get(T &item, int timeout) { - chSysLock(); +#if !EFI_UNIT_TEST + chSysLock(); while (fifo_buffer::isEmpty()) { msg_t msg = osalThreadEnqueueTimeoutS(&q_waiting, timeout); if (msg != MSG_OK) { @@ -127,17 +134,22 @@ public: item = fifo_buffer::get(); chSysUnlock(); return true; +#endif // EFI_UNIT_TEST } void clear() { chSysLock(); fifo_buffer::clear(); +#if !EFI_UNIT_TEST osalThreadDequeueAllI(&q_waiting, MSG_RESET); +#endif // EFI_UNIT_TEST chSysUnlock(); } protected: +#if !EFI_UNIT_TEST threads_queue_t q_waiting; +#endif // EFI_UNIT_TEST }; -#endif /* FIFO_BUFFER_H */ \ No newline at end of file +#endif /* FIFO_BUFFER_H */ diff --git a/unit_tests/can_mocks.h b/unit_tests/can_mocks.h new file mode 100644 index 0000000000..47066d42aa --- /dev/null +++ b/unit_tests/can_mocks.h @@ -0,0 +1,68 @@ +#pragma once + +// This corresponds to ChibiOS/os/hal/ports/STM32/LLD/CANv1/hal_can_lld.h + +typedef uint32_t canmbx_t; +typedef int32_t can_msg_t; +typedef int32_t can_sysinterval_t; + +#define CAN_MSG_OK (can_msg_t)0 +#define CAN_MSG_TIMEOUT (can_msg_t)-1 + +typedef struct { + struct { + uint8_t DLC:4; /**< @brief Data length. */ + uint8_t RTR:1; /**< @brief Frame type. */ + uint8_t IDE:1; /**< @brief Identifier type. */ + }; + union { + struct { + uint32_t SID:11; /**< @brief Standard identifier.*/ + }; + struct { + uint32_t EID:29; /**< @brief Extended identifier.*/ + }; + }; + union { + uint8_t data8[8]; /**< @brief Frame data. */ + uint16_t data16[4]; /**< @brief Frame data. */ + uint32_t data32[2]; /**< @brief Frame data. */ + uint64_t data64[1]; /**< @brief Frame data. */ + }; +} CANTxFrame; + +// Unfortunately we cannot utilize the common base class for CANTxFrame and CANRxFrame, +// because FMI and TIME fields come first, and we don't want to affect the fields order. +typedef struct { + struct { + uint8_t FMI; /**< @brief Filter id. */ + uint16_t TIME; /**< @brief Time stamp. */ + }; + struct { + uint8_t DLC:4; /**< @brief Data length. */ + uint8_t RTR:1; /**< @brief Frame type. */ + uint8_t IDE:1; /**< @brief Identifier type. */ + }; + union { + struct { + uint32_t SID:11; /**< @brief Standard identifier.*/ + }; + struct { + uint32_t EID:29; /**< @brief Extended identifier.*/ + }; + }; + union { + uint8_t data8[8]; /**< @brief Frame data. */ + uint16_t data16[4]; /**< @brief Frame data. */ + uint32_t data32[2]; /**< @brief Frame data. */ + uint64_t data64[1]; /**< @brief Frame data. */ + }; +} CANRxFrame; + +#define CAN_IDE_STD 0 /**< @brief Standard id. */ +#define CAN_IDE_EXT 1 /**< @brief Extended id. */ + +#define CAN_RTR_DATA 0 /**< @brief Data frame. */ +#define CAN_RTR_REMOTE 1 /**< @brief Remote frame. */ + +#define CAN_ANY_MAILBOX 0U diff --git a/unit_tests/global.h b/unit_tests/global.h index 24919250e3..fb9c104b5b 100644 --- a/unit_tests/global.h +++ b/unit_tests/global.h @@ -62,6 +62,10 @@ void chDbgAssert(int c, char *msg, void *arg); #define CCM_OPTIONAL +#define chSysLock() {} +#define chSysUnlock() {} +#define osalThreadDequeueNextI(x, y) {} + #ifdef __cplusplus namespace chibios_rt { // Noop for unit tests - this does real lock in FW/sim