행복한 하루
Raspberry Pi – Linux Device Driver 만들어 보기-9 (고분해능 타이머- High Resolution Timer) 본문
Raspberry Pi – Linux Device Driver 만들어 보기-9 (고분해능 타이머- High Resolution Timer)
변화의 물결 2023. 1. 18. 13:53
안녕하세요.
지난번 Timer를 사용해서 LED제어해 보았는데, 이것보다 좀 더 짧은 주기를 사용가능한 타이머를 확인해보려고 합니다. 고분해능 타이머는 jiffies 단위로 작동하는 타이머와 달리 나노초 단위로 동작시킬 수 있습니다. 조금 상세한 내용은 하단 <참조 사이트 2번> 링크를 참조하면 hrtimer 프레임워크에 대한 내용을 볼 수 있습니다.
1. 사전 준비
- 이전내용과 동일하게 기존에 드라이버 뼈대에 내용을 붙이는 형식으로 합니다. 그래서 처음내용의 소스를 복사해서 이름을 바꾸고 Makefile 내용도 수정해 줍니다.
pi@raspberrypi:~/DriverStudy $ cp -r day1 day9_hrTimer
pi@raspberrypi:~/DriverStudy $ cd day9_hrTimer/
pi@raspberrypi:~/DriverStudy/day9_hrTimer $ mv day1_module.c day9_hrTimer.c
pi@raspberrypi:~/DriverStudy/day9_hrTimer $ vim Makefile
2. 소스 수정하기
- 고분해 타이머를 사용하기 위한 헤더 파일과 전역변수를 선언합니다.
#include <linux/hrtimer.h>
#include <linux/jiffies.h>
/* High Resulution Timer */
static struct hrtimer ssHrTimer;
u64 start_t;
- 타이머가 실행되었을 되고 시간이 끝났을 때 수행하는 콜백함수를 구현합니다.
- 시작할 때 jiffies 횟수와 콜백함수가 호출될 때 횟수를 가지고 확인합니다.
MODULE_DESCRIPTION("A Simple High Rsulution Timer.");
static enum hrtimer_restart hrTimer_handler(struct hrtimer *timer) {
/* Get current time */
u64 now_t = get_jiffies_64(); //jiffies;
printk("start_t – now_t = %u\n", jiffies_to_msecs(now_t - start_t));
return HRTIMER_NORESTART;
}
- 커널에 모듈이 추가(driver_init 함수)되면 타이머가 초기화되고 카운터를 시작합니다.
- hrtimer_start 함수 구조는 hrtimer 구조체 포인터 넣고, 만료시간, 모드를 인자로 받습니다. 그리고 콜백함수 포인터를 연결해 줍니다.
void hrtimer_start ( struct hrtimer * timer, ktime_t tim, const enum hrtimer_mode mode);
- 몇 가지 인자 설명
> HRTIMER_MODE_REL : 상대 시간. 현재 시간으로부터 요청한 ktime이 지난 후에 만료.
> CLOCK_MONOTONIC : 단조 시계로 특정시간부터 흐른 시간을 측정합니다. (일반적으로 부팅 이후 시간)
/* Init of hrtimer */
hrtimer_init(&ssHrTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ssHrTimer.function = &hrTimer_handler;
start_t = get_jiffies_64(); //jiffies;
hrtimer_start(&ssHrTimer, ms_to_ktime(10000), HRTIMER_MODE_REL); // 10sec
- 커널에서 제거(dirver_exit 함수)하면 타이머를 제거시켜 줍니다.
hrtimer_cancel(&ssHrTimer);
3. 동작확인하기
- 컴파일해서 디바이스 드라이버 파일을 생성한 후 커널에 추가해 봅니다. 바로 메시지를 보면 10000 표시가 안되다가 10초 후 “start_t – now_t = 10000” 메시지가 출력되는 것을 확인할 수 있습니다.
pi@raspberrypi:~/DriverStudy/day9_hrTimer $ sudo insmod day9_hrTimer.ko
pi@raspberrypi:~/DriverStudy/day9_hrTimer $ dmesg | tail -4
- 완료했으면 커널에서 삭제합니다.
pi@raspberrypi:~/DriverStudy/day9_hrTimer $ sudo rmmod day9_hrTimer.ko
감사합니다.
<참고 사이트>
1. Let's code a Linux Driver - 9: High Resolution Timer in a Linux Kernel Module
https://www.youtube.com/watch?v=3Djn_iGf7K8&list=PLCGpd0Do5-I3b5TtyqeF1UdyD4C-S-dMa&index=10
2. Linux Kernel Timer
3. High Resolution Timer
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=moony6463&logNo=10187067717
4. clock_gettime 사용법 (리눅스 정밀한 시간 얻어오기)
https://hand-over.tistory.com/74
5. hrtimer timer mode in hrtimer_init() vs expiry mode in hrtimer_start()
6. hrtimer_start High-resolution timers
https://linuxtv.org/downloads/v4l-dvb-internals/device-drivers/API-hrtimer-start.html
7. ktime accessors
https://docs.kernel.org/core-api/timekeeping.html#ktime-accessors