![](/zbxe/layouts/mr_layouts_1st/images/default/blank.gif)
강좌 & 팁
NVIC와 인터럽트 제어
NVIC 개요
NVIC는 1에서 240개의 외부 인터럽트 입력을 지원합니다.
지원되는 인터럽트의 정확안 수는 칩 제조사들이 cortex-M3 칩을 개발할 때 칩 제조사들에 의해 결정 됩니다.
또 한 NVIC는 마그킹이 불가능한 인터럽트 입력도 지원합니다. NMI의 실제 기능 또한 칩 제조사에 의해 결정 됩니다.
어떤 경우에는 이 NVIC는 외부 소스에 의해 제어 될 수 없습니다.
NVIC는 메모리 위치 0xE000E000으로 접근 될 수 있습니다. 인터럽트 제어/상태 레지스터의 대부분은 특권 모드에 의해서만
접근 가능합니다. 단 소프트웨어 트리거 인터럽트 레지스터는 제외되는데 이것은 사용자 모드에서도 셋업될 수 있습니다.
인터럽트 제어/상태 레지스터는 워드, 하드워드, 바이트 전송으로 접근될 수 있습니다.
또한 다른 인터럽트-마스킹 레지스터 몇몇은 인터럽트에 포함되어 있을 수 있으며, 특별한 레지스터를 말하며 MRS 와 MSR
명령어에 의해 접근됩니다.
기본적인 인터럽트 설정
각각의 외부 인터럽트는 그와 관련된 몇 가지 레지스터들을 가지고 있습니다.
● 활성화 레지스터와 클리어 활성화 레지스터
● 셋 펜딩 레지스터와 클리어 펜딩 레지스터
● 우선순위 레벨
● 활성화 상태
● 익셉션 마스킹 레지스터(PRIMASK, FAULTMASK, BASEPRI)
● 벡터 테이블 오프셋 레지스터
● 소프트웨어 트리거 인터럽트 레지스터
● 우선순위 그룹
인터럽트 활성화 및 클리어 활성화
인터럽트 활성화 레지스터는 두 개의 주소를 통해 프로그래밍됩니다. 활성화 비트를 1로 설정하기 위해서는 SETENA 레지스터
주소에 값을 쓰면 됩니다. 그리고 활성화 비트를 0으로 클리어하기 위해서는 CLRENA 레지스터 주소에 값을 쓰면 됩니다.
이러한 방식으로 어떤 인터럽트를 활성화하거나 비활성화하면 다른 인터럽트 활성화 상태에는 영향을 주지 않습니다.
SETENA/CLRENA 레지스터들은 32비트 폭이며, 각 비트는 하나의 인터럽트 입력을 나타낸다.
Cortex-M3 프로세서 안에는 32개 이상의 외부 인터럽트들이 있을 수 있기 때문에 하나 이상의 SETENA 와 CLRENA
레지스터들이 있습니다
인터럽트 펜딩 및 클리어 펜딩
인터럽트가 발생하였으나 바로 실행될 수 없다면 그것은 펜딩될 것입니다. 인터럽트 펜딩 상태는 인터럽트 셋 펜딩 레지스터와 인터럽트 클리어 펜딩 레지스터를 통해 접근될 수 있습니다. 활성화 레지스터와 유사하게, 펜딩 상태 제어는 32개의 외부 인터럽트 입력이 있다면, 하나 이상의 레지스터들을 포함할 수 있습니다.
현재 펜딩된 익셉션을 취소하거나 SETPEND 레지스터를 통해 소프트웨어 인터럽트를 발생시키기 위해, 펜딩 상태 레지스터들을 변경할 수도 있습니다.
우선순위 레벨
각각의 인터럽트들은 관련된 우선순위-레벨 레지스터를 가지고 있는데, 이는 최대 8비트에서 최소 3비트까지의 폭을 갖습니다.
활성화 상태 각가의 외부 인터럽트는 활성화 상태 비트를 가지고 있습니다. 프로세서가 인터럽트 핸들러를 시작할 때 이 비트는
1로 설정되며, 인터럽트 리턴이 실행될 때 0으로 클리어됩니다.
하지만 인터럽트 서비스 루틴이 실행하는 동안 더 높은 우선순위의 인터럽트가 발생하여 선점할 수 있습니다. 이러한 과정 동안에는 프로세서가 또 다른 인터럽트 핸들러를 실행하고 있음에도 불구하고, 이전의 인터럽트는 여전히 활성화 상태로 정의되어 있습니다. 활성화 레지스터는 32비트이지만, 하프워드 또는 바이트 크기의 전송을 사용하여 접근될 수도 있습니다. 만약 32개 이상의 외부 인터럽트들이 있다면, 하나 이상의 활성화 레지스터가 있게 될 것입니다. 회붙 인터럽트들을 위한 활성화 상태 레지스터들은 읽기만 가능합니다.
PRIMASK와 FAULTMASK 특별한 레지스터
PRIMASK 레지스터는 NMI와 하드 결함을 제외한 모든 익셉션들을 비활성화하기 위해 사용됩니다.
이것은 결과적으로 현재의 우선순위 레벨을 0으로 바꿉니다. 이 레지스터는 MRS와 MSR 명령어를 사용하여 프로그래밍될 수
있습니다.
PRIMASK는 크리티컬한 태스크들을 위해 임시로 모든 인터럽트들을 비활성화하고자 사용됩니다. PRIMASK가 1로 설정되었을 때 결함이 발생하면, 하드 결함 핸들러가 실행될 것입니다.
FAULTMASK는 하드 결함 핸들러조차 발생하지 않도록 현재의 우선순위 레벨을 1로 변경한다는 것만 제외하면 PRIMASK와
거의 유사합니다. FAULTMASK가 1로 설정 되면, NMI만 실행될 수 있습니다.
FAULTMASK는 익셉션 핸들러에서 나오게 되면, 자동적으로 0으로 클리어됩니다. FAULTMASK와 PRIMASK 레지스터는
사용자 상태에서는 1로 설정될 수 없습니다.
BASEPRI 특별한 레지스터
어떤 경우에는 어떤 레벨보다 더 낮은 우선순위를 갖는 인터럽트들만을 비활성화하고 싶을 수도 있습니다. 이 경우에 BASEPRI
레지스터를 사용할 수 있습니다. 이것을 수행하기 위해서는 BASEPRI 레지스터에 필요로 하는 마스킹 우선순위 레벨을 갖는 모든 인터럽트들을 마스킹하기를 원한다면, 다음과 같이 BASEPRI에 그 값을 쓰면 됩니다.
BASEPRI 레지스턴느 BASEPRI_MAX 레지스터 이름을 사용하여 접근될 수도 있습니다. 그것은 실제로 동이한 레지스터이지만,
이 이름을 사용하면 조건부 쓰기 연산을 수행 할 수 있습니다.
레지스터로 BASEPRI_MAX를 사용할 때 그것은 더 높은 우선순위 레벨로만 변경될 수 있으며, 더 낮은 우선순위 레벨로는 변경될 수 없습니다. 더 낮은 마스킹 레벨로 변경하거나 그 마스킹을 비활성화 하기 위해서는 BASEPRI라는 레지스터 이름이 사용되어야만 한다. BASEPRI/BASEPRI_MAX 레지스터는 사용자 상태에서는 설정될 수 없다.
다른 우선순위-레벨 레지스터에서처럼, BASEPRI 레지스터의 형식은 구현된 우선순위 레지스터 너비의 수에 의해 영향을 받습니다.
소프트웨어 인터럽트
소프트웨어 인터럽트는 여러가지 방법으로 발생시킬 수 있습니다. 첫 번째 방법은 SETPEND 레지스터를 사용하는 것이고,
두 번째 방법은 소프트웨어 트리거 인터럽트 레지스터를 사용하는 것입니다.
시스템 익셉션들은 이 레지스터를 사용하여 펜딩될 수 없습니다. 디폴트로는, 사용자 프로그램은 NVIC에 값을 쓸 수 없습니다.
하지만 사용자 프로그램이 이 레지스터에 값을 쓸 수 있도록 해야 한다면, NVIC 설정 제어 레지스터의 비트 1을 1로 설정하여, NVIC의 STIR에 사용자 접근을 가능 하게 할 수 있습니다.