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
orMIS
register(s) to find out which UART interrupt(s)
- read UART
- clear interrupt using UART
ICR
(and eliminate cause of interrupt if necessary) - write to
GICC_EOIR
when finished, as for the timer interrupt
- read
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!
- mostly a problem for Marklin, not Console
- 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)
- interrupt “trigger levels” are 1/8 full, 1/4 full, etc. (see UART
- 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
- UART Tx interrupt generated when output buffer is empty
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
- pattern:
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