Skip to content

Commit

Permalink
pbio/util: Introduce PBIO_CONTAINER_OF macro
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
dlech committed Jun 1, 2019
1 parent 28e4fd2 commit 4a722a1
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
11 changes: 6 additions & 5 deletions lib/pbio/drv/debug/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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];
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/pbio/include/pbio/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_

0 comments on commit 4a722a1

Please sign in to comment.