ST20 에서의 인터럽트의 사용방법을 간단한 예제와 함께 설명하고 있다. 참고로 여기서는 7710 을 기준으로 설명한다. 5517 과 많이 다르지 않기 때문에 그대로 적용해도 문제는 없을 것이다.
7710 에서의 인터럽트
총 54 개의 인터럽트를 지원하고 있다. 각각의 목록은 7710 데이터시트의 111 페이지를 보면 각 인터럽트 번호가 나와 있다. 많은 인터럽트 중에 EXT_IRQ 를 사용할 것이다. 7710 에서는 5 개의 EXTERNAL INTERRUPT 를 제공한다.
이름 | SOURCE NUMBER | 설명 |
IRB_WAKEUP_INT | 64 | IR 을 이용한 리모콘 입력시 사용 |
EXT_IRQ_0 | 65 | PIO 2 인터럽트 사용(데이터 시트 37 페이지) |
EXT_IRQ_1 | 66 | PIO 3 인터럽트 사용(데이터 시트 37 페이지) |
EXT_IRQ_2 | 67 | 7710 회로도 2 페이지 |
EXT_IRQ_3 | 68 | 7710 회로도 2 페이지 |
7710 데이터 시트에는 각각의 SOURCE NUMBER 표와 다르게 나와 있다.(0 ~ 4)
하지만, 기존의 SOURCE NUMBER 와 중복되기 때문에 제대로 인터럽트를 체크할 수 없다.
Sti7710.h 파일을 보면 표와 같이 정의되어 있다. 실제로 잘 동작하였다.
몇가지 설명을 덧붙이자면, IRQ_0 과 IRQ_1 은 각각 PIO 2 와 PIO 3 의 Bit 2 를 사용한다. 두 가지 기능을 가지고 있다.
IRQ_2 와 IRQ_3 은 7710 하드웨어적으로 지원한다. 회로도를 보면 알 수 있다.
인터럽트 실험하기
실험 조건은 다음과 같다.
인터럽트는 특정 포트가 High 또는 Low 로 될 때, 발생한다. 실시간으로 일어나야 하기 때문에 변환하기 쉬운 스위치를 사용했다.
프로그램은 7710ref 를 사용했다. 소스코드는 다음과 같다.
ST_ErrorCode_t TestApplication(void) { ST_ErrorCode_t ST_ErrorCode; #ifndef VID_INJECT_FROM_MEMORY SERVICE_Mode_t SERVICE_Mode=MODE_DVB; int index = 0; #endif int transponder = 0, channel = 0; /* default indexes for packet injector */ InterruptTest(); // 바로 이것이다 #ifndef VID_INJECT_FROM_MEMORY /* live injection from tuner or PI */ ST_ErrorCode = TUNER_Setup( SERVICE_Mode );
다음은 InterruptTest() 이다.
void InterruptTest(void) { int interrupt_stack[500]; interrupt_init_controller((void*)INTERRUPT_CONTROLLER_BASE, 8,(void*)INTERRUPT_LEVEL_CONTROLLER_BASE, INTERRUPT_NUMBERS,INTERRUPT_INPUTS_OFFSET); // 여기서 Define 되어 있는 값들은 Sti7710.h 을 참고한다 interrupt_init(5,interrupt_stack, sizeof(interrupt_stack), interrupt_trigger_mode_high_level, ST7710_EXT_INT_IN3_INTERRUPT); interrupt_install(0, 5, (void(*)(void*))interrupt_fat, NULL); interrupt_enable(5); }
다음은 인터럽트 핸들러인 interrupt_fat() 이다. 인터럽트 발생시 실행된다.
void interrupt_fat(void) { printf("\n!!!NOW INTERRUPT!!\n"); }
소스코드를 모두 살펴봤다. 앞에서 호출하고 있는 각각의 인터럽트 관련 시스템 콜은 ST20_2.1.2 의 데이터 시트를 참고하기 바란다.
시스템 콜 분석
interrupt_init_controller
인터럽트를 사용하기전에 가장 먼저 호출하는 API.
처음에 한번만 선언해준다. 두 번 선언하면 그 즉시 프로그램이 뻗는 현상이 생김.
몇 번의 테스트 결과, 처음에 반드시 선언하지 않아도 제대로 동작했음. 위의 소스에서 8 로 지정한 것은 인터럽트의 레벨이다. 이 값은 0 ~ 15 까지 지정 할 수 있고, 값이 높을 수록 우선 순위가 높다.
※ 주의할 것은 interrupt_init_controller 를 호출하지 않으면 두 번째 인터럽트 발생 시 제대로 처리하지 못했다. 이 부분은 차후에 테스트가 좀 더 필요하다.
interrupt_init
ST20_2.1.2 데이터 시트를 보면 두 번째로 호출하는 API.
하지만 테스트 결과, interrupt_init_controller 를 호출하면 interrupt_init 를 호출하지 않아도 동작하였다.
위의 소스에서 5 로 지정한 것은 인터럽트 레벨이다. 'interrupt_trigger_mode_high_level' 은 High 일 때, 인터럽트를 발생시킨다는 의미다.
※ 주의할 것은 interrupt_init_controller 와 interrupt_init 를 모두 호출하지 않으면 인터럽트가 동작하지 않는다.
interrupt_install
3 번째로 호출되는 API.
이 API를 호출하지 않으면, 전혀 인터럽트가 동작하지 않는다. 가장 핵심적인 API 라고 볼 수 있다.
여기서는 인터럽트 발생시 호출되는 인터럽트 핸들러를 지정한다. 두 번째 인자인 5 는 interrupt_init 에서의 인자와 같다.
interrupt_enable & interrupt_disable
각각 인터럽트를 활성화 또는 비활성화 시키는 API.
프로그램이 수행하면서, 중간 중간에 각각 이 API 를 호출할 수 있다. 여기서 부터는 INTERRUPT NUMBER 를 가지고 호출한다.