Timer và ngắt dùng timer: 1 Khái quát về timer trong kernel:

Một phần của tài liệu document (Trang 74 - 77)

1. Khái quát về timer trong kernel:

Timer là một định nghĩa quen thuộc trong hầu hết tất cả các hệ thống khác nhau. Trong linux kernel, timer được hiểu là trì hỗn thời gian động để gọi thực thi một hàm nào đó được lập trình trước. Nghĩa là thời điểm bắt đầu trì hỗn khơng cố định, thơng thường được tính từ lúc cài đặt khởi động timer trong hệ thống, khoảng thời gian trì hỗn do người lập trình quy định, khi hết thời gian trì hỗn, timersinh ra một ngắt. Kerneltạm hoãn hoạt động hiện tại của mình để thực thi hàm ngắt được lập trình trước đó.

Để đưa một timer vào hoạt động, chúng ta cần phải thực hiện nhiều thao tác. Đầu tiên phải khởi tạo timervào hệ thống linux. Tiếp theo, cài đặt khoảng thời gian mong muốn trì hỗn. Cài đặt hàm thực thi ngắt khi thời gian trì hỗn kết thúc. Khi xảy ra hoạt động ngắt,

timer sẽ bị vơ hiệu hóa. Vì thế, nếu muốn timer hoạt động theo chu kỳ cố định chúng ta phải khởi tạo lại timer ngay trong chương trình thực thi ngắt. Số lượng timer khởi tạo trong kernel là khơng giới hạn, vì đây là một timer mềm khơng phải là timer vật lý, có giới hạn là dung lượng vùng nhớ cho phép. Chúng ta sẽ trình bày cụ thể những bước trên trong phần sau.

2. Các bước sử dụng timer:

**Lưu ý: Khi sử dụng các hàm trong timer chúng ta phải thêm thư viện

<linux/timer.h>ở đầu chương trình.

a. Bước 1: Khai báo biến cấu trúc timer_listđể lưu timerkhi khởi tạo

Cấu trúc timer_list được linux kernel định nghĩa trong thư viện

<linux/timer.h>như sau:

struct timer_list { struct list_head entry; unsigned long expires;

void (*function) (unsigned long); unsigned long data;

struct tvec_t_base_s *base; }

Ta khai báo timer bằng dòng lệnh sau:

/*Khai báo một timer có tên là my_timer*/

struct timer_list my_timer;

b. Bước 2:Khai báo và định nghĩa hàm thực thi ngắtHàm thực thi ngắt có dạng như sau: Hàm thực thi ngắt có dạng như sau:

void my_timer_function (unsigned long data) {

/*Các thao tác do người lập trình driver quy định*/ ...

/*Nếu cần thiết có thể khởi tạo lại timer trong phần cuối chương trình*/

}

c. Bước 3:Khởi tạo các tham số cho cấu trúc timer

Công việc tiếp theo là yêu cầu kernel cung cấp một vùng nhớ cho timer hoat động, chúng ta sử dụng câu lệnh:

/*Khởi tạo timer vửa khai báo my_timer*/

init_timer (&my_timer);

Sau khi kernel dành cho timer một vùng nhớ, timer vẫn còn trống chưa được gán những thông số cần thiết, công việc này của người lập trình driver:

/*Khởi tạo giá trị khoảng thời gian muốn trì hỗn, đơn vị tính bằng tick*/

my_timer.expires = jiffies + delay;

/*Gán tham số cho hàm thực thi ngắt, nếu khơng có tham số ta có thể gán một giá trị bất kỳ*/

my_timer.data = 0;

/*Gán con trỏ hàm xử lý ngắt vào timer*/

my_timer.function = my_function;

 my_timer.expires đây là giá trị thời gian tương lai có đơn vị là tick, tại mọi thời điểm, timerso sánh với số jiffies. Nếu số jiffiesbằng với số my_timer.expiresthì ngắt xảy ra.

 my_timer.data là tham số chúng ta muốn đưa vào hàm thực thi ngắt, đôi khi chúng ta muốn khởi tạo các thông số ban đầu cho hàm thực thi ngắt, kế thừa những thông tin đã xử lý từ trước hay từ người dùng.

 my_timer.functionlà trường chứa con trỏ của hàm phục vụ ngắt đã được khởi tạo và định nghĩa trước đó.

d. Bước 4:Kích hoạt timer hoạt động trong kernel:Chúng ta thực thi lệnh sau: Chúng ta thực thi lệnh sau:

add_timer (&my_timer);

Tham số của hàm add_timer là con trỏ của timer được khởi tạo và gán các tham số cần thiết.

Khi timerđược kích hoạt, hàm thực thi ngắt hoạt động, nó sẽ bị vơ hiệu hóa trong chu kỳ tiếp theo. Muốn timer tiếp tục hoạt động, chúng ta phải kích hoạt lại bằng câu lệnh sau:

/*Kích hoạt timer hoạt động lại cho chu kỳ ngắt tiếp theo*/

mod_timer (&my_timer, jiffies + new_delay);

Nếu muốn xóa timer khỏi hệ thống chúng ta sùng lệnh sau:

/*Xóa timer khỏi hệ thống*/

del_timer (&my_timer);

Tuy nhiên lệnh này chỉ thực hiện thành công khi timer khơng cịn hoạt động, nghĩa là khi timer còn đang chờ chu kỳ ngắt tiếp theo dùng lệnh del_timer() sẽ không hiệu quả. Muốn khắc phục lỗi này, chúng ta phải dùng lệnh del_timer_sync(), lệnh này sẽ chờ cho đến khi timerhoàn thành chu kỳ ngắt gần nhất mới xóa timerđó.

3. Ví dụ:

Đoạn chương trình sau sẽ định thời xuất thơng tin ra màn hình hiển thị vời chu kỳ là 1s. Mỗi lần xuất sẽ thay đổi thông tin, thông báo những lần xuất thông tin là khác nhau;

int counter = 0;

/*Khai báo biến timer phục vụ ngắt*/

struct time_list my_timer;

/*Khai báo định nghĩa hàm phục vụ ngắt*/

void timer_isr (unsigned long data) {

/*In thông báo cho người dùng*/

printk (“Driver: Hello, the counter’s value is %d\n”, counter++);

/*Cài đặt lại giá trị timer cho lần hoạt động tiếp theo, cài đặt chu kỳ 1 giây*/

mod_timer (&my_timer, jiffies + HZ); }

/*Thực hiện khởi tạo timer trong khi cài đặt driver vào hệ thống, trong hàm init()*/

static int

__init my_driver_init (void) {

/*Các lệnh khởi tạo khác*/

...

/*Khởi tạo timer hoạt động ngắt*/ /*Khởi tạo timer đã được khai báo*/

init_timer (&my_timer);

/*Cài đặt các thông số cho timer*/

my_timer.expires = jiffies + HZ;//Khởi tạo trì hỗn ban đầu là 1s;

my_timer.data = 0;//Dữ liệu truyền cho hàm ngắt là 0;

my_timer.function = my_function;//Gán hàm thực thi ngắt cho timer.

/*Kích hoạt timer hoạt động trong hệ thống*/

add_timer (&my_timer); ...

}

Một phần của tài liệu document (Trang 74 - 77)

Tải bản đầy đủ (PDF)

(91 trang)