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 |