As for UART vs. USART, if you are using only UART functions, no need to bring in USART.
IIRC, ST ARMs have two separate peripherals at the hardware level (UART and USART; they might require different APIs (although, glancing quickly at the STM32f1xx manual, they have identical register definitions, so perhaps it's just a pinmux difference?)
Quote
Leave that C++ rubbish for PC bloatcode programmers.
The thing is, there are some C++ features that would REALLY HELP this sort of code, and they're NOT ones that cause bloat. In particular:
1) Function Overloading
Function overloading allows multiple functions to be defined with the same name, as long as they have different parameters.
This means that instead of having a function "USART_init(struct uart_config_params *confg);", where uart_config_params contains all of the parameters needed to initialize the USART in any possible mode supported by the hardware (IRDA, LIN, RS485, synchronous, async, etc) and then having USART__init() have a giant case statement handling all those possible cases, a HAL library could define multiple smaller functions:
USART_init(struct async_usart_config_params *config)
USART_init(struct irda_usart_config_params *config)
USART_init(struct lin_usart_config_params *config)
USART_init(struct rs485_usart_config_params *config)
USART_init(struct sync_usart_config_params *config)
Each one of those wouldn't have to contain code that implemented the others, and they could still share common code. (Now, it turns out that the STM32 usart code isn't so bad, but the above example of lumped features is from Atmel's ASF, so it's still a real problem.) Runtime cost: zero.
2) Templates and Template Meta Programming
As I understand it, this is essentially the pre-processing language that C should have had years ago, rather than sticking to the "all the preprocessor does is text substitution" crock that is what we have. With a bit of effort, templates can give you the sort of "optimize away all these things because their values are constant an known at runtime" that would require a really ugly combination of C preprocessing and non-standard inlining features, without being ugly, or non-standard. Runtime cost: zero (less than zero, really, since it will generally replace run-time decisions with compile-time decisions.)
Now, the big danger (IMO) is that C++ programmers DO come from a desktop/server environment, and don't tend to be very aware of when they are or are not introducing extra overhead. You're likely to get "why wouldn't I use an STL container for my FIFO?" (because that implementation assumes and uses dynamic memory allocation!) and similar.