cancel
Showing results for 
Search instead for 
Did you mean: 

How to write code that is port flexible? I have a project I want to do that the UARTs used may change by end-user config setting. So it may have communication on one or many UARTs (almost like a matrix scheme). How do I abstract the UART(s)?

Grant Bt
Senior
 
3 REPLIES 3
Grant Bt
Senior

I realize this isn't STM32 specific, but that's what I am using. I would like to learn from examples where ports and data are changeable at run-time. I know I need to use a pointer, but I'm not sure how to proceed. So a chunk of code at one boot might write data out UART1, then after user config and next boot, UART2 or both or whatever.

Edit: Preferably there would only be one set of UART functions for initialization, read, write, etc. These would use the appropriate data and hardware depending on the configuration.

The things are instances/objects to start with. The normal approach is to pass around a pointer rather than use a global.

UART_HandleTypeDef Uart[1] = {0};

void InitUart(UART_HandleTypeDef *UartInstance, USART_TypeDef *Uart, uint32_t BaudRate)

{

 UartInstance->Instance       = Uart;

 UartInstance->Init.BaudRate  = BaudRate;

 UartInstance->Init.WordLength = UART_WORDLENGTH_8B;

 UartInstance->Init.StopBits  = UART_STOPBITS_1;

 UartInstance->Init.Parity    = UART_PARITY_NONE;

 UartInstance->Init.HwFlowCtl = UART_HWCONTROL_NONE;

 UartInstance->Init.Mode      = UART_MODE_TX_RX;

 UartInstance->Init.OverSampling  = UART_OVERSAMPLING_16;

#ifdef UART_ONE_BIT_SAMPLE_DISABLE

 UartInstance->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

#endif

 if (HAL_UART_Init(UartInstance) != HAL_OK)

 {

   /* Initialization Error */

   Error_Handler();

 }

}

void OutString(UART_HandleTypeDef *UartInstance , char *s)

{

 HAL_UART_Transmit(UartInstance, (uint8_t *)s, strlen(s), 5000);

}

InitUart(Uart, USART2, 115200);

OutString(Uart,"Hello World!\n");

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Grant Bt
Senior

Thanks, Yes, this is what I was concerned about. If a process has data it can't just enqueue it Enqueue(theData), it has to pass around the instance as you say, Enqueue(theInterface, theData), so it still needs to specify which Uart. Hmmm. I also have some interfaces that are bit-bang port things, so I want to make it as clean as possible for the higher layers. Like for example, a byte might be going out a UART or USB CDC VCOM or even something else. I don't want to have to have to use switch statements all over the place where it decides at run-time which interface to receive the data.