STM32 HAL driver for register value update
While it would be tempting to think that if you are going to use the HAL libraries, you should maintain that abstraction and not pierce it, in fact it is often necessary to bypass them.

If you look at the source of stm32f4xx_hal_tim.c (for example in mbed's github, since ST prefers zip files) you will see that the only functions which set the CCRx registers directly (vs via DMA) are the kitchen-sink calls of the TIM_OCx_SetConfig() family.  As these are about 60 lines each and pull and manipulate values from a struct, they're a horribly inefficient way to so something ordinary like update the output of a PID control loop over and over.

Instead, either reading through the code or by reading the relevant Programmers Manual, you can learn that after getting the peripheral setup (with the aid of the HAL or by hand), what you likely want to do is directly write to the register, for example here is relevant line buried in one of those kitchen-sink functions:

/* Set the Capture Compare Register value */  
TIMx-&gt;CCR3 = OC_Config-&gt;Pulse;


Given the HAL just does not offer a practical way to update this register frequently, basically your only choices are to:

1) Modify the HAL to add a function that does the above, possibly trying to set it up to be inlined, this can work but you then get to maintain a private fork of the vendor hal, though in a large enough project you may be doing that for bugfix or code format reasons anyway.

2) Write your own meta-HAL that adds this while wrapping the vendor one

3) Just put the relevant register right in the code, either directly, or via an application-oriented abstraction like:

board.h

#define RIGHT_FRONT_PWM TIM3-&gt;CCR2


pilot.c

RIGHT_FRONT_PWM = pid_out[1];


... or you can throw the whole thing out in favor of a 3rd party HAL or write an original HAL that meets your preferences and needs.