본문 바로가기

Firmware/RTOS

임베디드 OS 개발 프로젝트 A-1

임베디드 OS 개발 프로젝트 부록 A 정리

 

A.1.1 익섹션 벡터 테이블

exception vector table

 

ARM은 전원이 켜지면 리셋벡터테이블을 읽는다.

 

그 아래 벡터테이블은 정의된 상황이 발생하면 강제적으로 PC값이 정의된 오프셋 주소로 강제 변환하게 된다.

 

exception address에는 명령어 한개만(4Byte) 실행 할 수 있다.

 

따라서 exception address를 따라가면 exception을 처리하는 코드가 있는 것이 아닌 Branch 하는 명령어가 있다.

 

 Cortex-M 에서도 IRQ Interrupt가 발생하면 IRQ Vector -> IRQ Handler -> IRQ CallBack 형식으로 

 

코드를 처리하는 걸 알 수있다.

 

익셉션이 발생하면 진행 중인 프로그램 흐름이 깨지므로 다시 원래 위치로 복귀할 수 있도록 ARM은 복귀 주소를

 

따로 저장해 둔다( LR Register에 저장. Window에서는 BX Register)

 

익셉션이 발생 했을 떄 수행하는 동작은 다음과 같다.

 

1. ARM 모드일 떄는 익셉션 에 따라 PC+4 혹은 PC+8을 R14에 저장한다.

   만약 Thumb 모드면 PC+2 또는 PC+4를 R14에 저장한다.

 

2. CPSR을 익셉션별 동작 모드에 연결된 SPSR_X에 저장한다.

 

3. CPSR의 동작 모드 비트와 I,T비트의 값을 각 익셉션과 동작 모드에 맞게 변경한다.

 

4. SCTLR의 EE 비트 값에 따라 E 비트를 설정한다.

 

5. SCTLR의 TE 비트 값에 따라 T 비트를 설정한다.

 

6. PC의 값을 익셉션 벡터 위치로 강제 변경한다.

 

7. 익셉션 핸들러가 끝나기 전에 정해진 연산을 수행한 후에 PC에 값을 넣으면 흐름이 끊겼던 위치로 자연스럽게

연결 된다.

 

 

인터럽트

인터럽트는 필연적으로 인터럽트 지연을 발생 시킨다. 인터럽트 지연이란 하드웨어가 인터럽트를 갑지해서 ARM에 인터럽트 신호가 입력되는 순간부터 펌웨어 에서 인터럽트 핸들러가 수행되기 직전까지 걸리는 시간을 말한다.

거의 찰나에 가까운 매우 짧은 시간이 지만 임베디드 시스템의 목적에 따라서 이 시간이 문제가 되기도 한다.

그래서 별도 하드웨어로 인터럽트 지연을 최대로 줄이려는 여러가지 시도를 한다. (벡터 인터럽트 컨트롤러)

책에서는 다섯가지 개념에 대해 설명하고 있다.

 

 

* Interrupt Request(IRQ)

* Fast Interrupt Request(FIQ)

* Non-Maskable Fast Interrupt(NMFI)

* Low Interrupt Latency(LIL)

* Interrupt Controller(IC)

 

IRQ는 Interrupt Request의 약자이다. IRQ는 FIQ 보다 우선순위가 낮으므로 만약 IRQ와 FIQ가 동시에 발생하면 ARM에서는 FIQ에 대한 처리 요청을 펌웨어에 먼저 보낸다. CPSR의 I비트를 1로 설정하면 IRQ 익셉션을 비활성화한다.

 

FIQ는 Fast interrupt Request의 약자이다. 동작 특성은 IRQ와 동일하지만 FIQ가 IRQ 보다 빠른 이유는 FIQ 익셉션 동작 모드는 별도로 R8에서 R12까지의 레지스터를 별도로 가지고 있기 때문이다. 펌웨어에서 인터럽트 처리를 할 떄 R8에서 R12까지만 사용하도록 코드를 작성하면 레지스터를 백업하고 복구하는 시간을 사용하지 않아도 된다.

 

NMFI는 Non Maskable Fast Interrupt의 약자이다. NMFI가 켜져 있으며 FIQ를 비활성화 할 수 없게 된다. (CPSR의 F비트를 0으로 클리어한다. NMFI를 켰을 때 CPSR의 F 비트가 1이 되는 경우는 FIQ 익셉션이 발생했거나 리셋 익셉션이 발생했을 경우이다. 이 역시 펌웨어가 하는 것이 아니라 하드웨어가 자동으러 처리하는 것이다.

 

Low Interrupt Latency는 인터럽트 지연을 줄이기 위한 기능 중 하나로 ARM의 기본 설정 기능이다. SCTLR의 21번째 비트인 FI 비트로 동작 여부를 알 수 있으며 항상 1로 설정되어 있다. LIL은 인터럽트가 발생 했을 때 현재 수행 중인 명령의 실행이 아직 끝나지 않았다 하더라도 실행 중인 명령어를 취소해 버리고 인터럽트를 먼저 처리한다. 실행이 끝나지 않은 명령어는 인터럽트를 처리가 모두 끝난 다음에 원래 프로그램을 실행 할때 SUBS PC, R14, #4로 인터럽트가 발생했던 시점에서 한 명령어 뒤로 다시돌아가도록 해서 처리한다. 이 말은 인터럽트 처리를 위해서 같은 명령어를 두번 실행 한다는 뜻이지만 인터럽트의 지연을 줄이고 그 시간을 인터럽트 처리 후에 보상한다는 개념이다.

 

Interrupt Controller는 인터럽트 처리를 전담하는 일종의 주변장치이다. ARM에는 인터럽트를 감지하는 핀이 IRQ와 FIQ 두개이다. 따라서 인터럽트가 발생했다는 것말 알 수 있지 어떤 인터럽트가 어떤 하드웨어에서 발생 했는지를 알 수 없다. 그것을 알려면 인터럽트 컨트롤러에 물어봐야한다.

인터럽트 컨트롤러는 다음과 같은 기능을 한다.

 

* 인터럽트가 발생했을 때 해당 인터럽트의 종류를 레지스터에 기록한다.

* 인터럽트가 발생 했을 때 ARM의 IRQ 혹은 FIQ에 맞춰서 인터럽트 신호를 준다.

* 특정 인터럽트를 골라서 마스킹 할 수 있다. 마스킹(set 1) 된 인터럽트는 비활성화된다.(IC 종류에 따라서 마스킹이 활성화)

* 인터럽트간의 우선순위를 설정할 수 있다.

 

인터럽트 서비스 루틴은 인터럽트 핸들러의 하위 개념으로 인터럽트 핸들러에서 인터럽트의 종류를 판별한 다음 해당 인터럽만 전담으로 처리하는 코드로 이동한다.

 

                                                                                         -OS 개발 프로젝트 A.1.3 정리-