2017-02-08 15 views
3

보호 모드에서 을 사용하여 에서 컴파일하는 하드웨어 인터럽트 처리기를 설정하려고합니다. 가능한 가장 작은 코드는 다음과 같습니다 (타이머 인터럽트).보호 된 하드웨어 인터럽트 처리기가 멈췄습니까? (DJGPP)

#include <dpmi.h> 
#include <go32.h> 
#include <stdio.h> 

unsigned int counter = 0; 

void handler(void) { 
    ++counter; 
} 
void endHandler(void) {} 

int main(void) { 
    _go32_dpmi_seginfo oldInfo, newInfo; 

    _go32_dpmi_lock_data(&counter, sizeof(counter)); 
    _go32_dpmi_lock_code(handler, endHandler - handler); 

    _go32_dpmi_get_protected_mode_interrupt_vector(8, &oldInfo); 

    newInfo.pm_offset = (int) handler; 
    newInfo.pm_selector = _go32_my_cs(); 
    _go32_dpmi_allocate_iret_wrapper(&newInfo); 

    _go32_dpmi_set_protected_mode_interrupt_vector(8, &newInfo); 

    while (counter < 3) { 
     printf("%u\n", counter); 
    } 

    _go32_dpmi_set_protected_mode_interrupt_vector(8, &oldInfo); 
    _go32_dpmi_free_iret_wrapper(&newInfo); 

    return 0; 
} 

나는 핸들러를 연결하지 않고 교체하는 중입니다. 카운터는 1 이상으로 증가하지 않으므로 (메인 루프를 멈추지 않음) 처리기가 올바르게 반환되지 않거나 한 번만 호출된다고 생각하게 만듭니다. 다른 한편으로 연결하면 잘 작동합니다 (래퍼 선을 제거하고 set_protected_modechain_protected_mode으로 바꿉니다). 라인이 누락 되었습니까?

+2

'카운터'는 '휘발성'으로 표시해야합니다. –

+0

또한'_go32_dpmi_lock_code'와'... data' 호출에서 불필요한 캐스트를 제거하십시오. 그들은'void * '(어떤 타입의 포인터도 받아 들일 것임)와'size_t' (이것은'sizeof'의 결과입니다)를 취합니다. –

+1

또한,'handler '의 크기를 계산하기위한'endHandler'의 사용은 의심 스럽습니다. 'endHandler'가 당신이 예상하는 것처럼'handler' 바로 다음에 오는 것을 보장하는 것은 아무것도 없습니다. GCC에서 더 나은 해결책은 커스텀 섹션에'handler'를 넣고 링커 스크립트 변수를 사용하여 크기를 얻는 것입니다. DJGPP에 대해서는 잘 모르겠습니다. –

답변

0

이전 처리기가 인터럽트 컨트롤러에 인터럽트 발생을 중지하도록 알리기 때문에 문서에 링크 된 Jonathon Reinhart와 같은 예전 인터럽트 처리기를 체인화해야합니다. 또한 BIOS 시계를 계속 유지하는 추가 이점이 있으므로 프로그램을 실행할 때마다 몇 초 정도의 시간을 낭비하지 않습니다. 그렇지 않으면 인터럽트 처리기가 반환 할 때 CPU가 즉시 처리기를 다시 호출하고 프로그램이 무한 루프에 멈추게됩니다.

또한 handler 뒤에 GCC가 endHandler을 배치한다는 보장은 없습니다. 캐스트 포인터로부터 자동 변환하는 기능 유형에 없다로서, 여기에 필요한

_go32_dpmi_lock_code((void *) handler, 4096); 

참고 : 나는에있는 페이지 handler 시작하고 페이지에 걸쳐 경우 다음 페이지를 모두 잠금 단지 권 해드립니다 void 에의 포인터.

+0

감사! _that_ 중요한 이전 처리기에 대한 정보는 가지고있는 것이 좋습니다. 나는 더 자세히 보았고 [오래된 핸들러가 아마도 무엇을하는지 알아 냈다.] (http://webpages.charter.net/danrollins/techhelp/0105.HTM) 내 핸들러에'outportb (0x20, 0x20);'추가하는 것 같다. 그것을 옛날 것과 같이 일하게 만드십시오. 하지만 내가 언급 한 추가 혜택이 실제로있는 경우 연쇄 적으로 남겨 둘 것입니다. – tobywoby

+0

@tobywoby 예를 들어 호스트 운영 체제 시계를 대신 사용하여 BIOS 시계를 완전히 에뮬레이션하지 못할 수도있는 DOSBox에서 시간을 잃지 않을 수도 있습니다. 실제 PC에서는 BIOS의 타이머 인터럽트 처리기가 현재 시간을 추적하기 위해 BIOS에서 사용하는 카운터를 증가시키기 때문에 시간이 많이 걸립니다. –