Yes there are many ways to skin a cat. My system still allows blocking printf calls to the uart for times when the scheduler is NOT running, such as printing out hard fault info, or during startup before the scheduler is first run. Its done simply by making a blocking call to Uart Tx via the HAL driver instead of the DMA/Irq call. I have also used your idea of a circular buffer to capture data for examination by the debugger. This is particularly good for diagnosing systems that capture transients at high speed, like sonar or radar.