ARM System Developer's Guide  

- Designing and Optimizaing System Software




#####

Exception Handling

Interrupts

Interrup Handiling Schemes





> Exception Handler

: 외부 시스템에 의해 발생되는 에러와 인터럽트, 이벤트들을 처리


- Exception Hanling 

- Interrupt

- Interrupt Handling Scheme 




### 9.1. Exception Handling


# Exception 

- 명령어들의 순차적인 실행 과정을 중단해야하는 상태

Exception 상태 : ARM 코어가 레셋되었을 경우, 명령어를 읽거나 메모리를 액세스 하려다 실패한 경우, 정의되지 않은 명령어를 만났을 경우,

소프트웨어 인터럽트가 발생한 경우, 외부 인터럽트가 발생한 경우 등

- Exception handling : 익셉션을 처리하는 방법

- Exception Handler : 익셉션이 발생한경우 실행되는 소프트웨어 루틴



## 9.1.1. ARM 프로세서 익셉션과 모드


> Exception이 발생하면 코어는

- exception mode의 spsr에 cpsr값을 저장

- exception mode의 lr에 pc값을 저장

- cpsr의 mode bit를 변경하여, 해당 exception mode로 진입

- pc에 exception handler의 주소를 저장하여 해당 주소로 분기



* ARM 프로세서는 ARM 상태로 변환




## 9.1.2. Vertor Table

: exception이 발생하였을 때 ARM 코어가 분기하는 주소 테이블을 의미. 하나의 분기 명령어를 포함


