1 / 12

IN2305-II Embedded Programming

IN2305-II Embedded Programming. Lecture 4: Interrupts. Interrupts: Principle. dev 1. IRQ contr. CPU. IRQ #. dev N. HW CALL. ISR: PUSH R1 ... POP R1 RET. ... MOVE R1, (var-addr) MULT R1, 9 DIVIDE R1, 5 ADD R1, 32. X32 Interrupts. IRQ controller preprocesses multiple IRQ’s

oksana
Télécharger la présentation

IN2305-II Embedded Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. IN2305-IIEmbedded Programming Lecture 4: Interrupts

  2. Interrupts: Principle dev 1 IRQ contr CPU IRQ # dev N HW CALL ISR: PUSH R1 ... POP R1 RET ... MOVE R1, (var-addr) MULT R1, 9 DIVIDE R1, 5 ADD R1, 32 ...

  3. X32 Interrupts • IRQ controller preprocesses multiple IRQ’s • Each device: (IRQ #, priority) • Vectored IRQ • Interrupts NOT disabled • Automatic ISR preemption if prio IRQ > prio current ISR • Normal call saves context -> no interrupt keyword IRQ # IRQ contr CPU

  4. Example: ISR version of hello.c #define IRQ_BUTTONS = INTERRUPT_BUTTONS void isr_buttons(void) { X32_leds = X32_buttons; if (X32_buttons == 0x09) done = 1; } void main(void) { SET_INTERRUPT_VECTOR(IRQ_BUTTONS),&isr_buttons); SET_INTERRUPT_PRIORITY(IRQ_BUTTONS),10); ENABLE_INTERRUPT(IRQ_BUTTONS); ENABLE_INTERRUPT(INTERRUPT_GLOBAL); printf(“Hello World!\r\n”); while (! done) X32_disp = X32_clock; DISABLE_INTERRUPTS(INTERRUPT_GLOBAL); }

  5. X32: Demo Demo .. (x32_projects.tgz, buttons.c, console.c)

  6. Interrupts: Data Sharing Problem void isr_read_temps(void) { iTemp[0] = peripherals[..]; iTemp[1] = peripherals[..]; } void main(void) { ... while (TRUE) { tmp0 = iTemp[0]; tmp1 = iTemp[1]; if (tmp0 != tmp1) panic(); } } 73 74 NOT ATOMIC!

  7. Interrupts: Data Sharing Problem • single C expressions usually aren’t atomic either ..: void isr_read_temps(void) { iTemp[0] = peripherals[..]; iTemp[1] = peripherals[..]; } void main(void) { ... while (TRUE) { if (iTemp[0] != iTemp[1]) panic(); } } 73 74 NOT ATOMIC!

  8. Solutions (1) • disable interrupts that trigger those ISRs that share the data ... while (TRUE) { !! DISABLE INT tmp0 = iTemp[0]; tmp1 = iTemp[1]; !! ENABLE INT if (tmp0 != tmp1) panic(); } The critical section is now atomic • use semaphores to protect critical section (discussed in a later lecture)

  9. Solutions (2) • don’t disable interrupts but write ingenious code, e.g., involving alternating data buffers (Fig. 4.15) or even queues (Fig. 4.16) such that ISR and (main) code never access the same data • problem: code becomes error-prone and (too) hard to read • rule: keep it simple, just disable interrupts, as long as you adhere to: • keep the critical sections SHORT • keep the ISRs SHORT (to minimize latency, see later)

  10. X32: Demo Demo .. (x32_projects.tgz, critical.c)

  11. Interrupt Latency • Quick response to IRQ may be needed • Depends on previous rules: worst-case latency = t_disabled + t_higher prio ISRs + t_myISR DI EI ip ISR nw ISR main nw IRQ ip IRQ 250 100 300

  12. X32: Demo Demo .. (x32_projects.tgz: timing.c)

More Related