diff --git a/src/main/build/build_config.h b/src/main/build/build_config.h index 517d51ed2c..c5bd1f8742 100644 --- a/src/main/build/build_config.h +++ b/src/main/build/build_config.h @@ -20,8 +20,6 @@ #pragma once -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) - #ifdef UNIT_TEST // make these visible to unit test #define STATIC_UNIT_TESTED @@ -35,8 +33,6 @@ #define UNIT_TESTED #endif -//#define SOFT_I2C // enable to test software i2c - #ifndef __CC_ARM #define REQUIRE_CC_ARM_PRINTF_SUPPORT #define REQUIRE_PRINTF_LONG_SUPPORT diff --git a/src/main/common/utils.h b/src/main/common/utils.h index 9bbf67d42a..076b4680f2 100644 --- a/src/main/common/utils.h +++ b/src/main/common/utils.h @@ -57,9 +57,8 @@ #if !defined(UNUSED) #define UNUSED(x) (void)(x) #endif -#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) -#define STATIC_ASSERT(condition, name) \ - typedef char assert_failed_ ## name [(condition) ? 1 : -1 ] __attribute__((unused)) + +#define STATIC_ASSERT(condition, name) _Static_assert((condition), #name) #define BIT(x) (1 << (x)) diff --git a/src/main/config/config_eeprom.c b/src/main/config/config_eeprom.c index 2b8c571737..7c51f2fbcf 100644 --- a/src/main/config/config_eeprom.c +++ b/src/main/config/config_eeprom.c @@ -86,12 +86,12 @@ typedef struct { void initEEPROM(void) { // Verify that this architecture packs as expected. - BUILD_BUG_ON(offsetof(packingTest_t, byte) != 0); - BUILD_BUG_ON(offsetof(packingTest_t, word) != 1); - BUILD_BUG_ON(sizeof(packingTest_t) != 5); + STATIC_ASSERT(offsetof(packingTest_t, byte) == 0, byte_packing_test_failed); + STATIC_ASSERT(offsetof(packingTest_t, word) == 1, word_packing_test_failed); + STATIC_ASSERT(sizeof(packingTest_t) == 5, overall_packing_test_failed); - BUILD_BUG_ON(sizeof(configFooter_t) != 2); - BUILD_BUG_ON(sizeof(configRecord_t) != 6); + STATIC_ASSERT(sizeof(configFooter_t) == 2, footer_size_failed); + STATIC_ASSERT(sizeof(configRecord_t) == 6, record_size_failed); } bool isEEPROMVersionValid(void) diff --git a/src/main/drivers/stm32f7xx_ll_ex.h b/src/main/drivers/stm32f7xx_ll_ex.h index d1e7ecd4e0..12895e5cf2 100644 --- a/src/main/drivers/stm32f7xx_ll_ex.h +++ b/src/main/drivers/stm32f7xx_ll_ex.h @@ -37,12 +37,12 @@ __STATIC_INLINE DMA_TypeDef *LL_EX_DMA_Stream_to_DMA(DMA_Stream_TypeDef *DMAx_St __STATIC_INLINE uint32_t LL_EX_DMA_Stream_to_Stream(DMA_Stream_TypeDef *DMAx_Streamy) { + STATIC_ASSERT(DMA1_Stream0_BASE - DMA1_BASE == sizeof(DMA_TypeDef), DMA_TypeDef_has_padding); + STATIC_ASSERT(DMA1_Stream1_BASE - DMA1_Stream0_BASE == sizeof(DMA_Stream_TypeDef), DMA_Stream_TypeDef_has_padding); + const size_t firstStreamOffset = sizeof(DMA_TypeDef); const size_t streamSize = sizeof(DMA_Stream_TypeDef); - STATIC_ASSERT(DMA1_Stream0_BASE - DMA1_BASE == firstStreamOffset, DMA_TypeDef_has_padding); - STATIC_ASSERT(DMA1_Stream1_BASE - DMA1_Stream0_BASE == streamSize, DMA_Stream_TypeDef_has_padding); - return (((uint32_t) DMAx_Streamy & DMA_STREAM_MASK) - firstStreamOffset) / streamSize; } diff --git a/src/main/flight/pid.c b/src/main/flight/pid.c index b5505e3678..b9b4da5777 100644 --- a/src/main/flight/pid.c +++ b/src/main/flight/pid.c @@ -236,7 +236,7 @@ static FAST_RAM_ZERO_INIT pt1Filter_t antiGravityThrottleLpf; void pidInitFilters(const pidProfile_t *pidProfile) { - BUILD_BUG_ON(FD_YAW != 2); // ensure yaw axis is 2 + STATIC_ASSERT(FD_YAW == 2, FD_YAW_incorrect); // ensure yaw axis is 2 if (targetPidLooptime == 0) { // no looptime set, so set all the filters to null diff --git a/src/main/interface/msp.c b/src/main/interface/msp.c index 92ee499981..5631e55c37 100644 --- a/src/main/interface/msp.c +++ b/src/main/interface/msp.c @@ -35,9 +35,10 @@ #include "common/axis.h" #include "common/bitarray.h" #include "common/color.h" +#include "common/huffman.h" #include "common/maths.h" #include "common/streambuf.h" -#include "common/huffman.h" +#include "common/utils.h" #include "config/config_eeprom.h" #include "config/feature.h" @@ -338,7 +339,7 @@ enum compressionType_e { static void serializeDataflashReadReply(sbuf_t *dst, uint32_t address, const uint16_t size, bool useLegacyFormat, bool allowCompression) { - BUILD_BUG_ON(MSP_PORT_DATAFLASH_INFO_SIZE < 16); + STATIC_ASSERT(MSP_PORT_DATAFLASH_INFO_SIZE >= 16, MSP_PORT_DATAFLASH_INFO_SIZE_invalid); uint16_t readLen = size; const int bytesRemainingInBuf = sbufBytesRemaining(dst) - MSP_PORT_DATAFLASH_INFO_SIZE; @@ -596,25 +597,27 @@ static bool mspCommonProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProce } case MSP_VOLTAGE_METER_CONFIG: - // by using a sensor type and a sub-frame length it's possible to configure any type of voltage meter, - // e.g. an i2c/spi/can sensor or any sensor not built directly into the FC such as ESC/RX/SPort/SBus that has - // different configuration requirements. - BUILD_BUG_ON(VOLTAGE_SENSOR_ADC_VBAT != 0); // VOLTAGE_SENSOR_ADC_VBAT should be the first index, - sbufWriteU8(dst, MAX_VOLTAGE_SENSOR_ADC); // voltage meters in payload - for (int i = VOLTAGE_SENSOR_ADC_VBAT; i < MAX_VOLTAGE_SENSOR_ADC; i++) { - const uint8_t adcSensorSubframeLength = 1 + 1 + 1 + 1 + 1; // length of id, type, vbatscale, vbatresdivval, vbatresdivmultipler, in bytes - sbufWriteU8(dst, adcSensorSubframeLength); // ADC sensor sub-frame length + { + // by using a sensor type and a sub-frame length it's possible to configure any type of voltage meter, + // e.g. an i2c/spi/can sensor or any sensor not built directly into the FC such as ESC/RX/SPort/SBus that has + // different configuration requirements. + STATIC_ASSERT(VOLTAGE_SENSOR_ADC_VBAT == 0, VOLTAGE_SENSOR_ADC_VBAT_incorrect); // VOLTAGE_SENSOR_ADC_VBAT should be the first index + sbufWriteU8(dst, MAX_VOLTAGE_SENSOR_ADC); // voltage meters in payload + for (int i = VOLTAGE_SENSOR_ADC_VBAT; i < MAX_VOLTAGE_SENSOR_ADC; i++) { + const uint8_t adcSensorSubframeLength = 1 + 1 + 1 + 1 + 1; // length of id, type, vbatscale, vbatresdivval, vbatresdivmultipler, in bytes + sbufWriteU8(dst, adcSensorSubframeLength); // ADC sensor sub-frame length - sbufWriteU8(dst, voltageMeterADCtoIDMap[i]); // id of the sensor - sbufWriteU8(dst, VOLTAGE_SENSOR_TYPE_ADC_RESISTOR_DIVIDER); // indicate the type of sensor that the next part of the payload is for + sbufWriteU8(dst, voltageMeterADCtoIDMap[i]); // id of the sensor + sbufWriteU8(dst, VOLTAGE_SENSOR_TYPE_ADC_RESISTOR_DIVIDER); // indicate the type of sensor that the next part of the payload is for - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatscale); - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivval); - sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivmultiplier); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatscale); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivval); + sbufWriteU8(dst, voltageSensorADCConfig(i)->vbatresdivmultiplier); + } + // if we had any other voltage sensors, this is where we would output any needed configuration } - // if we had any other voltage sensors, this is where we would output any needed configuration - break; + break; case MSP_CURRENT_METER_CONFIG: { // the ADC and VIRTUAL sensors have the same configuration requirements, however this API reflects // that this situation may change and allows us to support configuration of any current sensor with diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c index 94830f77ea..f122ecc5ad 100644 --- a/src/main/interface/settings.c +++ b/src/main/interface/settings.c @@ -1150,5 +1150,5 @@ const clivalue_t valueTable[] = { const uint16_t valueTableEntryCount = ARRAYLEN(valueTable); void settingsBuildCheck() { - BUILD_BUG_ON(LOOKUP_TABLE_COUNT != ARRAYLEN(lookupTables)); + STATIC_ASSERT(LOOKUP_TABLE_COUNT == ARRAYLEN(lookupTables), LOOKUP_TABLE_COUNT_incorrect); } diff --git a/src/main/io/ledstrip.c b/src/main/io/ledstrip.c index 6b62a5c4bf..d668c04407 100644 --- a/src/main/io/ledstrip.c +++ b/src/main/io/ledstrip.c @@ -165,7 +165,7 @@ void pgResetFn_ledStripConfig(ledStripConfig_t *ledStripConfig) memset(ledStripConfig->ledConfigs, 0, LED_MAX_STRIP_LENGTH * sizeof(ledConfig_t)); // copy hsv colors as default memset(ledStripConfig->colors, 0, ARRAYLEN(hsv) * sizeof(hsvColor_t)); - BUILD_BUG_ON(LED_CONFIGURABLE_COLOR_COUNT < ARRAYLEN(hsv)); + STATIC_ASSERT(LED_CONFIGURABLE_COLOR_COUNT >= ARRAYLEN(hsv), LED_CONFIGURABLE_COLOR_COUNT_invalid); for (unsigned colorIndex = 0; colorIndex < ARRAYLEN(hsv); colorIndex++) { ledStripConfig->colors[colorIndex] = hsv[colorIndex]; } diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 42de3f40bf..dffeec60d7 100644 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -1119,7 +1119,7 @@ void osdInit(displayPort_t *osdDisplayPortToUse) return; } - BUILD_BUG_ON(OSD_POS_MAX != OSD_POS(31,31)); + STATIC_ASSERT(OSD_POS_MAX == OSD_POS(31,31), OSD_POS_MAX_incorrect); osdDisplayPort = osdDisplayPortToUse; #ifdef USE_CMS diff --git a/src/main/rx/rx_spi.c b/src/main/rx/rx_spi.c index c8cb39d40c..db1b27db52 100644 --- a/src/main/rx/rx_spi.c +++ b/src/main/rx/rx_spi.c @@ -63,7 +63,7 @@ static protocolSetRcDataFromPayloadFnPtr protocolSetRcDataFromPayload; STATIC_UNIT_TESTED uint16_t rxSpiReadRawRC(const rxRuntimeConfig_t *rxRuntimeConfig, uint8_t channel) { - BUILD_BUG_ON(NRF24L01_MAX_PAYLOAD_SIZE > RX_SPI_MAX_PAYLOAD_SIZE); + STATIC_ASSERT(NRF24L01_MAX_PAYLOAD_SIZE <= RX_SPI_MAX_PAYLOAD_SIZE, NRF24L01_MAX_PAYLOAD_SIZE_larger_than_RX_SPI_MAX_PAYLOAD_SIZE); if (channel >= rxRuntimeConfig->channelCount) { return 0; diff --git a/src/main/target/system_stm32f7xx.c b/src/main/target/system_stm32f7xx.c index 1354bec2e6..cd9c38a887 100644 --- a/src/main/target/system_stm32f7xx.c +++ b/src/main/target/system_stm32f7xx.c @@ -337,11 +337,11 @@ void SystemInit(void) extern uint8_t isr_vector_table_base; const uint32_t vtorOffset = (uint32_t) &isr_vector_table_base; #define VTOR_OFFSET_ALIGNMENT 0x200 -#define VTOR_OFFSET_MASK (VTOR_OFFSET_ALIGNMENT - 1) - STATIC_ASSERT((vtorOffset % VTOR_OFFSET_MASK) == 0, isr_vector_table_base_is_not_512_byte_aligned); + if (vtorOffset % VTOR_OFFSET_ALIGNMENT != 0) { + // ISR vector table base is not 512 byte aligned + while (1); + } SCB->VTOR = vtorOffset; -#undef VTOR_OFFSET_MASK -#undef VTOR_OFFSET_ALIGNMENT /* Enable I-Cache */ if (INSTRUCTION_CACHE_ENABLE) {