# 분기명령어 형식

 B <address> 

 pc를 기준으로 한 상대 주소로 분기

 LDR   pc,   [pc,   #offset]

 메모리에서 핸들어이 주소를 로드하여 pc에 저장. (벡터 테이블 근처에 저장되어있는 32비트 절대 주소값)

 - 추가적인 메모리 액세스로 약간의 지연시간이발생하지만, 메모리 안에 있는 어떤 주소로도 분기가 가능

 LDR   pc,   [pc,   #-0xff0] 

 0xfffff303에서 특정인터럽트서비스 루틴 줏를 읽어 pc에 저장

 - 벡터 인터럽트 컨트롤러(VIC PL190)이 있을 때에만 사용이 가능

 MOV  pc,  #constant 

 상수값을 pc에 저장. 주소값으로 32비트 주소 공간 내에 있는 모든 값을 사용하는 것이 아니라, 8비트 상수값을 짝수 배만큼 오른쪽으로 로테이트하여 표현할 수 있는 주소값만 사용이 가능 


# Vector Table에서 사용할 수 있는 다른 유형의 명령어

: FIQ Handler는 주소오프셋 +0x1c에서 시작

=> FIQ Handler는 벡터 테이블의 가장 끝에 위치하여 FIQ 벡터 위치에서 바로 시작이 가능



# 전형적인 벡터 테이블

- Undefined Instruction 엔트리 : undefined 핸들러로 분기하는 명령어

- 나머지 다른 벡터들 : LDR 명령을 이용하는 간접 주소 분기 방법을 사용



## 9.1.3. Exception Priorities

Exception Priorities mechanism이 필요한 이유 : Exception은 동시에 발생할 수 있기 때문

- 어떤 exceptions은 cpsr의 I 또는 F 비트를 1로 설정하여 해당 인터럽트가 발생하지 못하게 함


 Reset Exception

 - 가장높은 우선순위

 - reset 핸들러는 메모리와 캐시를 셋업하고 시스템을 초기화 

 - 핸들러가  초기화 되기 전 인터럽트 신호가 활성화되면 예기치 못한 인터럽트가 발생하므로 FIQ, IRQ 인터럽트를 enable하기 전에 외부 인터럽트 솟들을 모두 초기화 해야 함

 - 각 프로세서 모드에 대한 스택 포인터들도 셋업 

 - 핸들러의 처음 명령어 몇 개가 실행되는 동안에는 exception과 interrupt가 발생하지 않는다고 가정

 - exception 신호가 발생하지 않도록 주의하여 핸들러를 구현해야 함

 Data Abort Exception

 - 메모리 컨트롤러나 MMU가 유효하지 않은 메모리 주소가 액세스 되었다는 것을 가리킬 때

 - 현재 코드가 access permision이 없이 메모리 read/write를 시도할 때

 - FIQ exception이 disable되지 않아 FIQ exception이 발생할 수 있음

    -> FIQ exception을 먼저 처리 후 Data Abort 핸들러로 제어권을 다시 넘김

 FIQ Exception

 - 외부 주변 장치가 FIQ 핀을 nFIQ로 설정하였을 경우에 발생 

 - 우선순위가 가장 높음

 - 코어는 FIQ 핸들러로 진입하자마자 IRQ와 FIQ 익셉션을 비활성화 시킴

    -> 어떤 외부 자원들은 프로세서에게 인터럽트를 발생시킬수 없음. 단, 소프트웨어적인 IRQ, FIQ 발생은 가능

 IRQ Exception

 - 외부의 주변 장치가 IRQ 핀을 nIRQ로 설정했을 때 발생

 - 두번째로 높은 우선순위

 - FIQ나 Data Abort Exception이 발생하지 않은 경우 IRQ 핸들러로의 진입이 가능

 - IRQ 핸들러로 진입할 때, IRQ Exception은 disable이 되어, 현재 인터럽트 처리가 끝날 때까지 비활성화를 유지

 Prefetch Abort Exception

 - 메모리로부터 명령어를 읽어오려고 시도하다가 실패한 경우 발생

 - 명령어가 파이프라인의 execute단계에 있고, 우선순위가 높은 다른 exceptions이 발생하지 않았을 때 발생

 - prefetch 핸들러로 진입하면, IRQ Exception은 비활성화, FIQ Exception은 변화없이 유지

 - FIQ Exception이 활성화 되어 발생된다면 Prefetch Exception의 처리 도중이라도 먼저 처리

 SWI Exception

 - 명령어가 실행되고 다른 높은 우선순위의 Exception이 발생하지 않은 경우 발생

 - 이 핸들러로 진입할 때, cpsr은 supervisor 모드로 변경 

 - SWI 호출을 중첩해 사용한다면, lr인 r14와 spsr은 중첩된 SWI로 분기하기 전 반드시 저장 됨

    (lr와 spsr의 손상 가능성을 피하기 위함)

 Undefined Instruction Exception

 - ARM이나Thumb 명령어가 아닌 파이프라인의 실행 단계에 이르렀고, 그 외 우선순위가 높은 다른 Exception이 발생하지 않은 경우에 발생

 - ARM 프로세서는 코프로세서에게 코프로세서 명령어에 이것이 있는지를 물어봄

 - 코프로세서는 파이프라인을 따르기 때문에 명령어의 존재는 "execute" 단계에서 발생

 - 만약 코프로세서가 이 명령어를 이해하지 못하면, Undefined Istruction Exception이 발생


* SWI와 Undefined Instruction Exception은 같은 레벨의 우선순위를 가지며 실행되는 명령어가 SWI 명령어 이면서 Undefined 명령어일 수 없음



## 9.1.4. Link Register Offsets

Exception이 발생하면  lr은 현재 pc값을 기준으로 특정 주소값으로 설정

- IRQ Exception이 발생하면, lr은 마지막으로 실행된 명령어에 8을 더한값을 가리킴

- lr은 Exception Handler를 처리한 후에 복귀를 위해 사용되므로 복귀할 주소는 다음명령어, 즉  lr-4.



# IRQ나 FIQ Exception Handler로 부터 복귀할 수 있는 다양한 방법들


> Example 9.2 : IRQ와 FIQ에서 리턴되는 전형적인 방법인 SUBS 명령어의 사용


hanler

...

SUBS    pc,    r14,    #4    ; pc = r14 -4


: pc값이 결과 레지스터인 경우 cpsr값이 spsr 레지스터로부터 자동 복원

> Example 9.3 : 핸들러의 시작 위치에서 링크 레지스터 r14로부터의 offset만큼 빼는 방법


handler

SUB    r14,    r14,    #4    ; r14 -= 4

...

<핸들러코드>

...

MOVS    pc,    r14        ; return


: 핸들러 루틴 수행을 완료한 후, 원래 코드로 돌아가기 위해 lr인 r14값을 pc에 저장하고, spsr을 cpsr로 복원


> Example 9.4 : lr을 저장하기 위해 인터럽트 스택을 사용하는 방법. 맨 처음 lr로 부터 offset을 뺀 후, interrupt stack에 값을 저장


handler

SUB    r14,    r14,    #4                    ; r14 -= 4

STMFD     r13!,    {r0-r3,    r14}        ; register value 백업

...

<핸들러코드>

...

LDMF    r13,    {r0-r3,    pc}^        ; return


: 원래 코드로 되돌아가기 위해 LDM 명령어가 사용. 명령어 뒤의 ^이라는 심볼은 spsr값을 cpsr로 저장하라는 의미




'System > Embedded' 카테고리의 다른 글

[ARM] 펌웨어  (0) 2015.11.12
[ARM] 익셉션과 인터럽트 처리 2  (0) 2015.11.10
[ARM] 최적화된 C프로그래밍  (0) 2015.11.10
[ARM] 32비트 ARM 명령어 2  (0) 2015.11.09
[ARM] 32비트 ARM 명령어  (0) 2015.11.09

+ Recent posts