'pxa255 인터럽트 제어 레지스터'에 해당되는 글 1건

 

* 인터럽트 제어레지스터

 

pxa 계열 프로세서의 인터럽트 제어 방식 및 관련 레지스터는 거의 유사하다. pxa계열 프로세서의 인터럽트 컨트롤러는 내부 유닛에서 발생하는 각종 인터럽트 및 GPIO 핀을 통한 외부 장치로 부터의 인터럽트 요청(IRQ)을 모두 처리한다.

 

PXA 계열 프로세서에서의 인터럽트는 상위레벨과 하위레벨의 두 단계 구조를 가진다.

상위레벨은 인터럽트를 발생하는 장치들이며 하위레벨은 각 장치 내부의 개별적인 인터럽트 소스들이다. 이들 내부 인터럽트 소스의 구분은 각 장치 내부의 상태 레지스터를 읽으므로써 알 수 있다.

 

 

예를 들어 DMA 컨트롤러는 상위레벨 인터럽트 발생 장치인데, DMA 컨트롤러 내부에는 16개의 채널이 있고 이들 개별 채널이 각각 하위레벨 인터럽트 소스가 된다. 따라서 DMA 컨트롤러는 16개의 하위레벨 인터럽트 소스를 가진다. 또 UART는 상위레벨 인터럽트 발생 장치인데, UART 내부에서는 송신 인터럽트, 수신 인터럽트, 에러 인터럽트 등 여러개의 하위레벨 인터럽트 소스를 가지는 것이다.

 

인터럽트 기능을 제어하는 레지스터들은 다음과 같은 것들이 있다

 

Interrupt Controller Pending Register(ICPR)

 

Interrupt Controller IRQ Pending Register(ICIP)

 

Interrupt Controller FIQ Pending Register(ICFP)

 

Interrupt Controller Mask Register(ICMR)

 

Interrupt Controller Level Register(ICLR)

 

Interrupt Controller Control Register(ICCR)

 

 

위의 인터럽트 컨트롤러 레지스터 중 ICPR 레지스터는 인터럽트 발생 시 해당 비트가 "1"로 된다.

 

인터럽트 소스로 IS 8 ~ IS 31 까지가 정의되어 있고 해당 인터럽트 장치(소스)에서 인터럽트 발생 시 해당 비트가  "1"로 되며 커널에서는 이를 보고 해당 장치의 인터럽트 핸들러를 찾을 수 있게 된다. 해당 장치의 인터럽트 핸들러에서는 해당 인터럽트 장치의 내부 레지스터를 접근해서 실제 인터럽트를 발생한 하위레벨 인터럽트 소스를 찾은 다음 여기에 대한 처리를 한다.

 

인터럽트 소스 IS 11은 USB 장치이며 하위레벨 인터럽트를 7개 가지는 것을 알 수 있고, 인터럽트 소스 IS 10 PXA 프로세서의 GPIO 핀 2~80으로부터의 외부 인터럽트이며 각 핀마다 인터럽트를 가지므로 총 79개의 하위레벨 인터럽트를 가짐을 알 수 있다. GPIO 총 79개 핀 중 하나라도 인터럽트가 발생하면 인터럽트 소스 IS 10은 "1"로 되며, 인터럽트 소스 IS 10에 대한 인터럽트 핸들러에서 GPIO 어느 핀에서 인터럽트가 발생하였는지 검색하여 여기에 대한 인터럽트 처리를 하는 것이다.

 

ICLR 레지스터는 발생한 인터럽트가 일반 인터럽트인 IRQ인지 고속 인터럽트인 FIQ인지 나타낸다. 해당 비트가 '0'이면 IRQ이고 "1"이면 FIQ 이다....

 

 

* 인터럽트 처리 및 등록

 

처리 : IRQ 인터럽트가 발생하면 현 프로그램 카운터 값을 링크 레지스터에 저장하고 CPSR(Current Processor Status Register) 값을 SPSR_irq(Saved Processor Status Register)에 각각 저장한다.

 

그리고 IRQ의 exception 벡터 주소로 점프하여 인터럽트 처리가 시작된다. 인터럽트 처리 완료 후에는 링크 레지스터에 저장된 복귀 주소로 리턴되고 SPSR_irq 레지스터 내용도 다시 CPSR로 복구하여 인터럽트 이전 상태로 돌아간다.

 

등록 : 인터럽트를 사용하고자 하는 디바이스 드라이버는 인터럽트 서비스 루틴을 등록하고 이는 리눅스 커널의 전역변수 irq_desc에 등록된다. 인터럽트가 발생하면 커널은 ICPR 레지스터에서 "1"인 비트를 조사해 인터럽트를 발생한 장치 번호를 얻고, do_IRQ() 함수에서 전역변수 irq_desc를 조사해 해당 인터럽트 서비스 루틴을 찾는 방식으로 동작한다.

 

* GPIO 핀을 인터럽트 입력으로 설정하기

 

PXA 계열 프로세서의 GPIO 핀들은 외부장치로부터의 인터럽트 요청을 받는 입력신호로 사용할 수 있다. 이와 같이 설정하기 위해서 필요한 PXA 계열 프로세서의 GPIO 관련 레지스터들 및 그 기능은 다음과 같다.

 

인터럽트 입력으로 설정할 때

 

GPDR 레지스터 : 인터럽트 입력으로 사용할 핀의 동작 방향을 입력으로 설정한다.

 

GAFR 레지스터 : 인터럽트 입력으로 사용할 핀은  부가기능을 OFF 시켜야 하므로 이에 대응한 비트를 "00"으로 설정한다.

 

GRER 레지스터 : 인터럽트 입력으로 사용할 핀에서 신호가 상승 에지 시 인터럽트를 검출하고자 할 때 설정한다.

 

GFER 레지스터 : 인터럽트 입력으로 사용할 핀에서 신호가 하강 에지 시 인터럽트를 검출하고자 할 때 설정한다.

 

GEDR 레지스터 : 인터럽트 신호가 들어오면 해당 핀에 대응하는 비트가 "1"로 된다.

 

예를 들어 GPIO 40번 핀을 하강 에지로 설정하려면 위의 GFER1 레지스터의 비트 8을 "1"로 해주면 되고 GPIO 28핀을 상승 에지로 설정하려면 GRER레지스터의 28을 "1"로 해주면 된다. 이와 같은 기능을 대신해주는 함수로 set_GPIO_IRQ_edge()이 있다.

 

첫 번째 인수는 인터럽트 입력으로 설정하려는 GPIO 핀 번호이고 두 번째 인수는 플랙으로서 해당 핀을 상승에지로 설정하려면 GPIO_RISING_EDGE를 하강에지로 설정하려면 GPIO_FALLING_EDGE를 각각 넣으면 된다.

 

 

블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

댓글을 달아 주세요