CS452 F23 Lecture Notes
Lecture 10 - 17 Oct 2023

1. Real-Time Loops

  • suppose we want to perform an action with fixed period X ticks
    • e.g., poll track sensor
  • naive approach

      loop:
        action();
        Delay(tid, X);
      endloop;
    
  • but: action() takes time, time might vary
  • better:

      target = Time(tid);
      loop:
        action();
        target += X;
        DelayUntil(tid, target);
      endloop;
    

2. UART Interrupts

  • see BCM Ch 11
  • Each UART can be configured to generate multiple types of interrupts, for example
    • TX (transmit) - when there is sufficient room in the transmit FIFO
    • RX (receive) - where there is sufficient data in the receive FIFO
    • CTS - when the CTS flow control signal changes state
    • and more!
  • IMSC (Interrupt Mask Set Clear) register controls which interrupts are generated
    • one bit per interrupt: 1 enables interrupt, 0 disables it
  • GIC gets one UART interrupt signal (Interrupt ID = 153)
    • logical OR of all interrupt signals from all UARTS
  • How to enable UART interrupts:
    • set appropriate bit(s) in IMSC
    • enable Interrupt ID in the GIC, and set CPU target (like for timer interrupt)
  • How to handle UART interrupts:
    • read GICC_IAR to find the InterruptID
    • if it is a UART interrupt
      • read UART RIS or MIS register(s) to find out which UART interrupt(s)
    • clear interrupt using UART ICR (and eliminate cause of interrupt if necessary)
    • write to GICC_EOIR when finished, as for the timer interrupt

3. UART FIFOs

  • can be enabled or disabled (32 entries for Tx and 32 for Rx)
  • should enable Tx FIFO?
    • allows for small bursts of writes
    • but can’t control when queued writes are sent
      • mostly a problem for Marklin, not Console
        • Marklin needs to finish processing previous request before the next request can be sent
      • in theory hardware flow control should prevent sending too fast
        • in practice, Marklin might not de-assert CTS fast enough!
  • should enable Rx FIFO?
    • helps buffer bursts of incoming data
    • but can’t get an RX interrupt on non-empty RX FIFO
      • interrupt “trigger levels” are 1/8 full, 1/4 full, etc. (see UART IFLS register)
  • recommendation: disable FIFOs for UART3 (Marklin)
  • with FIFOs disabled:
    • UART Tx interrupt generated when output buffer is empty
      • but this only tells you that a command has been sent (not processed)
    • UART Rx interrutp generated when input buffer is full

4. Sending Train Commands

  • A0: send command, wait before sending the next command
    • how long to wait? Conservative estimate…
    • waiting ==> spinning
  • Now: take advantage of UART interrupts to avoid spinning
    • pattern:
      • send command
      • wait for CTS de-assert
      • wait for CTS re-assert
    • States: Ready -> CommandSent -> DeviceBusy -> Ready

5. UART Servers (K4)

  • API:
    • unsigned char Getc(int tid, int channel)
    • int Putc(int tid, int channel, unsigned char ch)
  • How many servers?
  • Exact semantics:
    • when does Putc return, does it block
    • does Getc block?
  • Use server/notifier pattern?
  • Need to define events for servers to AwaitEvent() on

Author: Ken Salem

Created: 2023-10-17 Tue 12:41