Interrupt
goal: Push switch를 이용하여 LED Toggle하기
Interrupt vs Polling 비교
[Interrupt]
- 하드웨어적으로 hardware의 변화를 감지하여 외부로부터의 입력을 CPU가 알아채는 방법
- CPU가 다른 일을 할 수 있는 상태
- 인터럽트 발생시 해당 task를 수행 후, 다시 하던 일로 돌아옴
- CPU가 다른 일을 할 수 있는 상태이지만, 다시 해당 task로 순서가 돌아오려면 시간차이가 발생 = Overhead
[Polling] - hardware의 변화를 지속적으로 읽어들여 변화를 알아채는 방법
- CPU가 다른 일을 하지 않고 계속 변화를 관찰하므로, 즉각적으로 상태를 알아낼 수 있다.
- 한 cycle을 돌아야 상태 변화를 check 할 수 있다.
Interrupt의 종류
- Internal Interrupt
- software 내부에서 발생
- 하드웨어 고장
- 실행할 수 없는 명령어
- 명령어 실행 오류: 나누기 0
- External Interrupt
- hardware에서 발생
- 타이머 인터럽트
- 입출력 인터럽트
Interrupt 처리 과정
- 인터럽트 요청
- 상태 저장
- 인터럽트 서비스 루틴으로 이동
- 복귀
Interrupt Enable flag
- 상태 레지스터에 있는 제어 플래그 중 하나
- 중앙처리장치가 인터럽트를 허용할지 제어
- STI(Set Interrupt Flag): IE = 1, 인터럽트 요청을 인식
- CLI(Clear Interrupt Flag): IE = 0, 인터럽트 요청을 인식하지 않음
Interrupt Service Routine(ISR)
인터럽트 요청을 해결하는 프로그램
인터럽트 처리 순서
- 프로그램 실행 중
- 인터럽트 요청
- 프로그램 실행과 비동기
- 인터럽트 단계
- 인터럽트 확인
- 콘텍스트 저장
- PC <- ISR 주소
- 인터럽트 서비스 루틴 실행
- 인터럽트 리턴
- 콘텍스트 복구
- 중단된 프로그램 다시 시작
인터럽트 단계 후 실행하는 프로그램
SP <- SP - [단어 크기] // PUSH PC, 콘텍스트 저장 Mem[SP] <- PC SP <- SP - [단어 크기] // PUSH SR PC <- ISR 시작 주소 // PC 갱신
마지막에 인터럽트 리턴 명령어(IRET) 실행
[인터럽트 리턴 명령어]SR <- Mem[SP] // POP SR, 콘텍스트 복구 SP <- SP + [단어 크기] PC <- Mem[SP] // POP PC SP <- SP + [단어 크기]
- 인터럽트 요청이 수신된 시점에 실행 중인 프로그램 부분과 관련이 없을 수 있다.
- 따라서, 인터럽트 서비스 루틴으 ㅣ실행을 시작하기 전에 루틴 실행 중에 예상치 못한 방식으로 변경될 수 있는 프로세서 레지스터의 상태 정보와 내용을 저장해야 한다.
- 저장된 정보는 중단된 프로그램의 실행이 재개되기 전에 복원되어야 한다.
- 이러한 방식으로 원래 프로그램은 시간 지연을 제외하고 중단으로 인해 어떠한 영향도 받지 않고 계속 실행될 수 있다.
Context Switching
- 인터럽트 발생시 실행하던 process의 context를 저장
- context switching 일 때, CPU overhead 발생
Interrupt Vector Table
- 인터럽트 발생시 처리해야 할 루틴의 주소 보관 테이블
ERU
예제
ERU_Interrupt.h
#ifndef ERU_INTERRUPT_H_
#define ERU_INTERRUPT_H_
/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "Ifx_Types.h"
#include "IfxSrc.h"
#include "IfxScuEru.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define RED_LED &MODULE_P10,1 /* LED which gets toggled in Interrupt Service Routine */
#define BLUE_LED &MODULE_P10,2 /* LED which gets toggled in While Routine */
#define SW1 &MODULE_P02, 0
#define SW2 &MODULE_P02, 1
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/*-------------------------------------------------Data Structures---------------------------------------------------*/
/*********************************************************************************************************************/
typedef struct
{
IfxScu_Req_In *reqPin; /* External request pin */
IfxScuEru_InputChannel inputChannel; /* Input channel EICRm depending on input pin */
IfxScuEru_InputNodePointer triggerSelect; /* Input node pointer */
IfxScuEru_OutputChannel outputChannel; /* Output channel */
volatile Ifx_SRC_SRCR *src; /* Service request register */
} ERUconfig;
/*********************************************************************************************************************/
/*--------------------------------------------Private Variables/Constants--------------------------------------------*/
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void init_gpio(void);
#endif /* ERU_INTERRUPT_H_ */
ERU_Interrupt.c
/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "ERU_Interrupt.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define ISR_PRIORITY_SCUERU_INT0 40 /* Define the SCU ERU interrupt priority */
#define REQ_IN &IfxScu_REQ14_P02_1_IN /* External request pin (defined @IfxScu_PinMap.c */
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
ERUconfig g_ERUconfig;
/*********************************************************************************************************************/
/*--------------------------------------------Private Variables/Constants--------------------------------------------*/
/*********************************************************************************************************************/
volatile Ifx_SRC_SRCR *src; /* Service request register */
/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* Interrupt definition */
IFX_INTERRUPT(SCUERU_Int0_Handler, 0, ISR_PRIORITY_SCUERU_INT0);
/* Interrupt Service Routine */
void SCUERU_Int0_Handler(void)
{
IfxPort_setPinState(RED_LED, IfxPort_State_toggled); /* Toggle LED */
}
void init_gpio(void)
{
/* Set GPIO 10.1 and 10.2 as Output */
IfxPort_setPinModeOutput(RED_LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
IfxPort_setPinModeOutput(BLUE_LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
/* Set GPIO 10.1 and 10.2 as Low (LED Off) */
IfxPort_setPinLow(RED_LED);
IfxPort_setPinLow(BLUE_LED);
/* Set GPIO 2.0 and 2.1 as Input */
IfxPort_setPinModeInput(SW1, IfxPort_InputMode_pullUp);
IfxPort_setPinModeInput(SW2, IfxPort_InputMode_pullUp);
/* initialize external request pin */
g_ERUconfig.reqPin = REQ_IN; /* Select external request pin */
IfxScuEru_initReqPin(g_ERUconfig.reqPin, IfxPort_InputMode_pullUp);
/* Select which edge should trigger the interrupt */
g_ERUconfig.inputChannel = (IfxScuEru_InputChannel) g_ERUconfig.reqPin->channelId;
IfxScuEru_enableFallingEdgeDetection(g_ERUconfig.inputChannel);
/* Enable generation of trigger events with the function */
/* Signal destination */
g_ERUconfig.outputChannel = IfxScuEru_OutputChannel_2; /* OGU channel 0 */
/* Event from input ETL0 triggers output OGU0 (signal TRx0) */
g_ERUconfig.triggerSelect = IfxScuEru_InputNodePointer_2;
IfxScuEru_enableTriggerPulse(g_ERUconfig.inputChannel);
/* Choose the output channel by selecting the Output Gating Unit (OGUz) and the trigger pulse output (TRxz) */
IfxScuEru_connectTrigger(g_ERUconfig.inputChannel, g_ERUconfig.triggerSelect);
/*Select the condition to generate an interrupt with the function */
IfxScuEru_setInterruptGatingPattern(g_ERUconfig.outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);
/* Configure and enable the service request */
g_ERUconfig.src = &MODULE_SRC.SCU.SCU.ERU[(int) g_ERUconfig.outputChannel % 4];
IfxSrc_init(g_ERUconfig.src, IfxSrc_Tos_cpu0, ISR_PRIORITY_SCUERU_INT0);
IfxSrc_enable(g_ERUconfig.src);
}
Cpu0_Main.c
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "IfxPort.h"
#include "ERU_Interrupt.h"
IfxCpu_syncEvent g_cpuSyncEvent = 0;
void core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them period ically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
init_gpio();
boolean swStateOld, swState = 0;
while(1)
{
/* I. SW1을 한번 누를 때마다 Blue LED가 Toggle 되도록 제어 (Polling) */
/* Polling for SW1 */
swState = IfxPort_getPinState(SW1); // SW1 on: push되면 Low
if((swState == 0) && (swStateOld == 1)){
IfxPort_togglePin(BLUE_LED);
}
swStateOld = swState;
/* II. SW2을 한번 누를 때마다 Red LED가 Toggle 되도록 제어 (Interrupt) */
}
}
IfxPort_togglePin()
은 port output을 toggle한다.
- port: Pointer to the port which should be accessed.
- pinIndex: Specifies the pin to be toggled.
IfxPort_getPinState()
은 port state를 return
- port: Pointer to the port which should be accessed.
- pinIndex: Specifies the pin for which the state should be returned.
- Return
- TRUE: pin = high
- FALSE: pin = low
'IVS > 마이크로프로세서' 카테고리의 다른 글
[마이크로프로세서] 마이크로프로세서를 활용한 임베디드 제어 시스템 이해 (0) | 2025.01.20 |
---|---|
마이크로프로세서의 전장시스템 활용 (0) | 2025.01.17 |