Understanding the uart_printf behaviour when printing a uint64_t variable. #965
-
I have been figuring out how to use the uart_printf function for a bit now to print uint64_t variables. I have a couple hypotheses on what behaviour is happening, but I would like them see confirmed. I have looked into the datasheet and user guide, but I don't see any specific description of this function yet. I believe this behaviour is thus undefined, especially since the code comments of this printf implementation only mention 32 bit values. Hypo 1) When you pass a 64 bit variable to the printf function through the %u placeholder, it only takes the 32 LSBs. However, the 32 MSBs do not get discarded IF!!! there is another placeholder %u further along in the string to be printed. I concluded this based on the behaviour that I wanted to print two uint64_t variables of which the value did not exceed the 32 LSBs. Instead of seeing the second variable printed by the second %u, it was always 0. This 0 seems to come from the 32 MSBs of the first variable which get passed to the second %u placeholder. Hypo 2) The best solution to solve the Hypo 1) problem is to cast the variables to uint32_t. Hypo 3) The behaviour described in Hypo 1) does NOT happen when there is only a singular %u placeholder in the printf function. Then the 32 MSBs which did not get printed yet get discarded. I concluded this by having two sequential printf statements in my code, both loaded with a uint64_t variable. In this case both the 32 LSBs of the variables were printed. The 32 MSBs of the first variable which were 0's, were not propegated to the next printf call. Is anything wrongly described? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
That's right - unfortunately. The only documentation here is the code itself. 🙈 The neorv32/sw/lib/source/neorv32_uart.c Lines 305 to 315 in 371b177
The compiler will put high and low parts of that variable on the stack, but
Right, you can pass high and low word individually and print them one by one (as hexadecimal only). uint64_t tmp = 0xABCD1234CAFE5678;
neorv32_uart0_printf("tmp = 0x%x%x\n", (uint32_t)(tmp>>32), (uint32_t)(tmp)); If you need the full printf features you can try to include Therefore, I highly recommend a more embedded-friendly port:
|
Beta Was this translation helpful? Give feedback.
That's right - unfortunately. The only documentation here is the code itself. 🙈
The
neorv32_uart_printf
function(s) only provides a minimal set of formatting options:neorv32/sw/lib/source/neorv32_uart.c
Lines 305 to 315 in 371b177