Look I get it. This SHOULD be simple.
Why is it not? That's the point of the thread and it's title.
Yes, much easier, you just need to do it differently.
Let's say you have a structure that needs to be edited. Structure with raw data: double precision numbers, + unsigned numbers, + small bit fields, in general, complete inconsistency. It doesn't matter what's inside, the main thing is that the first in the structure should be a unique symbol. The characters "0-9,A-F" are already taken, zero cannot be transmitted, "\n,\r" - there is no point in transmitting (short distance). There are a lot of characters left for the role of the starter, let's say "G".
You have a data sending event not in itself, but a very specific result of the program execution, when all the data in the structure becomes relevant and ready to be transferred. That's when it's ready, then you can call the function for forming a string from the structure into one of the buffers (there should be two). There, if the first buffer is already involved in the transfer, then you need to switch to the second one. When forming a string, you can discard the standard "0x" (short distance). After collecting the line, we check the operation of DMA, and if it is busy, then we wait, then everything is standard.
Now we need to receive the data.
DMA is configured for a ring buffer, and works to receive without stopping. The UART has a character match interrupt in which you just need to read the DMA position, and write (head) so that it is visible to your processing functions. The processing function itself is called either through a timer or non-stop. As soon as a number other than 0xFFFF appears, it must be read into a new variable, and then replaced with 0xFFFF.
Next, we rewrite the contents of the ring buffer into the temporary buffer in the waiting loop for a new value of the DMA counter (read directly from the register). Or use a delay (the size and transmission time are known). You can restore binary data on the fly, or you can when a sufficient amount has already accumulated, it doesn’t matter.
Data checksum verification and recognition of different structures - at your discretion. Once everything fits together, you can copy the buffer data into the link structure for further use.
What the Internet does not have is the functions to handle the transmission failure mode. For the physical layer, it seems to be as it is, but write something purely into the debug port.