1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-21 15:25:36 +03:00

Adding a per-target unit test for timer metadata consistency.

This commit is contained in:
Andrej Podzimek 2018-09-10 22:58:01 +02:00
parent 17b66067bb
commit 9d553380c3
11 changed files with 317 additions and 51 deletions

View file

@ -0,0 +1,103 @@
/*
* This file is part of Betaflight.
*
* Betaflight 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.
*
* Betaflight 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 Betaflight. If not, see <http://www.gnu.org/licenses/>.
*/
extern "C" {
#include <target.h>
#include <drivers/timer.h>
extern const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT];
}
#include <bitset>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include "gtest/gtest.h"
TEST(TimerDefinitionTest, Test_counterMismatch) {
for (const timerHardware_t &t : timerHardware)
ASSERT_EQ(&t - timerHardware, t.def_tim_counter)
<< "Counter mismatch in timerHardware (in target.c) at position "
<< &t - timerHardware << "; the array may have uninitialized "
<< "trailing elements. This happens when USABLE_TIMER_CHANNEL_COUNT"
<< " is not equal to the number of array initializers. Current "
<< "value is " << USABLE_TIMER_CHANNEL_COUNT << ", last initialized"
<< " array element appears to be " << &t - timerHardware - 1 << '.';
}
TEST(TimerDefinitionTest, Test_duplicatePin) {
std::set<TestPinEnum> usedPins;
for (const timerHardware_t &t : timerHardware)
EXPECT_TRUE(usedPins.emplace(t.pin).second)
<< "Pin " << TEST_PIN_NAMES[t.pin] << " is used more than once. "
<< "This is a problem with the timerHardware array (in target.c). "
<< "Check the array for typos. Then check the size of the array "
<< "initializers; it must be USABLE_TIMER_CHANNEL_COUNT.";
EXPECT_EQ(USABLE_TIMER_CHANNEL_COUNT, usedPins.size());
}
namespace {
std::string writeUsedTimers(const std::bitset<TEST_TIMER_SIZE> &tset) {
std::stringstream used_timers;
if (tset.any()) {
unsigned int timer{0};
for (; timer < TEST_TIMER_SIZE; ++timer)
if (tset[timer]) {
used_timers << "( TIM_N(" << timer << ')';
break;
}
for (++timer; timer < TEST_TIMER_SIZE; ++timer)
if (tset[timer]) used_timers << " | TIM_N(" << timer << ')';
used_timers << " )";
} else {
used_timers << "(0)";
}
return used_timers.str();
}
}
TEST(TimerDefinitionTest, Test_usedTimers)
{
std::bitset<TEST_TIMER_SIZE> expected;
for (const timerHardware_t &t : timerHardware)
expected |= TIM_N(t.timer);
const std::bitset<TEST_TIMER_SIZE> actual{USED_TIMERS};
EXPECT_EQ(expected, actual)
<< "Used timers mismatch. target.c says " << expected << ", but "
<< "target.h says " << actual << ". This has two possible causes: "
<< "(1) The USED_TIMERS bitmap (in target.h) is outdated and out of "
<< "sync with timerHardware (in target.c). (2) There is an "
<< "inconsistency between USABLE_TIMER_CHANNEL_COUNT and the length "
<< "of timerHardware's initializer list.";
std::cerr
<< "USED_TIMERS definition based on timerHardware:" << std::endl
<< writeUsedTimers(expected) << std::endl;
}
// STUBS
extern "C" {
void spiPinConfigure(int) {}
int spiPinConfig(int) { return 0; }
void spiInit(int) {}
int i2cConfig(int) { return 0; }
void i2cHardwareConfigure(int) {}
void i2cInit(int) {}
void bstInit(int) {}
}

View file

@ -0,0 +1,21 @@
#include <mock_enums.h>
typedef struct timerHardware_s {
enum TestTimerEnum timer;
enum TestChannelEnum channel;
enum TestPinEnum pin;
enum TestTimUseEnum purpose;
unsigned int def_tim_counter;
} timerHardware_t;
// F7 and F4 have 6 arguments, F3 and F1 have 5 arguments.
#define DEF_TIM(timer_, channel_, pin_, purpose_, ...) \
{ \
.timer = timer_, \
.channel = channel_, \
.pin = pin_, \
.purpose = purpose_, \
.def_tim_counter = __COUNTER__, \
}
#define TIM_N(n) (1 << (n))

View file

