본문 바로가기
Linux BSP

[Linux Device Driver] Timer Interrupt

by TYB 2024. 2. 27.
반응형

리눅스와 같은 운영체제의 핵심 기능은 스케줄링인데, 이를 위해 핵심적인 것이 타이머 인터럽트이다.

리눅스 커널에서는 이를 위해 HZ라는 상수 값을 초기에 설정하고 잇따.

 

HZ라는 상수값을 통해 타이머 인터럽트가 발생하는 주기가 설정되면, 커널은 이 값으로 각 프로세스의 동작 시간을 체크하여 스케줄링 한다.

 

이때 프로세스의 동작시간을 체크 할 수 있는 기준값이 필요한데,

 

이때 리눅스 커널은 jiffies_64(커널 2.4에서는 jiffies)라는 전역변수를 통해 커널 전체에 동일한 기준 시간값을 제공한다.

 


jiffies 값이 1초당 100씩 증가한다. 고로, 10ms마다 jiffies 값이 증가하는거고,

 

그에 맞게 계산하여 1초마다 실행시키고 싶으면 jiffies가 100이 될 때마다 동작하게 설정하면 되는거임.

 

근데 이게 버전마다 사용법이 조금씩 차이가 있음.

 

커널 버전별 사용자가 직접 0.3초의 시간을 구하는 방법


짧은 지연 처리

하드웨어의 sync를 맞추기 위해 10ms 보다 짧은 찰나의 순간의 지연을 처리하고 싶다면 

 

mdelay(): 밀리초 단위의 지연

udelay(): 마이크로초 단위의 지연

ndelay(): 나노초 단위의 지연


긴 지연 처리

디바이스 드라이버에서 1밀리초 이상의 시간을 지연시키는 루틴을 사용하는 것은 피해야 하나, 정말 어쩔 수 없이 긴시간 동안 지연을 시켜야 한다? 라면 다음 방법을 사용 할 수는 있음.

커널 2.4의경우 
#define DELAY_TIME_MSEC (3* HZ/10) 
unsigned long endtime = jiffies + DELAY_TIME_MSEC ; 

 

while(jiffies < endtime) schedule( ) ; 
jiffies 를 이용하여 원하는 시간 뒤의 jiffies 값을 미리 계산하여 endtime 변수에 설정한 이후 무한 루프를 반복뼈 jiκies endtime 에 도달하기를 기다리는 방식이다. jiffies가 원하는 시간에 도달하지 않았다면 다른 프로세스가 동작하도록 schedule( ) 함수를 호출한다.

주의해야될건 정확한 지연시간을 보장하지 않는다는거

 

대략적으로 300 밀리초를 약간 초과한 시간 지연이 발생하고, 위와 같은 지연방식은 정확한 시간을 요구하는 인터럽트핸들러에서는 사용하면 안됨.

 

 

커널 2.6은 선점형 커널이다. 그러므로 커널2.4와 달리 다음과 같은 형식으로사용해도 된다. 
#define DELAY TIME MSEC (3*HZ /10) 
u64 endtime get jiffies 64( ) + DELAY TIME MSEC ; 
while(jiffies < endtime) ;

커널 2.4에서 이런 방식을 사용하면 시스템이 멈추는 듯한 효과가 생기지만, 커널 2.6 은 선 
점형 커널이므로 루프문 수행 중에 스케줄이 전환되므로 schedule( ) 함수를 호출할 필요가 
없음.


시스템 시간

리눅스에서 제공하는 시스템 시간과 관련된 구조체들이 있음.


시간을 설정하거나 시간을 얻기 위해 사용되는 구조체, tv_sec은 현재 시간을 초로 계산하여 처리하는데 사용되고, tv_usec은 tv_sec에서 짤리는 작은 값들을 처리하는데 사용




커널 2.6에서 사용되는 구조체로 do_settimeofday()함수에서 사용됨. tv_sec 똑같고, tv_nsec은 nano초까지 지원.

 

디바이스 드라이버에서  시스템의 시간을 설정할 때는 시스템 전체의 시간이 변화되기 때문에 주의해야 함.

 

응용 프로그램이 시간을 지연시키고 있거나 시간과 관련된 연산 처리를 하는 도중에 시스템 시간이 변경되면 잘못된 처리가 발생할 수 있기 때문

반응형