24.01.07 최초 작성
24.01.09 예제 추가
struct timer_list {
struct hlist_node entry;
unsigned long expires;
void (*function)(struct timer_list *);
u32 flags;
}
///
entry : 타이머 리스트
expires : jiffies 단위의 만료 시간
function : 핸들러 함수
flags : 플래그
#include <linux/timer.h>
timer_setup(timer, callback, flags); //timer_list 초기화
extern void add_timer_on(struct timer_list *timer, int cpu);
//지정한 cpu에 타이머 가동
extern int del_timer(struct timer_list *timer);
//타이머 삭제
extern int mod_timer(struct timer_list *timer, unsinged long expires); //타이머의 expire 설정
extern int mod_timer_pending(struct timer_list *timer, unsinged long expires);
//타이머의 expire 추가
extern int timer_reduce(struct timer_list *timer, unsigned long expires);
//expire에 입력한 만큼 expire에 설정된 시간 차감
/buildroot
의 .confing
파일의 CONFIG_HZ=(정수)
로 원하는 값 설정4ms마다 타이머 인터럽트가 발생하는 기존 리눅스 타이머를 보완하기 위해 탄생한 타이머
nanosleep
, itimers
, posix-timers
는 설정에 따라 High resolution timer
활용
#include <linux/hrtimer>
짧은 지연의 경우 busy waiting
으로 처리 (mdelay(), udelay(), ndelay()
)
긴 지연은 schedule_timeout(), usleep_range(int, int), usleep()
으로 처리
전원이 인가되지 않은 경우에도 설정한 시간 유지 (외부 배터리로 동작)
/dev/rtc
에서 관리하며 xtime
이라는 변수에 값 저장
드라이버 등록 | 드라이버 해제 | 타이머 인터럽트 핸들러 |
---|---|---|
k_module_init() | k_module_exit() | test_timer_callback() |
k_module_init()
: 타이머와 타이머 인터럽트 핸들러 등록하고 500ms 이후 작동하도록 설정static int __init k_module_init(void)
{
int retval;
pr_info("k 커널 모듈 \n");
timer_setup(&test_timer, test_timer_callback, 0);
pr_info( "현재 jiffies 값: (%ld)\n", jiffies);
retval = mod_timer(&test_timer, jiffies + msecs_to_jiffies(500));
if (retval)
pr_info("타이머 설정 에러\n");
return 0;
}
test_timer_callback()
: 현재 jiffies값 출력static struct timer_list test_timer;
void test_timer_callback(struct timer_list *t)
{
pr_info("callback 함수: jiffies 값: (%ld).\n", jiffies);
}
k_module_exit()
: 실행되지 않은 타이머를 해제static void __exit k_module_exit(void)
{
int retval;
retval = del_timer(&test_timer);
if (retval)
pr_info("타이머 제거 실패...\n");
pr_info("바이!!n");
}
드라이버 등록 | 드라이버 해제 | 타이머 인터럽트 핸들러 |
---|---|---|
k_module_init() | k_module_exit() | test_timer_callback() |
k_module_init()
: 타이머 동작 간격을 설정, 타이머를 지정한 옵션으로 초기화하고 타이머 시작#define TIMEOUT_NSEC 1000000000L
#define TIMEOUT_SEC 4
static int __init k_module_init(void)
{
ktime_t ktime;
pr_info("k 커널 모듈 \n");
ktime = ktime_set(TIMEOUT_SEC, TIMEOUT_NSEC);
hrtimer_init(&k_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
k_hrtimer.function = &timer_callback;
hrtimer_start(&k_hrtimer, ktime, HRTIMER_MODE_REL);
return 0;
}
test_timer_callback()
: jiffies값을 출력하고 타이머 작동 시간을 초기화, 타이머 다시 동작시킴static struct hrtimer k_hrtimer;
enum hrtimer_restart timer_callback(struct hrtimer *timer)
{
pr_info("callback 함수: jiffies 값: (%ld).\n", jiffies);
hrtimer_forward_now(timer, ktime_set(TIMEOUT_SEC, TIMEOUT_NSEC));
return HRTIMER_RESTART;
}
k_module_exit()
: 지정한 타이머 종료static void __exit k_module_exit(void)
{
int retval;
retval = hrtimer_cancel(&k_hrtimer);
if (retval)
pr_info("타이머 제거 \n");
pr_info("바이!!n");
}