class: title, smokescreen, shelf, bottom, no-footer background-image: url(images/pcxt.jpg) # 181U Spring 2020 ### Software/Hardware Interface --- layout: true .footer[ - Geoffrey Brown, 2020 - 181U ] <style> h1 { border-bottom: 8px solid rgb(32,67,143); border-radius: 2px; width: 90%; } .smokescreen h1 { border-bottom: none; } .small.remark-slide-content.compact {font-size:1.2rem} .smaller.remark-slide-content.compact {font-size:1.1rem} .small-code.remark-slide-content.compact code {font-size:1.0rem} .very-small-code.remark-slide-content.compact code {font-size:0.9rem} .line-numbers{ /* Set "line-numbers-counter" to 0 */ counter-reset: line-numbers-counter; } .line-numbers .remark-code-line::before { /* Increment "line-numbers-counter" by 1 */ counter-increment: line-numbers-counter; content: counter(line-numbers-counter); text-align: right; width: 20px; border-right: 1px solid #aaa; display: inline-block; margin-right: 10px; padding: 0 5px; } </style> --- class: compact # Agenda * Memory Mapped I/O * Interrupts * DMA --- class: compact # Memory Mapped Input/Output (I/O) * Signals and Timing Diagrams * Functions and Latches * General Purpose I/O --- class: compact # Bus Model of Processor ![](images/2019-12-27-13-05-44.png# w-60pct fr) * CPU (central processing unit) communicates with memory and I/O devices over a bus. * Everything on the bus looks like memory to the CPU * A bus consists of a set of *shared* signal wires -- Address wires, Data wires, and Control wires. * Communication over bus is time dependent --- class: compact # Memory Operations At the machine instruction level, this interface is completely hidden. The Cortex-M (and most processors) has two basic memory access instructions. Load, which reads from "memory" with an address(pointer) ```asm ldr r1, [r2] @ r1 = *r2 ``` and Store, which writes to a memory address ```asm ldr r1, [r2] @ *r1 = r1 ``` --- class: compact # Cortex Address Map ![](images/2019-12-27-13-12-29.png# w-40pct fr) The Cortex-M architecture reserves ranges of memory for specific functions -- * peripherals (hardware devices), * data (SRAM), * and code. --- class: compact # Aside on Timing Diagrams ![](images/space.png# w-2-12th) ![](images/2019-12-27-13-14-08.png# w-70pct) * Timing diagrams provide a way to specify and reason about signals on a bus. * There are three electrical levels -- high, low, floating * There are two logical levels -- 1, 0 * We often describe groups of wires with hexadecimal or decoded values * Wires can be *driven* in both directions, but not at the same time --- class: compact # Timing Diagram Example -- Memory Access ![](images/space.png# w-2-12th) ![](images/2019-12-27-13-17-15.png# w-70pct) In this example there are three memory transactions * Read from address 0x04 -- returns 1 * Write 2 to address 0x04 * Read from address 0x04 -- returns 1 Notice that the Data lines are allowed to float between transactions. * On reads, the data lines are *driven* by the memory/device * On writes, the data lines are *driven* by the cpu --- class: compact # Hardware primitives -- finite functions ![](images/space.png# w-20pct) ![](images/2019-12-27-13-22-31.png# w-60pct) * In principle, we can build any function with finite input and outputs from boolean logic gates * In practice, inputs and output signals are restricted to the processor word size (or less) * In practice, only relatively simple operations are implemented in a single functions (e.g. add,and).. ) --- class: compact # Hardware primitives -- latch ![](images/space.png# w-20pct) ![](images/2019-12-27-13-25-29.png# w-60pct) A *latch* provides a state-holding element. * We can build them in any width. * The basic operating is "load" which copies the input to the output * When a load is not being performed, the output is preserved even if the input changes. --- class: compact # Hardware primitives -- buffer ![](images/space.png# w-20pct) ![](images/2019-12-27-13-27-45.png# w-60pct) * A buffer provides a way to have multiple *drivers* on a bus * The output of a buffer *floats* when it is not enabled * When the buffer is enabled, its input is copied to its output --- class: compact # Example: A single memory word ![](images/space.png# w-20pct) ![](images/2019-12-27-13-29-50.png# w-60pct) --- class: compact # Example: Digital I/O Port ![](images/space.png# w-3-12th) ![](images/2019-12-27-13-31-26.png# w-50pct) --- class: compact,hljs-tomorrow-night-eighties,line-numbers # C Model of I/O Port ```C typedef struct { volatile unsigned int in; volatile unsigned int out; volatile unsigned int dir; } port; ``` ```C extern port *p; p->dir = 3; // set bits (pins) 0 and 1 to outputs p->out = 1; // set pin 0 to 1 x = p->in; // read pins. ``` --- class: compact # Interrupts * Why Interrupts ? * Basic interrupt processing * Sources of interrupts * Interrupt handlers --- class: compact # Polling Suppose we are waiting for data from a communication device * Polling is the process of querying the device (through software) * Polling takes time away from other work * Polling makes it difficult to satisfy real-time constraints --- class: compact # Interrupts * **Interrupts** provide a general mechanism for hardware to signal the processor that attention is required * Rather than repeatedly asking devices if they need service (polling) let the devices signal the processor. --- class: compact # The big idea * For each type of event that potential needs service, associate a special procedure, called a **handler** that will be executed when the event occurs. * We call these events *interrupts* * In purely software implementations, **callbacks** serve the role of **handlers** -- this model is frequently used in GUIs * Interrupt **handlers** are called by the CPU * Before each "normal" instruction is executed, the CPU checks for pending events * If an event is pending, the CPU transfers control to the associated handler. --- class: compact # Interrupt Service ![](images/space.png# w-20pct) ![](images/2019-12-27-13-47-41.png# w-60pct) --- class: compact # Instruction Execution with Interrupt Handling ![](images/space.png# w-10pct) ![](images/2019-12-27-13-48-54.png# w-80pct) --- class: compact # Key Points for Programmers * If interrupts are **enabled**, they can occur at any point during program execution * Interrupts are **disabled** when the handler is called (at least from the same priority level) * Interrupt handlers are similar to normal procedures with a few caveats * They must save *everything*, not just the regular callee saved registers * They should not touch shared data except that specifically associated with the handler (e.g. an input queue) --- class: compact # The need to preserve registers (including status) ![](images/space.png# w-3-12th) ![](images/2019-12-27-13-53-37.png# w-50pct) --- class: compact # Revised Memory Layout ![](images/space.png# w-3-12th) ![](images/2019-12-27-13-55-02.png# w-50pct) --- class: compact # Sources of Interrupts * External device **interrupts** * timer * Serial port * Button * **Processor Exceptions** * Memory access violation * Divide by zero * **Software Interrupts** -- OS system calls --- class: compact,hljs-tomorrow-night-eighties,line-numbers # Direct Memory Access (DMA) * Example * What DMA does * STM32 DMA Architecture ```C for (i = 0; i < N; i++) { while(flagBusy); buf[i] = peripheralRegister; } ``` --- class: compact # Performance Without DMA ![](images/2019-12-27-14-02-17.png) --- class: compact # Performance with DMA ![](images/2019-12-27-14-03-29.png) --- class: compact # How DMA works ![](images/space.png# w-10pct) ![](images/2019-12-27-14-09-08.png# w-80pct) --- class: compact # STM32 DMA Architecture ![](images/space.png# w-10pct) ![](images/2019-12-27-14-06-46.png# w-80pct) --- class: compact # Summary * Memory Mapped I/O * Interrupts * Direct Memory Acces * Cover (pxct): By <a href="https://de.wikipedia.org/wiki/User:Putput" class="extiw" title="de:User:Putput">Putput</a>, <a href="http://creativecommons.org/licenses/by-sa/3.0/" title="Creative Commons Attribution-Share Alike 3.0">CC BY-SA 3.0</a>, <a href="https://commons.wikimedia.org/w/index.php?curid=25662571">Link</a>