第一個Linux驅動

來源:互聯網
上載者:User

Linux系統將驅動映射成檔案,這些檔案稱為裝置檔案或驅動檔案,
都儲存在/dev/目錄中。這種設計理念使得與Linux驅動進行互動就像
與普通檔案進行互動一樣容易。

---編寫Linux驅動程式的步驟

Linux驅動程式和其他類型的Linux程式一樣,也有自己的規則。以
下是編寫一個基本Linux驅動的一般步驟。

1)建立Linux驅動骨架(裝載和卸載Linux驅動)
任何類型的程式都有個基本的結構,就像C程式都需要一個main函
數一樣。核心在使用驅動的時候也會需要先進行初始化、建立裝置
檔案、分配記憶體等工作,當驅動卸載時需要釋放資源、刪除檔案等
工作。在Linux驅動中需要提供兩個函數來進行初始化和退出操作。
分別是module_init和module_exit,驅動程式都會具備這兩個函數

2)註冊和銷毀裝置檔案
Linux下所有的裝置都是檔案,所以每個驅動都需要一個裝置檔案,
建立裝置檔案的工作通常放在初始化的位置。刪除裝置檔案通常放
在驅動退出的位置。

3)指定驅動相關資訊
驅動程式是自描述的。可以使用modinfo來擷取驅動程式的作者、遵
循協議、驅動描述等資訊。這些資訊都需要在驅動代碼中指定。
MODULE_AUTHOR MODULE_LICENSE MODULE_ALIAS等

4)指定回呼函數
Linux指定了多種動作,也可以成為事件。例如,向裝置檔案寫入資料
時會觸發"寫"事件,Linux體統會調用對應驅動程式的write回呼函數,從
裝置檔案讀資料時,會觸發讀事件,系統會調用驅動程式的read回呼函數
一個驅動程式並不需要指定所有的毀掉函數。回呼函數會通過相關機制
進行註冊。

5)編寫商務邏輯
這是驅動程式的核心部分,以上4部分只有骨架是沒有意義的。任何一個
完整的Linux驅動都會做一些與其功能相關的工作。
6)編寫Makefile檔案
7)編譯驅動程式
8)安裝和卸載Linux驅動

---驅動分析
裝置檔案和普通檔案不同,不能使用IO函數建立,而是需要進行專門的裝置註冊
函數和裝置銷毀函數。在初始化驅動時執行建立裝置檔案,在卸載驅動時刪除
裝置檔案。並且裝置還需要一個結構體來描述與其相關的資訊。裝置結構體中有
個重要的成員變數fops,用於描述裝置檔案在各種可觸發時間的函數指標。這樣如
何實現對裝置檔案進行操作的過程就清楚了。
---代碼實現
下面的代碼參考和整理了《Android深度探索HAL與驅動開發》(-李寧)的書籍。

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "worldcount"

static unsigned char mem[1000];
static char read_flag = 'y';
static int written_count = 0;


static ssize_t wordCountRead( struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
if( read_flag == 'n')
{
copy_to_user( buf, (void *)mem, written_count);
printk ("read count:%d", written_count);
read_flag = 'y';
return written_count;
}
else
return 0;
}

static ssize_t wordCountWrite (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
copy_from_user (mem, buf, count);
read_flag = 'n';
written_count = count;
printk ("written count :%d", count);
return count;
}

static struct file_operations dev_fops =
{.owner = THIS_MODULE, .read = wordCountRead, .write = wordCountWrite};

static struct miscdevice misc =
{.minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops};


static int wordCount_init( void)
{
int ret;
ret = misc_register (&misc);
printk ("word count init success \n");
return ret;
}

static void wordCount_exit (void)
{
misc_deregister (&misc);
printk (" word count exit success \n");
}

module_init (wordCount_init);
module_exit (wordCount_exit);


MODULE_LICENSE ("GPL");
MODULE_ALIAS ("word count module");
MODULE_AUTHOR ("lining");

---程式碼分析
1)本驅動是一個簡單字元裝置驅動MISC裝置,該種裝置便於註冊而且操作也不複雜
2)除了引入必要的標頭檔和定義相關的變數,代碼中也專門實現了裝置檔案的讀寫操作
3)所有的函數和變數都定義為static,這樣便於調高驅動效率。
4)code中制定了讀寫回呼函數並且指定了檔案操作結構體,在模組載入卸載函數中進行
了裝置的安裝和移除工作,這樣我們就會在/dev/下發現wordcount裝置檔案。
5)最後指定了裝置檔案的相關資訊
---錯誤總結
總結編寫該驅動過程中遇到的錯誤。
1)由於忘記指定裝置安裝和卸載,並且錯誤的寫成MODULE_INIT(wordCount_init);
MODULE_EXIT(wordCount_exit).這會導致在/dev/下無法產生裝置檔案,但是使用命令對
驅動進行安裝的時候仍然能夠成功,也能modinfo查看資訊。
2)使用sudo echo 'hello world' > /dev/wordCount能夠操作成功,而且使用cat查看能夠顯示字元
但是之後對模組進行卸載的時候會提示資源繁忙,無法卸載。
PS-->以上測試錯誤是我在Ubuntu系統中測試的,當我切換到win7下使用虛擬機器測試的時候

則不會出現這種問題,上述問題可能是一個意外。

---驅動測試代碼

#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

void main()
{
int fd;
char *buf;
buf = (char *)malloc(10);
puts("hello world\n");
fd = open("/dev/worldcount", O_RDWR);
if (fd > 0)
printf(" open success %d\n", fd);
else
printf("open failed \n");

write (fd,"test", sizeof("test") );
read (fd, buf,1);
buf[1] = '\0';
puts(buf);
}

---代碼效果
便已執行代碼顯示結果如下
hello world

open success 3
t

證明驅動是工作的,但是我們去cat /dev/worldcout則不會看到其中的內容
(這個我也很好奇為什麼不會看到字串test。)
基本上這個簡單的MISC裝置驅動就完成了。
O(∩_∩)O謝謝,記錄自己學習的點點滴滴。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.