Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTT implementation should probably not default to blocking mode #133

Closed
mvirkkunen opened this issue Aug 26, 2020 · 5 comments · Fixed by knurling-rs/probe-run#69
Closed

Comments

@mvirkkunen
Copy link

Judging by the code it looks like RTT output will block forever once the buffer is full if there's no debugger attached to empty it. This will cause applications to stop working after a while when nothing is there to empty the buffer which leads to the same problem as semihosting's "why doesn't my application work when not being debugged", except after a sneaky delay.

rtt-target supports changing the buffer mode on the fly via the debugger, so one option would be to implement that, default to a non-blocking mode, and when a debugger (such as the de facto probe-run) attaches, the debugger could change the mode on the fly to a blocking mode to ensure messages aren't lost. That leaves a race condition between application boot and debugger attach where messages can be lost, however using a breakpoint to synchronize with the debugger can be used to solve that.

@japaric
Copy link
Member

japaric commented Aug 26, 2020

I would like to make defmt-rtt default to non-blocking behavior but we should implement #64 so that tools like probe-run can try to recover from corrupted streams (just discard the corrupted log frame and try the next one).

That leaves a race condition between application boot and debugger attach

I think we can avoid that one. The initial value of RTT_BLOCK is stored in Flash so probe-run could patch that bit of program data (*) before flashing it onto the device. That way when you are loading a program with probe-run you'll get blocking behavior on boot but if you load with something else (like cargo-flash or openocd) you'll get the non-blocking (overwrite) behavior.

(*) the operation is a bit gnarly but since RTT_BLOCK has a known memory location and memory layout it should be possible

@mvirkkunen
Copy link
Author

Flashing the value permanently assumes that people reflash after using probe-run though. I think it's likely that many people will forget/not know that they should.

@andresv
Copy link

andresv commented Sep 3, 2020

I learned about it today the hard way.

How can I turn logging completely off for release build, but allow it for dev build?

@japaric
Copy link
Member

japaric commented Sep 21, 2020

I think to fix this we can:

  • default defmt-rtt to non-blocking
  • have probe-run set a hardware breakpoint after RAM init (on main? is that symbol stable?)
  • use probe-rs to change the RTT header (stored in RAM) from non-blocking to blocking
  • resume the program
  • the rest of probe-run logic can stay as it is I think (probe-rs-rtt instance should be created after the ^ operation)

defmt-rtt::write would need to be updated to check it's mode in the RTT header

@mvirkkunen
Copy link
Author

Sounds like a good solution to me. probe-rs-rtt has UpChannel::set_mode that's meant to be used for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants