Skip to content

Allow configuring whether to care about the CTS line - #66

Open
meithecatte wants to merge 1 commit into
rust-osdev:mainfrom
meithecatte:push-txwvlvrktzpv
Open

Allow configuring whether to care about the CTS line#66
meithecatte wants to merge 1 commit into
rust-osdev:mainfrom
meithecatte:push-txwvlvrktzpv

Conversation

@meithecatte

Copy link
Copy Markdown

Resolves #65.

I have chosen to make "ignore CTS" the default, as that is the choice that is more likely to simply work for the user, as the aforementioned issue demonstrates.

Since the PR adds a new field to the Config struct, it would probably need to be a semver bump. Perhaps that's a good opportunity to mark the Config struct as #[non_exhaustive], but I'll leave that call up to you.

@phip1611

phip1611 commented Aug 7, 2026

Copy link
Copy Markdown
Member

thanks for bringing this up! I just returned from vacation and will take a look into that in the following days (hopefully)

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution:

Please:

  • change the commit title to: config: allow disabling CTS check
  • Add a why comment to the commit message body: Why is this necessary (Real hardware, which one) and why is this a good default
  • add a changelog entry like this **Breaking:** ready_to_send()` doesn't check `MSR::CTS` anymore by default because <insert concise reason>. For manual checks, users can check `if device.msr().contains(MSR::CTS) {}`. This field is configurable in the `Config`.

Comment thread src/config.rs Outdated
/// Whether parity bits should be used.
pub parity: Parity,
/// Whether to wait for CTS before sending.
pub observe_cts: bool,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename to check_cts_before_sending.

And please extend the rustdoc like this:

    /// Whether to wait for CTS before sending.
    ///
    /// Only activate this if.. keep it off if ...
    pub check_cts_before_sending: bool,

something concise yet helpful.

Comment thread src/lib.rs Outdated
// Software flow control. TODO, what to do with hardware flow control?
// Is this something we can and should support?
if !mcr.contains(MCR::LOOP_BACK) && !msr.contains(MSR::CTS) {
if self.config.observe_cts && !mcr.contains(MCR::LOOP_BACK) && !msr.contains(MSR::CTS) {

@phip1611 phip1611 Aug 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not correct or at least difficult to read. How about we slightly rewrite it to keep it readable:

if mcr.contains(MCR::LOOP_BACK) {
    return Ok(());
}
if self.config.check_cts_before_sending {
    let mcr = self.mcr();

    if !mcr.contains(MCR::LOOP_BACK) {
        let msr = self.msr();

        if !msr.contains(MSR::CTS) {
            return Err(ByteSendError::RemoteNotClearToSend);
        }
    }
}
Ok(());

WDYT? It is a little nested and ugly but I prefer it over smart collapsed statements.

ping @mkroening

Most modern hardware only hooks up the RX and TX lines, and doesn't
bother with the flow control pins. This means that, in practice, waiting
for CTS before sending data will prevent the UART from working, without
a clear indication of what's wrong.

This commit introduces an option for configuring whether the CTS line
should be checked before sending data. We default to not checking the
CTS line, believing that:
- it's a more useful default on modern hardware, with receive FIFO
  overruns being virtually unheard of despite the lack of a CTS pin;
- even when the CTS line is usefully exposed, ignoring its state leads
  to more useful behavior when the UART is not connected, for the usecase of
  emitting logs – logging into the void is better than hanging the
  system.
- when hardware flow control is necessary, the clear symptom of FIFO overruns
  should be much easier to track down than a silent hang.
@meithecatte

Copy link
Copy Markdown
Author

I've applied the changes you requested, although I instead renamed the Config field to flow_control – I think that's a better name than either of our first attempts at naming the option ;3

@phip1611

Copy link
Copy Markdown
Member

Lovely, thanks :)

Comment thread src/lib.rs
Comment on lines 680 to 681
// Software flow control. TODO, what to do with hardware flow control?
// Is this something we can and should support?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a stale comment?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that you mention it, possibly so? I previously assumed that "software flow control" meant "we're driving the flow control lines manually instead of configuring the UART to do it for us", but now that I've looked it up, it appears that software flow control usually refers to using the ASCII XON/XOFF characters for in-band signaling.

@phip1611 phip1611 Aug 14, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not 100 percent sure about software and hardware flow control. I tried my best by reading the spec and experimenting on real hardware. Any improvement to the (likely unnecessary?) comment is highly appreciated

We might also just remove that comment. WDYT @meithecatte?

@makubacki makubacki left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This resolved the issue I was having with v0.6.0.

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 this pull request may close these issues.

Allow bypassing CTS

3 participants