define SCULLIOCMAGIC k define SCULLIOCRESET IOSCULLIOCMAGIC 0 Use

  • Slides: 52
Download presentation

#define SCULL_IOC_MAGIC 'k' #define SCULL_IOCRESET _IO(SCULL_IOC_MAGIC, 0) /* Use 'k' as magic number */

#define SCULL_IOC_MAGIC 'k' #define SCULL_IOCRESET _IO(SCULL_IOC_MAGIC, 0) /* Use 'k' as magic number */ #define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC, 1, int) #define SCULL_IOCSQSET _IOW(SCULL_IOC_MAGIC, 2, int) #define SCULL_IOCTQUANTUM _IO(SCULL_IOC_MAGIC, 3) #define SCULL_IOCTQSET _IO(SCULL_IOC_MAGIC, 4) #define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5, int) #define SCULL_IOCGQSET _IOR(SCULL_IOC_MAGIC, 6 int) #define SCULL_IOCQQUANTUM _IO(SCULL_IOC_MAGIC, 7) #define SCULL_IOCQQSET _IO(SCULL_IOC_MAGIC, 8) #define SCULL_IOCXQUANTUM _IOWR(SCULL_IOC_MAGIC, 9, int) #define SCULL_IOCXQSET _IOWR(SCULL_IOC_MAGIC, 10 int) #define SCULL_IOCHQUANTUM _IO(SCULL_IOC_MAGIC, 11) #define SCULL_IOCHQSET _IO(SCULL_IOC_MAGIC, 12) /*HARDRESET命令,可將模組的用量計次歸零*/

簡易休眠 • wait_event(queue , condition) • wait_event_interruptible(queue , condition) • wait_event_timeout(queue , condition ,

簡易休眠 • wait_event(queue , condition) • wait_event_interruptible(queue , condition) • wait_event_timeout(queue , condition , timeout) • wait_event_interruptible_timeout (queue , condition , timeout)

遲滯式I/O : scullpipe • scull_p_read • https: //github. com/martinezjavier/ldd 3/blob/ master/scull/pipe. c

遲滯式I/O : scullpipe • scull_p_read • https: //github. com/martinezjavier/ldd 3/blob/ master/scull/pipe. c

6. 2. 2 -A Deeper Look at Wait Queues-手動休眠 • 第一步是建立並初始化一個待命佇列,通常以 DEFINE_WAIT(my_wqentry)巨集完成 • my_wqentry可以看成以下2個等效步驟

6. 2. 2 -A Deeper Look at Wait Queues-手動休眠 • 第一步是建立並初始化一個待命佇列,通常以 DEFINE_WAIT(my_wqentry)巨集完成 • my_wqentry可以看成以下2個等效步驟 : wait_queue_t my_wqentry; init_wait(my_wqentry); • void prepare_to_wait(wait_queue_head_t *queue, wait_queue_t *my_wqentry, int state) • void finish_wait(wait_queue_head_t *queue, wait_queue_t *my_wqentry)

喚醒程序的細節 • wake_up(wait_queue_head_t *queue) • wake_up_interruptible(wait_queue_head_t *queue) • wake_up_nr(wait_queue_head_t *queue) • wake_up_interruptible_nr(wait_queue_head_t *queue) •

喚醒程序的細節 • wake_up(wait_queue_head_t *queue) • wake_up_interruptible(wait_queue_head_t *queue) • wake_up_nr(wait_queue_head_t *queue) • wake_up_interruptible_nr(wait_queue_head_t *queue) • wake_up_all(wait_queue_head_t *queue) • wake_up_interruptible_all(wait_queue_head_t *queue)

6. 3 -poll and select • poll_table結構 – 宣告在<linux/poll. h> – 每個驅動程式都應該引入此標頭檔 void poll_wait(struct

6. 3 -poll and select • poll_table結構 – 宣告在<linux/poll. h> – 每個驅動程式都應該引入此標頭檔 void poll_wait(struct file *filp, wait_queue_head_t *sync, poll_table *pt); • poll. h預先定義了一系列常數的各種可能的輪詢狀態 – – – POLLIN : 裝置可被READ而不遲滯 POLLOUT裝置可被寫入而不遲滯 POLLRDNORM : 資料已準備好可被讀取 POLLWRNORM : 資料已準備好可被寫入 POLLPRI, POLLHUP, POLLER

Poll 所用的資料結構 只調查一個裝置 struct poll_table_struct int error; struct poll_table_page *tables; struct poll_table_entry wait_queue_t wait;

Poll 所用的資料結構 只調查一個裝置 struct poll_table_struct int error; struct poll_table_page *tables; struct poll_table_entry wait_queue_t wait; wait_queue_head_t *wait_address; 自備wait_queue_head_t 的一般裝置結構 一個觸發了poll() 系統呼叫的行程 poll_table_struct結構 輪詢表項目 正在輪詢兩個裝置

6. 4 -Asynchronous Notification • signal (SIGIO , &input_handler); fcntl (STDIN_FILENO , F_SETOWN ,

6. 4 -Asynchronous Notification • signal (SIGIO , &input_handler); fcntl (STDIN_FILENO , F_SETOWN , getpid()); oflags = fcntl (STDIN_FILENO , F_GETFL); fcntl (STDIN_FILENO , F_SETFL , oflags | FASYNC); • 執行過這兩次fcntl( )系統呼叫之後,就可要求輸入檔的 驅動程式在每次收到新資料時,就發出SIGIO信號。此 信號會被送到filp->owner所指的行程。

6. 4. 1 -驅動程式對於臨時通知的 支援 • <linux/fs. h> • int fasync_helper (int fd ,

6. 4. 1 -驅動程式對於臨時通知的 支援 • <linux/fs. h> • int fasync_helper (int fd , struct file *filp , int mode , struct fasync_struct **fa) • void kill_fasync (struct fasync_struct **fa , int sig , int band)

DEMO - 1 • 範例misc-modules/sleepy. c 1. make 2. insmod. /sleepy. ko 3. cat

DEMO - 1 • 範例misc-modules/sleepy. c 1. make 2. insmod. /sleepy. ko 3. cat /proc/devices | grep sleepy 4. mknod /dev/sleepy c 250 0 5. cat /dev/sleepy &(讀取動作==read) 6. echo trash > /dev/sleepy(寫入動作==write)

DEMO - 2 1. tail -f /var/log/kernlog 觀察cat與echo會造 成Process怎樣的結果 2. cat /dev/sleepy & –

DEMO - 2 1. tail -f /var/log/kernlog 觀察cat與echo會造 成Process怎樣的結果 2. cat /dev/sleepy & – Process 3066去睡覺 3. echo trash > /dev/sleepy • Process 3066被喚醒