diff --git a/src/main/blackbox/blackbox_io.c b/src/main/blackbox/blackbox_io.c index 245e67d65..c1fb2434b 100644 --- a/src/main/blackbox/blackbox_io.c +++ b/src/main/blackbox/blackbox_io.c @@ -40,8 +40,10 @@ static uint8_t blackboxMaxHeaderBytesPerIteration; // How many bytes can we write *this* iteration without overflowing transmit buffers or overstressing the OpenLog? int32_t blackboxHeaderBudget; -static serialPort_t *blackboxPort = NULL; +STATIC_UNIT_TESTED serialPort_t *blackboxPort = NULL; +#ifndef UNIT_TEST static portSharing_e blackboxPortSharing; +#endif #ifdef USE_SDCARD @@ -66,6 +68,7 @@ static struct { #endif +#ifndef UNIT_TEST void blackboxOpen() { serialPort_t *sharedBlackboxAndMspPort = findSharedSerialPort(FUNCTION_BLACKBOX, FUNCTION_MSP); @@ -73,6 +76,7 @@ void blackboxOpen() mspSerialReleasePortIfAllocated(sharedBlackboxAndMspPort); } } +#endif void blackboxWrite(uint8_t value) { @@ -541,6 +545,7 @@ bool blackboxDeviceFlushForce(void) /** * Attempt to open the logging device. Returns true if successful. */ +#ifndef UNIT_TEST bool blackboxDeviceOpen(void) { switch (blackboxConfig()->device) { @@ -611,6 +616,7 @@ bool blackboxDeviceOpen(void) return false; } } +#endif /** * Erase all blackbox logs @@ -650,6 +656,7 @@ bool isBlackboxErased(void) /** * Close the Blackbox logging device immediately without attempting to flush any remaining data. */ +#ifndef UNIT_TEST void blackboxDeviceClose(void) { switch (blackboxConfig()->device) { @@ -670,6 +677,7 @@ void blackboxDeviceClose(void) ; } } +#endif #ifdef USE_SDCARD diff --git a/src/test/Makefile b/src/test/Makefile index 14f767019..5edd12e68 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -46,6 +46,12 @@ battery_unittest_SRC := \ $(USER_DIR)/common/maths.c +blackbox_unittest_SRC := \ + $(USER_DIR)/blackbox/blackbox_io.c \ + $(USER_DIR)/common/encoding.c \ + $(USER_DIR)/common/printf.c \ + $(USER_DIR)/common/typeconversion.c + cms_unittest_SRC := \ $(USER_DIR)/cms/cms.c \ $(USER_DIR)/common/typeconversion.c \ diff --git a/src/test/unit/blackbox_unittest.cc b/src/test/unit/blackbox_unittest.cc new file mode 100644 index 000000000..3edf4197a --- /dev/null +++ b/src/test/unit/blackbox_unittest.cc @@ -0,0 +1,130 @@ +/* + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include +#include + +extern "C" { + #include "platform.h" + + #include "blackbox/blackbox.h" + #include "blackbox/blackbox_io.h" + #include "common/utils.h" + + #include "config/parameter_group.h" + #include "config/parameter_group_ids.h" + + #include "drivers/serial.h" + extern serialPort_t *blackboxPort; + + PG_REGISTER_WITH_RESET_TEMPLATE(blackboxConfig_t, blackboxConfig, PG_BLACKBOX_CONFIG, 0); + + PG_RESET_TEMPLATE(blackboxConfig_t, blackboxConfig, + .device = DEFAULT_BLACKBOX_DEVICE, + .rate_num = 1, + .rate_denom = 1, + .on_motor_test = 0 // default off + ); +} + +#include "unittest_macros.h" +#include "gtest/gtest.h" + + +static int serialWritePos = 0; +static int serialReadPos = 0; +static int serialReadEnd = 0; +#define SERIAL_BUFFER_SIZE 256 +static uint8_t serialReadBuffer[SERIAL_BUFFER_SIZE]; +static uint8_t serialWriteBuffer[SERIAL_BUFFER_SIZE]; + +serialPort_t serialTestInstance; + +void serialWrite(serialPort_t *instance, uint8_t ch) +{ + EXPECT_EQ(instance, &serialTestInstance); + EXPECT_LT(serialWritePos, sizeof(serialWriteBuffer)); + serialWriteBuffer[serialWritePos++] = ch; +} + +void serialWriteBuf(serialPort_t *instance, const uint8_t *data, int count) +{ + while(count--) + serialWrite(instance, *data++); +} + +void serialBeginWrite(serialPort_t *instance) +{ + EXPECT_EQ(instance, &serialTestInstance); +} + +void serialEndWrite(serialPort_t *instance) +{ + EXPECT_EQ(instance, &serialTestInstance); +} + +uint32_t serialRxBytesWaiting(const serialPort_t *instance) +{ + EXPECT_EQ(instance, &serialTestInstance); + EXPECT_GE(serialReadEnd, serialReadPos); + int ret = serialReadEnd - serialReadPos; + if (ret >= 0) return ret; + return 0; +} + +uint8_t serialRead(serialPort_t *instance) +{ + EXPECT_EQ(instance, &serialTestInstance); + EXPECT_LT(serialReadPos, serialReadEnd); + const uint8_t ch = serialReadBuffer[serialReadPos++]; + return ch; +} + +uint32_t serialTxBytesFree(const serialPort_t *instance) +{ + UNUSED(instance); + return SERIAL_BUFFER_SIZE - serialWritePos; +} + +bool isSerialTransmitBufferEmpty(const serialPort_t *instance) +{ + EXPECT_EQ(instance, &serialTestInstance); + return true; +} + +void serialTestResetBuffers() +{ + memset(&serialReadBuffer, 0, sizeof(serialReadBuffer)); + serialReadPos = 0; + serialReadEnd = 0; + memset(&serialWriteBuffer, 0, sizeof(serialWriteBuffer)); + serialWritePos = 0; +} + +TEST(BlackboxTest, Test1) +{ + blackboxPort = &serialTestInstance; + blackboxWriteUnsignedVB(0); + EXPECT_EQ(0, serialWriteBuffer[0]); + blackboxWriteUnsignedVB(128); + EXPECT_EQ(0x80, serialWriteBuffer[1]); + EXPECT_EQ(1, serialWriteBuffer[2]); +} + +// STUBS +extern "C" { +void mspSerialAllocatePorts(void) {} +} diff --git a/src/test/unit/target.h b/src/test/unit/target.h index 6f2bbbd62..e3b04dc19 100644 --- a/src/test/unit/target.h +++ b/src/test/unit/target.h @@ -20,6 +20,7 @@ #define CMS #define CMS_MAX_DEVICE 4 #define USE_FAKE_GYRO +#define BLACKBOX #define MAG #define BARO #define GPS @@ -61,6 +62,8 @@ #define TARGET_BOARD_IDENTIFIER "TEST" +#define DEFAULT_BLACKBOX_DEVICE BLACKBOX_DEVICE_SERIAL + #define LED_STRIP_TIMER 1 #define SOFTSERIAL_1_TIMER 2 #define SOFTSERIAL_2_TIMER 3