Skip to content

Commit

Permalink
Backup SRAM Unit Tests (#390)
Browse files Browse the repository at this point in the history
* Add backup memory functionality to testBoard

* Add unit tests for recovering from hardfaults

* Finish up backup sram tests
  • Loading branch information
BillThePlatypus authored Mar 16, 2020
1 parent 334dcfe commit cfe32fe
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 4 deletions.
113 changes: 113 additions & 0 deletions test/state_machine_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "rosflight.h"
#include "mavlink.h"
#include "test_board.h"
#include "state_manager.h"

using namespace rosflight_firmware;

Expand All @@ -20,6 +21,7 @@ class StateMachineTest : public ::testing::Test

void SetUp() override
{
board.backup_memory_clear();
rf.init();
rf.state_manager_.clear_error(rf.state_manager_.state().error_codes); // Clear All Errors to Start
rf.params_.set_param_int(PARAM_MIXER, 10);
Expand Down Expand Up @@ -389,3 +391,114 @@ TEST_F (StateMachineTest, RegainRCAfterFailsafe)
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
constexpr uint32_t StateManager::BackupData::ARM_MAGIC; // C++ is weird
TEST_F (StateMachineTest, NormalBoot)
{
board.backup_memory_clear();
rf.state_manager_.check_backup_memory();
EXPECT_EQ(rf.state_manager_.state().armed, false);
EXPECT_EQ(rf.state_manager_.state().error, false);
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
TEST_F(StateMachineTest, CrashRecoveryDisarmed)
{
board.backup_memory_clear();
StateManager::BackupData data;
data.arm_flag = 0;
data.error_code = 1;
data.reset_count = 1;
data.finalize();
board.backup_memory_write(&data, sizeof(data));
rf.state_manager_.check_backup_memory();
EXPECT_EQ(rf.state_manager_.state().armed, false);
EXPECT_EQ(rf.state_manager_.state().error, false);
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
TEST_F(StateMachineTest, CrashRecoveryArmed)
{
board.backup_memory_clear();
StateManager::BackupData data;
data.arm_flag = StateManager::BackupData::ARM_MAGIC;
data.error_code = 1;
data.reset_count = 1;
data.finalize();
board.backup_memory_write(&data, sizeof(data));
rf.state_manager_.check_backup_memory();
EXPECT_EQ(rf.state_manager_.state().armed, true);
EXPECT_EQ(rf.state_manager_.state().error, false);
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
TEST_F(StateMachineTest, CrashRecoveryInvalidChecksum)
{
board.backup_memory_clear();
StateManager::BackupData data;
data.arm_flag = StateManager::BackupData::ARM_MAGIC;
data.error_code = 1;
data.reset_count = 1;
data.finalize();
data.checksum += 1;
board.backup_memory_write(&data, sizeof(data));
rf.state_manager_.check_backup_memory();
EXPECT_EQ(rf.state_manager_.state().armed, false);
EXPECT_EQ(rf.state_manager_.state().error, false);
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
TEST_F(StateMachineTest, CrashRecoveryInvalidArmMagic)
{
board.backup_memory_clear();
StateManager::BackupData data;
data.arm_flag = StateManager::BackupData::ARM_MAGIC-101;
data.error_code = 1;
data.reset_count = 1;
data.finalize();
board.backup_memory_write(&data, sizeof(data));
rf.state_manager_.check_backup_memory();
EXPECT_EQ(rf.state_manager_.state().armed, false);
EXPECT_EQ(rf.state_manager_.state().error, false);
EXPECT_EQ(rf.state_manager_.state().error_codes, StateManager::ERROR_NONE);
EXPECT_EQ(rf.state_manager_.state().failsafe, false);
}
TEST_F(StateMachineTest, WriteBackupDataDisarmed)
{
board.backup_memory_clear();
const StateManager::BackupData::DebugInfo debug_info{1, 2, 3, 4, 5, 6, 7, 8};
rf.state_manager_.write_backup_data(debug_info);
StateManager::BackupData data;
board.backup_memory_read(&data, sizeof(data));
EXPECT_EQ(data.reset_count, 1);
EXPECT_EQ(data.arm_flag, 0);
EXPECT_TRUE(data.valid_checksum());
EXPECT_EQ(data.debug.r0, debug_info.r0);
EXPECT_EQ(data.debug.r1, debug_info.r1);
EXPECT_EQ(data.debug.r2, debug_info.r2);
EXPECT_EQ(data.debug.r3, debug_info.r3);
EXPECT_EQ(data.debug.r12, debug_info.r12);
EXPECT_EQ(data.debug.lr, debug_info.lr);
EXPECT_EQ(data.debug.pc, debug_info.pc);
EXPECT_EQ(data.debug.psr, debug_info.psr);
}

TEST_F(StateMachineTest, WriteBackupDataArmed)
{
board.backup_memory_clear();
rf.state_manager_.set_event(StateManager::EVENT_REQUEST_ARM);
StateManager::BackupData::DebugInfo debug_info{1, 2, 3, 4, 5, 6, 7, 8};
rf.state_manager_.write_backup_data(debug_info);
StateManager::BackupData data;
board.backup_memory_read(&data, sizeof(data));
EXPECT_EQ(data.reset_count, 1);
EXPECT_EQ(data.arm_flag, StateManager::BackupData::ARM_MAGIC);
EXPECT_TRUE(data.valid_checksum());
EXPECT_EQ(data.debug.r0, debug_info.r0);
EXPECT_EQ(data.debug.r1, debug_info.r1);
EXPECT_EQ(data.debug.r2, debug_info.r2);
EXPECT_EQ(data.debug.r3, debug_info.r3);
EXPECT_EQ(data.debug.r12, debug_info.r12);
EXPECT_EQ(data.debug.lr, debug_info.lr);
EXPECT_EQ(data.debug.pc, debug_info.pc);
EXPECT_EQ(data.debug.psr, debug_info.psr);
}
32 changes: 31 additions & 1 deletion test/test_board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ void testBoard::set_imu(float *acc, float *gyro, uint64_t time_us)


// setup
void testBoard::init_board() {}
void testBoard::init_board()
{
backup_memory_clear();
}
void testBoard::board_reset(bool bootloader) {}

// clock
Expand Down Expand Up @@ -110,6 +113,33 @@ bool testBoard::imu_read(float accel[3], float *temperature, float gyro[3], uint
return true;
}

bool testBoard::backup_memory_read(void *dest, size_t len)
{
bool success = true;
if(len > BACKUP_MEMORY_SIZE)
{
len = BACKUP_MEMORY_SIZE;
success = false;
}
memcpy(dest, backup_memory_, len);
return success;
}

void testBoard::backup_memory_write(const void *src, size_t len)
{
if(len > BACKUP_MEMORY_SIZE)
len = BACKUP_MEMORY_SIZE;
memcpy(backup_memory_, src, len);
}
void testBoard::backup_memory_clear(size_t len)
{
memset(backup_memory_, 0, len);
}
void testBoard::backup_memory_clear()
{
backup_memory_clear(BACKUP_MEMORY_SIZE);
}

void testBoard::imu_not_responding_error() {}

bool testBoard::mag_present() { return false; }
Expand Down
9 changes: 6 additions & 3 deletions test/test_board.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class testBoard : public Board
float acc_[3] = {0, 0, 0};
float gyro_[3] = {0, 0, 0};
bool new_imu_ = false;
static constexpr size_t BACKUP_MEMORY_SIZE{1024};
uint8_t backup_memory_[BACKUP_MEMORY_SIZE];

public:
// setup
Expand Down Expand Up @@ -130,9 +132,10 @@ class testBoard : public Board

//Backup memory
void backup_memory_init() override {}
bool backup_memory_read(void *dest, size_t len) override { (void)dest; (void)len; return false; }
void backup_memory_write(const void *src, size_t len) override { (void)src; (void)len; }
void backup_memory_clear(size_t len) override { (void)len; }
bool backup_memory_read(void *dest, size_t len) override;
void backup_memory_write(const void *src, size_t len) override;
void backup_memory_clear(size_t len) override;
void backup_memory_clear(); // Not an override

void set_imu(float *acc, float *gyro, uint64_t time_us);
void set_rc(uint16_t *values);
Expand Down

0 comments on commit cfe32fe

Please sign in to comment.