ecs642u embedded systems interrupts in cyclic systems william marsh

Post on 13-Dec-2015

238 Views

Category:

Documents

7 Downloads

Preview:

Click to see full reader

TRANSCRIPT

ECS642U Embedded Systems

Interrupts in Cyclic SystemsWilliam Marsh

2ARM University ProgramCopyright © ARM Ltd 2013

Acknowledgement

• Some slides from ARM University Program lab-in-a-box

• Copyright acknowledged

Outline

• Recap: Cyclic systems and polling• SysTick – timer interrupt

– Timing cyclic systems• GPIO interrupts

– Configuration and use• Managing concurrency

– What can do wrong – concurrency– Signals

• Going deeper– How interrupts work … consequences– Priority and nested interrupts

The Problem

• How to organise code in a reactive system

• Aims– Reactive– Flexible – easy to extend

• Answer: cyclic systems

Essential concept. Cyclic systems are used both with polling and interrupts.

Alternative will be use of an RTOS.

Recap of Cyclic Systems

• A system design of reactive systems

• Polling … and its limitations• The way ahead

Example Problem (Lab 2)

• Red LED flashes, every 2 seconds• When button pressed, stop flashing for 5 sec

System

Unreactive System (It Works)

void oneCycle(void){ redOn(); // wait for 500ms Delay(500) ; redOff();

// wait for 500ms Delay(500) ;

// test the input if (isPressed()) { Delay(5000) ; }}

• Long period when button not tested

• … Cannot react to anything else either

Unreactive Systems

• Long period when button not tested

• … Cannot react to anything else either

Is Presse

d

Start

0.5 sec?

Light On

Light Off

0.5 sec?

No

Yes

5 sec?

Unreactive System

• Timing– Most of time waiting– Ignoring button most of time

Set lights

Delay

Poll

Time

5sec

Cyclic Execution

• Repeatedly– Test input– Calculate– Set outputs

• Repeat fast enough – Appears

continuous– ’Cycle time‘

Initialise

Write outputs

Read inputs

Calculate

WAIT

50ms

Cyclic Execution

• No waits inside tasks

• Multiple ‘tasks’– Test input– Calculate– Set outputs

• Tasks can interact with ‘global’ variables

Initialise

Write outputs

Read inputs

Calculate

Task 1

Task 2

WAIT

int main (void) { configureGPIOoutput() ; configureGPIOinput() ;

while (1) { task1PollInput() ;

task2ControlLight() ; Delay(CYCLEDELAY) ; }}

Example Project: Reactive Design

• Multiple tasks• No delays in tasks

// Task 1: poll the input - detect changes in the switch state.// isPressed and not closed new press; // ~isPressed and closed not closed

int closed = 0 ; // Track switch positionint pressed = 0 ; // Signal next task

void task1PollInput(void) { if (isPressed()) { if (~closed) { closed = 1 ;

pressed = 1 ; }

} else { // not pressed if (closed) { closed = 0 ; } }}

// Task 2 Toggle LED when count down complete// Detect if a button press event has occurredint ledOn = 0 ; // State – flashing on / offint counter = 0 ; // Times flashes

void task2ControlLight(void) { if (counter > 0) counter-- ; // Detect button press event and pause flashing if (pressed ) { pressed = 0 ; redOff() ; counter = PAUSECOUNT ; return ; } // Check counter and toggle LED if (counter==0) { if (ledOn) { redOff() ;

ledOn = 0 ; } else { redOn() ; ledOn = 1 ; } counter = FLASHCOUNT ; } }

Summary of Cyclic System Principles

• No waits inside tasks• Timing by count cycles• Tasks communicate using global variables• Tasks use state variable

• Each cycle– What state?– Do I need to change state?

Interrupt Principles

• What is an interrupt?• First example: SystTick• Using SysTick to time cyclic

systems

Question

• What happens when you press reset?• The program restarts but how?

• …. main program … other satrt points • … analogies: GUI, box with buttons• … vector

Interrupt Processing Sequence

• Interrupt trigger occurs– Processor does some hard-wired processing– Processor executes ISR

• Processor resumes other code

Main Code Interrupt routineHardwired CPU

response activitiesTime

How Many Interrupts?

• Interrupt is a physical signal (i.e. a pin)– Early MCU had e.g. 2 interrupts

• Cortex-M0+– Configure pins to be interrupts

• NVIC Nested Vector Interrupt Controller– A memory mapped– Interrupt number, priority and vector

• Port– Making pins into interrupts

Cortex-M0+ Core: NVIC

• NVIC– Vectors for

interrupts and exceptions

– Priority: possible to interrupt and interrupt

• Aims to make interrupt handling fast

Summary of Terms So Far

• Interrupt– Asynchronous event from h/w– Change program being executed

• Interrupt Service Routine / Handler– Code that is executed when an interrupt occurs– … before returning to earlier code

• Vector– Address of ISR– Table of vectors: one for each interrupt

SysTick

A simple timer interruptUse in cyclic systems

Overview

• Generates a periodic interrupt • Part of CPU core’s peripherals

• What can we do with a fixed period?

– Time intervals, by counting– Delay for a precise period

Timing Jitter

• Time for ‘Calculate’ varies

• … Cycle time varies

• E.g. waveform generation

• E.g. motor control

Initialise

Write outputs

Read inputs

Calculate

WAIT

Configure SysTick

// Configure SysTick to interrupt every millisecond void Init_SysTick(void) { uint32_t r = 0 ; r = SysTick_Config(SystemCoreClock / 1000) ;

// Check return code for errors if (r != 0) { // Error Handling while(1); }}

Using SysTick

// This function handles SysTick interrupt // Decrement the counter when greater than zerovoid SysTick_Handler(void) { if (SysTickCounter > 0x00) // check not already zero { SysTickCounter--; // decrement towards zero }} // Wait for the SysTick counter to expire then

reset it// Param: number of ticks to set countervoid WaitSysTickCounter(int ticks) { while (SysTickCounter > 0) ; SysTickCounter = ticks ;}

Timing with SysTick

• Fix period of cycle

• Period chosen– Latency

acceptable– Computation

possible

• Other counters– e.g. since button

pressed

Initialise

Write outputs

Read inputs

Calculate

Task 1

Task 2

Wait for SysTick Counter

Number of

SysTick

Periods

GPIO Interrupt: Configuration and Use

Interrupt on input: better than polling

Limitations of Polling

• Do not notice changes that occur for less than cycle time

• Cycle time unnecessarily fast

KL25Z GPIO Ports with Interrupts• Port A (PTA)

through Port E (PTE)

• Not all port bits are available (package-dependent)

• Ports A and D support interrupts

Port Module• Port Module (A – E)

– Port is 32 pins– Includes connection of external inputs to NVIC

• PCR - Pin control register (32 per port)– Each register corresponds to an input pin– Configure pin as interrupt

• ISFR - Interrupt status flag register (one per port)– Each bit corresponds to an input pin– Bit is set to 1 if an interrupt has been detected

Pin Control Register (PCR)

• Each pin has a PCR

• MUX for alternative use (GPIO is 1)• IRQC controls interrupts

IRQC Configuration0000 Interrupt Disabled…. DMA, reserved1000 Interrupt when logic

zero1001 Interrupt on rising

edge1010 Interrupt on falling

edge1011 Interrupt on either

edge1100 Interrupt when logic

one… reserved

NVIC Registers and State

• Enable interrupts– Two registers (set bits for interrupts)

• Pending interrupt– Requested but is not yet serviced

Bit C Code (CMSIS) Description

NVIC_ISER NVIC_EnableIRQ(IRQnum) Enable interrupt

NVIC_ICER NVIC_DisableIRQ(IRQnum) Disable interrupt

Bit C Code (CMSIS) Description

NVIC_ISPR NVIC_ClearPendingIRQ(IRQnum) Set pending

NVIC_ICPR NVIC_ClearPendingIRQ(IRQnum) Clear pending

(NVIC_ISPR) NVIC_GetPendingIRQ(IRQnum) Get pending

Switch Initializationvoid init_switch(void) { /* Enable clock for port D */ SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; /* Select GPIO and enable pull-up resistors and interrupts on falling edges for pin connected to switch */ PORTD->PCR[SW_POS] |= PORT_PCR_MUX(1) |

PORT_PCR_PS_MASK | PORT_PCR_PE_MASK | PORT_PCR_IRQC(0x0a); /* Set port D switch bit to inputs */ PTD->PDDR &= ~MASK(SW_POS); /* Enable Interrupts */ NVIC_SetPriority(PORTD_IRQn, 128); NVIC_ClearPendingIRQ(PORTD_IRQn); NVIC_EnableIRQ(PORTD_IRQn);}

ISR

void PORTD_IRQHandler(void) {

// clear pending interrupts NVIC_ClearPendingIRQ(PORTD_IRQn);

// check that the interrupt was for switch if ((PORTD->ISFR & MASK(SW_POS))) { buttonPress = 1 ; }

// clear interrupt status flags (all flags for PortD) PORTD->ISFR = 0xffffffff;}

Name creates the Vector

Show interrupt serviced

Check correct pin (c.f. port)

Cyclic Execution

with Interrupts

• Interrupts reduce latency

• … BUT concurrency issues

Initialise

Write outputs

Read inputs

Calculate

Interrupt Handler 1

Interrupt Handler 2

Concurrency

• What can go wrong when we use interrupts

• How to avoid it

Interleaving

• Model of concurrency– Interrupts– (Later: pre-emptive scheduling)

• Any non-atomic instruction can interleaved

• Note: task == thread == process

An Incorrect Program

• Wish to provide a sequence of numbers to different tasks so no number used more than once

• This program does not work. The two tasks could get the same number

int num = 0 ;

int getNext() { return num++ ; }

x1 = getNext();

seq

x2 = getNext();

seqTask 1 Task 2

Interleaving

• Each task successively reads and write to ‘num’

x1 = numnum = num + 1

x2 = numnum = num + 1

x1 = 0num = 0 + 1 = 1x2 = 1num = 1 + 1 = 2x1 = 2num = 2 + 1 = 3x2 = 3num = 3 + 1 = 4x1 = 4num = 4 + 1 = 5

OK

Task 1

2

1

2

1

Interleaving

• Each task successively reads and write to ‘num’

x1 = 0seq.num = 0 + 1 = 1x2 = 1seq.num = 1 + 1 = 2x1 = 2seq.num = 2 + 1 = 3x2 = 3seq.num = 3 + 1 = 4x1 = 4seq.num = 4 + 1 = 5

STILL OK

Task 1

1

1

2

1

x1 = numnum = num + 1

x2 = numnum = num + 1

Interleaving

• Each task successively reads and write to ‘num’

x1 = 0x2 = 0num = 0 + 1 = 1num = 0 + 1 = 1x1 = 1x2 = 1num = 1 + 1 = 2num = 1 + 1 = 2x1 = 2num = 2 + 1 = 3

NOT OK

x1 = numnum = num + 1

x2 = numnum = num + 1

Signal

• Yes / no • Interrupt handler

– Sets it• Main task

– Clear to acknowledge

• Machine instructions are atomic• Data type must be single word• What happens if two interrupts before

acknowledged?

Going Deeper

• How interrupts work• … consequences• Advanced features

Some Interrupt Sources (Partial)Vector Start

AddressVector # IRQ Source Description

0x0000_0004 1 ARM Core Initial program counter

0x0000_0008 2 ARM Core Non-maskable interrupt

0x0000_0040-4C 16-19 0-3 Direct Memory Access Controller

Transfer complete or error

0x0000_0058 22 6 Power Management Controller

Low voltage detection

0x0000_0060-64 24-25 8-9 I2C Modules Status and error

0x0000_0068-6C 26-27 10-11 SPI Modules Status and error

0x0000_0070-78 28-30 12-14 UART Modules Status and error

0x0000_00B8 46 30 Port Control Module Port A Pin Detect

0x0000_00BC 47 31 Port Control Module Port D Pin Detect

Up to 32 non-core vectors, 16 core vectorsFrom KL25 Sub-Family Reference Manual, Table 3-6

Exceptions not interrupts

CPU’s Hardwired Exception Processing

• Finish current instruction – Some exceptions

• Push context (registers) onto current stack (MSP or PSP)

• Load PC with address of interrupt handler– Where from?

• Start executing code of interrupt handler

• Usually 16 cycles from exception request to execution of first instruction in handler

NVIC Priority Registers: NVIC_IPR0-7

• Priority – deal with simultaneous interrupts– Two bits per interrupt source– Four interrupt sources per register– Set priority to 0 (highest priority), 64, 128 or 192 (lowest)

• Exceptions (core vectors) have higher priorities

– CMSIS: NVIC_SetPriority(IRQnum, priority)

Bits 31:30 29:24 23:22 21:16 15:14 13:8 7:6 5:0

IPR0 IRQ3 reserved IRQ2 reserved IRQ1 reserved IRQ0 reserved

IPR1 IRQ7 reserved IRQ6 reserved IRQ5 reserved IRQ4 reserved

IPR2 IRQ11 reserved IRQ10 reserved IRQ9 reserved IRQ8 reserved

IPR3 IRQ15 reserved IRQ14 reserved IRQ13 reserved IRQ12 reserved

IPR4 IRQ19 reserved IRQ18 reserved IRQ17 reserved IRQ16 reserved

IPR5 IRQ23 reserved IRQ22 reserved IRQ21 reserved IRQ20 reserved

IPR6 IRQ27 reserved IRQ26 reserved IRQ25 reserved IRQ24 reserved

IPR7 IRQ31 reserved IRQ30 reserved IRQ29 reserved IRQ28 reserved

PRIMASK: Exception Mask Register

• Bit 0: PM Flag– Set to 1 to prevent activation of all exceptions with

configurable priority– Clear to 0 to allow activation of all exception

• Use to prevent data race conditions with code needing atomicity

• CMSIS-CORE API– void __enable_irq() - clears PM flag– void __disable_irq() - sets PM flag

Summary

Summary of Interrupts

• Cortex-M0+ NVIC– 32 interrupts– 2 bits of priority – 4 priorities– Vector: address of code

• Two GPIO port interrupts: A & D• Initialisation

– Enable interrupt by number (NVIC)– Configure pin (PCR)

• Use– Read PORT Interrupt status register (my bit?)– (Read) / clear interrupt pending

top related