@ -0,0 +1,66 @@
#pragma once
enum TestTimerEnum {
TIM0, TIM1, TIM2, TIM3, TIM4, TIM5, TIM6, TIM7, TIM8, TIM9,
TIM10, TIM11, TIM12, TIM13, TIM14, TIM15, TIM16, TIM17, TIM18, TIM19, TIM20,
TEST_TIMER_SIZE,
};
enum TestChannelEnum {
CH0, CH1, CH2, CH3, CH4, CH5, CH6, CH7, CH9, CH10, CH1N, CH2N, CH3N,
TEST_CHANNEL_SIZE,
};
// Keep this in sync with TEST_PIN_NAMES below.
enum TestPinEnum {
PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, PA8, PA9,
PA10, PA11, PA12, PA13, PA14, PA15,
PB0, PB1, PB2, PB3, PB4, PB5, PB6, PB7, PB8, PB9,
PB10, PB11, PB12, PB13, PB14, PB15,
PC0, PC1, PC2, PC3, PC4, PC5, PC6, PC7, PC8, PC9,
PC10, PC11, PC12, PC13, PC14, PC15,
PD0, PD1, PD2, PD3, PD4, PD5, PD6, PD7, PD8, PD9,
PD10, PD11, PD12, PD13, PD14, PD15,
PE0, PE1, PE2, PE3, PE4, PE5, PE6, PE7, PE8, PE9,
PE10, PE11, PE12, PE13, PE14, PE15,
PF0, PF1, PF2, PF3, PF4, PF5, PF6, PF7, PF8, PF9,
PF10, PF11, PF12, PF13, PF14, PF15,
PG0, PG1, PG2, PG3, PG4, PG5, PG6, PG7, PG8, PG9,
PG10, PG11, PG12, PG13, PG14, PG15,
PH0, PH1, PH2, PH3, PH4, PH5, PH6, PH7, PH8, PH9,
PH10, PH11, PH12, PH13, PH14, PH15, TEST_PIN_SIZE,
};
// Keep this in sync with TestPinEnum above.
const char *const TEST_PIN_NAMES[TEST_PIN_SIZE] = {
"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7", "PA8", "PA9",
"PA10", "PA11", "PA12", "PA13", "PA14", "PA15",
"PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PB8", "PB9",
"PB10", "PB11", "PB12", "PB13", "PB14", "PB15",
"PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7", "PC8", "PC9",
"PC10", "PC11", "PC12", "PC13", "PC14", "PC15",
"PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PD8", "PD9",
"PD10", "PD11", "PD12", "PD13", "PD14", "PD15",
"PE0", "PE1", "PE2", "PE3", "PE4", "PE5", "PE6", "PE7", "PE8", "PE9",
"PE10", "PE11", "PE12", "PE13", "PE14", "PE15",
"PF0", "PF1", "PF2", "PF3", "PF4", "PF5", "PF6", "PF7", "PF8", "PF9",
"PF10", "PF11", "PF12", "PF13", "PF14", "PF15",
"PG0", "PG1", "PG2", "PG3", "PG4", "PG5", "PG6", "PG7", "PG8", "PG9",
"PG10", "PG11", "PG12", "PG13", "PG14", "PG15",
"PH0", "PH1", "PH2", "PH3", "PH4", "PH5", "PH6", "PH7", "PH8", "PH9",
"PH10", "PH11", "PH12", "PH13", "PH14", "PH15",
};
enum TestTimUseEnum {
TIM_USE_ANY,
TIM_USE_BEEPER,
TIM_USE_CAMERA_CONTROL,
TIM_USE_LED,
TIM_USE_MOTOR,
TIM_USE_NONE,
TIM_USE_PPM,
TIM_USE_PWM,
TIM_USE_SERVO,
TIM_USE_TRANSPONDER,
TEST_TIM_USE_SIZE,
};

View file

@ -0,0 +1 @@
void bstInit(int);

View file

@ -0,0 +1,5 @@
#define I2CDEV_2 (1)
int i2cConfig(int);
void i2cHardwareConfigure(int);
void i2cInit(int);

View file

@ -0,0 +1,5 @@
#define SPIDEV_1 (0)
void spiPinConfigure(int);
int spiPinConfig(int);
void spiInit(int);

View file

@ -0,0 +1,5 @@
#include <mock_enums.h>
#include "target/common_pre.h"
#include "target.h"
#include "target/common_post.h"
#include "target/common_defaults_post.h"