Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • L lpc43xx-hal
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
  • Issues 2
    • Issues 2
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 7
    • Merge requests 7
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Embedded Rust
  • lpc43xx-hal
  • Issues
  • #2
Closed
Open
Issue created May 18, 2021 by Christian Häggström@christian.haggstromDeveloper

v0.9.1: Serial::write_queue locks serial port while busy-waiting

Serial::write_queue does:

                        // Start of new block, ensure TX FIFO empty
                        if n % 16 == 0 {
                            while !self.serial.lsr.read().thre().bit() {}
                        }

That prevents the a receive task from running, causing characters to be dropped.

In our code we have these two tasks, that due to priority ceiling can't run at the same time inside the critical region:

    #[task(resources = [to_xray_queue, xray_serial])]
    fn dump_to_xray(cx: dump_to_xray::Context) {
        let mut xray_serial = cx.resources.xray_serial;
        let mut to_xray_queue = cx.resources.to_xray_queue;

        xray_serial.lock(|s| to_xray_queue.lock(|q| s.write_queue(q)));
    }
    #[task(binds = USART0, priority = 5, resources = [from_xray_queue, xray_serial], spawn = [dump_from_xray])]
    fn usart0(cx: usart0::Context) {
        let mut xray_serial = Exclusive(cx.resources.xray_serial);
        let mut from_xray_queue = Exclusive(cx.resources.from_xray_queue);

        if let Some(int_id) = xray_serial.lock(|s| s.read_iir()) {
            match int_id {
                INTID_A::RDA => {
                    // Get data from serial port
                    if let Ok(c) = xray_serial.lock(|s| s.read()) {
                        let _ = from_xray_queue.lock(|q| q.enqueue(c));
                    }

                    // Signal dump over can
                    let _ = cx.spawn.dump_from_xray();
                }
                _ => (),
            }
        }
    }
Assignee
Assign to
Time tracking