From 488dcdb19b6c56891fdba19f18ba51a92e14a714 Mon Sep 17 00:00:00 2001 From: Devan Lai Date: Sat, 29 Apr 2017 13:27:02 -0700 Subject: [PATCH] Add static asserts to validate circular buffer sizes Circular buffers using unmasked indices have size restrictions: * The size must be an exact power of two * The size cannot be greater than half of the max value represented by the index type Buffers used to process data from USB out endpoints must also be big enough to hold at least one maximum size packet to prevent the flow control logic from NAK'ing all packets. --- src/CAN/can.c | 6 ++++++ src/USB/cdc.c | 3 +++ src/USB/vcdc.c | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/src/CAN/can.c b/src/CAN/can.c index 67ac00c..7332cf3 100644 --- a/src/CAN/can.c +++ b/src/CAN/can.c @@ -28,6 +28,12 @@ #if CAN_RX_AVAILABLE +#define IS_POW_OF_TWO(X) (((X) & ((X)-1)) == 0) +_Static_assert(IS_POW_OF_TWO(CAN_RX_BUFFER_SIZE), + "Unmasked circular buffer size must be a power of two"); +_Static_assert(CAN_RX_BUFFER_SIZE <= UINT8_MAX/2, + "Buffer size too big for unmasked circular buffer"); + static volatile CAN_Message can_rx_buffer[CAN_RX_BUFFER_SIZE]; static volatile uint8_t can_rx_head = 0; static volatile uint8_t can_rx_tail = 0; diff --git a/src/USB/cdc.c b/src/USB/cdc.c index 3bfa9b3..b5a7335 100644 --- a/src/USB/cdc.c +++ b/src/USB/cdc.c @@ -30,6 +30,9 @@ #if CDC_AVAILABLE +_Static_assert((CONSOLE_TX_BUFFER_SIZE >= USB_CDC_MAX_PACKET_SIZE), + "TX buffer too small"); + /* Descriptors */ const struct cdc_acm_functional_descriptors cdc_acm_functional_descriptors = { .header = { diff --git a/src/USB/vcdc.c b/src/USB/vcdc.c index fa5a319..d31f8e4 100644 --- a/src/USB/vcdc.c +++ b/src/USB/vcdc.c @@ -65,6 +65,19 @@ static uint16_t vcdc_tx_tail = 0; static uint16_t vcdc_rx_head = 0; static uint16_t vcdc_rx_tail = 0; +_Static_assert((VCDC_RX_BUFFER_SIZE >= USB_VCDC_MAX_PACKET_SIZE), + "RX buffer too small"); + +#define IS_POW_OF_TWO(X) (((X) & ((X)-1)) == 0) +_Static_assert(IS_POW_OF_TWO(VCDC_RX_BUFFER_SIZE), + "Unmasked circular buffer size must be a power of two"); +_Static_assert(IS_POW_OF_TWO(VCDC_TX_BUFFER_SIZE), + "Unmasked circular buffer size must be a power of two"); +_Static_assert(VCDC_TX_BUFFER_SIZE <= UINT16_MAX/2, + "Buffer size too big for unmasked circular buffer"); +_Static_assert(VCDC_RX_BUFFER_SIZE <= UINT16_MAX/2, + "Buffer size too big for unmasked circular buffer"); + static bool vcdc_tx_buffer_empty(void) { return vcdc_tx_head == vcdc_tx_tail; }