From 4a722a134d8dddc1253f8e04f88af842c2be6b8d Mon Sep 17 00:00:00 2001 From: David Lechner Date: Mon, 27 May 2019 17:45:10 -0500 Subject: [PATCH] pbio/util: Introduce PBIO_CONTAINER_OF macro This macro lets us get the container of a nested structure. Make use of it in the debug UART driver so we don't have to be so careful about the offset of the handle field. --- lib/pbio/drv/debug/uart.c | 11 ++++++----- lib/pbio/include/pbio/util.h | 8 ++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/pbio/drv/debug/uart.c b/lib/pbio/drv/debug/uart.c index 939dbc7d7..7a6c1943a 100644 --- a/lib/pbio/drv/debug/uart.c +++ b/lib/pbio/drv/debug/uart.c @@ -10,6 +10,7 @@ #include "pbio/event.h" #include "pbio/port.h" #include "pbio/uartdev.h" +#include "pbio/util.h" #include "pbsys/sys.h" #include "sys/process.h" @@ -20,7 +21,7 @@ #define RX_BUF_SIZE 64 // must be power of 2! typedef struct { - UART_HandleTypeDef handle; // must be first in struct! + UART_HandleTypeDef handle; const uint8_t irq; uint8_t tx_buf[TX_BUF_SIZE]; uint8_t rx_buf[RX_BUF_SIZE]; @@ -50,7 +51,7 @@ PROCESS(pbdrv_uart_process, "UART"); // overrides weak function in stm32f4xx_hal_uart.c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { - pbdrv_uart_t *uart = (void *)huart; + pbdrv_uart_t *uart = PBIO_CONTAINER_OF(huart, pbdrv_uart_t, handle); uint8_t new_head; new_head = (uart->rx_buf_head + 1) & (RX_BUF_SIZE - 1); @@ -100,7 +101,7 @@ pbio_error_t pbdrv_uart_get_char(pbio_port_t port, uint8_t *c) { // overrides weak function in stm32f4xx_hal_uart.c void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { - pbdrv_uart_t *uart = (void *)huart; + pbdrv_uart_t *uart = PBIO_CONTAINER_OF(huart, pbdrv_uart_t, handle); if (uart->tx_buf_tail != uart->tx_buf_head) { // there is still more data to send @@ -160,7 +161,7 @@ pbio_error_t pbdrv_uart_set_baud_rate(pbio_port_t port, uint32_t baud) { // overrides weak function in stm32f4xx_hal_uart.c void HAL_UART_MspInit(UART_HandleTypeDef *huart) { - pbdrv_uart_t *uart = (void *)huart; + pbdrv_uart_t *uart = PBIO_CONTAINER_OF(huart, pbdrv_uart_t, handle); // clocks are enabled in sys.c // pin mux is handled in ioport.c @@ -171,7 +172,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef *huart) { // overrides weak function in stm32f4xx_hal_uart.c void HAL_UART_MspDeInit(UART_HandleTypeDef *huart) { - pbdrv_uart_t *uart = (void *)huart; + pbdrv_uart_t *uart = PBIO_CONTAINER_OF(huart, pbdrv_uart_t, handle); HAL_NVIC_DisableIRQ(uart->irq); } diff --git a/lib/pbio/include/pbio/util.h b/lib/pbio/include/pbio/util.h index 5a9ebc6f1..48ba8c3d6 100644 --- a/lib/pbio/include/pbio/util.h +++ b/lib/pbio/include/pbio/util.h @@ -10,4 +10,12 @@ */ #define PBIO_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +/** + * Get a pointer to the structure that contains another structure. + * @param ptr Pointer to the child structure + * @param type The type of the parent structure + * @param member The name of the field containing ptr + */ +#define PBIO_CONTAINER_OF(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) + #endif // _PBIO_UTIL_H_