gauteh / defmt-serial

Log defmt messages over the serial port.
23 stars 6 forks source link

Logging produces only garbage (binary data) #16

Closed FransUrbo closed 3 weeks ago

FransUrbo commented 3 weeks ago

I'm using Embassy for my RPi/Pico project.

I initialize the UART and do a write with it (using blocking_write()). Works fine, I get the "Hello World" just fine. But then when I initialize defmt-serial, all subsequent defmt functions just outputs garbage on the serial port.

I'm not a very experienced Rust developer, but I'm a fairly decent C/Python/Perl/PHP/etc developer, so I'm not a complete noob :). Not entirely sure how defmt-serial actually works, I'm having trouble understanding the code, but it's almost like "something" is "garbaging" the buffer!

I've tried using UART0/PIN0, but same thing happens - but since the blocking_write() directly from the Embassy API works fine, I need to assume that that part at least works.. Which leads me to defmt-serial. However, I'm not experienced enough to find out what it is :(.

Any pointers would be most welcome..

Screenshot 2024-06-07 at 08 17 49
FransUrbo commented 3 weeks ago

Embassy do seem to have a blocking::serial::Write, although it uses embedded_hal_02 instead of embedded_hal.

I've been trying to understand #14, which seems to be about just that - newer HAL.. ? However, that PR isn't finished, it fails to compile..

gauteh commented 3 weeks ago

Hi. That looks correct: You have to decode the output with defmt-print: https://github.com/gauteh/defmt-serial?tab=readme-ov-file#parsing-logs , there are examples for how to set that up with cargo run or Makefiles (https://github.com/gauteh/sfy/blob/main/sfy-buoy/Makefile#L37) .

The PR isn't compiling because the HAL in one of the examples is on eh pre 1. I think I will just disable that example in CI.

FransUrbo commented 3 weeks ago

Oh!?? A note about that would be helpful :). That that's necessary I mean.

However, I did try that ((stty speed 115200 >/dev/null && cat) </dev/cu.usbmodem2102 | defmt-print -e target.elf), but didn't get anything. Turns out, that the stty doesn't work that way on MacOS - the port must be opened before you set the speed!

But now I tried again (cat < /dev/cu.usbmodem2102 | defmt-print -e target.elf), then set the speed in a different terminal (stty -f /dev/cu.usbmodem2102 speed 115200 -crtscts -mdmbuf) and now it works!!

If you could update the documentation about this, I'd appreciate it.

FransUrbo commented 3 weeks ago

One note though, is there a reason why defmt-print is necessary? Could this not just output it in text directly?

gauteh commented 3 weeks ago

That's the whole point of defmt :) It sends encoded minimal data and you decode it on the host. This is explained in defmt docs. Otherwise you would just use normal logging to serial.

FransUrbo commented 3 weeks ago

"normal logging to serial"? As in, using the example in example-std?

gauteh commented 3 weeks ago

If you don't want encoded data, don't use defmt. Just print to serial.

FransUrbo commented 3 weeks ago

Ah. Well, defmt is quite nice, it takes care of a lot of the legwork :).

Thanx for the clarification!

For posterity, anyone else have problem with this on MacOS, this is a one-liner that works for me:

export DEV=/dev/cu.usbmodem2102 ; (cat < "${DEV}" & stty -f "${DEV}" speed 115200 -crtscts -mdmbuf) | defmt-print -e target.elf

As in, on MacOS, the stty needs to come after the port have been opened! Otherwise, the OS will reset it to default (9600 baud etc).