Linux 2 6字元裝置驅動程式樣例

2021-05-12 09:55:44 字數 4314 閱讀 4775

寫這些東西還真是花時間啊,繼續昨天的內容。

我寫驅動的時候總希望能找到乙個樣例參考一下,可惜網上的例子基本找不到。還好友善之臂的文件裡有些例子,但是說的很不詳細,要是直接輸入會有很多的編譯錯誤。我的這個例子是乙個控制led的例子,用linux就控制led,當然是相當的弱智的哈哈。我用的是s3c2410,led連線在gpb7~10上,灌電流方式驅動,io配置暫存器gpbcon的實體地址0x56000010,io資料暫存器gpbdat的實體地址0x56000014。程式中的幾個關鍵點,在我昨天的blog中有敘述。

首先編寫乙個叫做leds_test.c的檔案,內容如下:

#include

#include

#include

#include

#include

#include

//please configure your kernel first to use the following headers, because the directory "asm" is a short cut to your arch's "asm" directory.

//so do the headers in the "hardware" sub directory.

#include //this header is for ioremap(), iounmap().

#include //this header is for get_user(), put_user().

#define name "led_test"

module_author("lu xianzi <

[email protected]>"); //this line and the following 4 lines can be omitted.

module_description("led test driver");

module_license("gpl");

module_param(major, int, 0);

module_parm_desc(major, "major device number");

static int major = 231; //define device major

unsigned long * preg; //definition of register base.

static ssize_t led_test_write(struct file *file, const char __user *data, size_t len, loff_t *ppos)

static ssize_t led_test_read(struct file *file, char __user *buf, size_t len, loff_t *ppos)

static int led_test_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)

return 1; }

static int led_test_open(struct inode *inode, struct file *file)

static int led_test_release(struct inode *inode, struct file *file)

static struct file_operations led_test_fops = ;

static int __init led_test_init(void)

preg = ioremap(0x56000010, 0x20);

printk("virtual addr base = 0x%lx/n", (unsigned long)preg);

tmp = * (volatile unsigned long *)preg;

printk("gpbcon = 0x%lx/n", tmp);

tmp = * (volatile unsigned long *)(preg + 1);

printk("gpbdat = 0x%lx/n", tmp);

printk("seting led test driver.../n");

* (volatile unsigned long *)preg = 0x155555;

* (volatile unsigned long *)(preg + 1) = 0xfff;

tmp = * (volatile unsigned long *)preg;

printk("gpbcon = 0x%lx/n", tmp);

tmp = * (volatile unsigned long *)(preg + 1);

printk("gpbdat = 0x%lx/n", tmp);

printk("led test driver initiated./n");

return 0; }

static void __exit led_test_cleanup(void)

module_init(led_test_init);

module_exit(led_test_cleanup);

在驅動程式的目錄下建立乙個名為「makefile」的檔案,其內容只有一行:

obj-m := leds_test.o

編譯之,我的linux核心存在/home/lxz/linux-2.6.11.7,所以編譯命令為

make -k -c /home/lxz/linux-2.6.11.7 subdirs=$pwd modules

編譯後生成幾個檔案,其中leds_test.ko是我們需要的驅動模組。

然後在另外乙個目錄中編寫乙個叫做leds.c的檔案,其內容如下

#include

#include

int main(int argc, char **argv) ;

unsigned long tmp;

if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2], "%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no >3)

fd = open("/dev/leds", o_rdwr);

if (fd < 0)

ioctl(fd, on, led_no);

write(fd, buf, 10);

read(fd, buf, 4);

tmp = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);

printf("user program read: gpbdat = 0x%lx/n", tmp);

close(fd);

return 0;}

編譯之,輸入

arm-linux-gcc -o leds leds.c

然後把生成的leds_test.ko和leds這2個檔案拷貝到你的檔案系統中,如/home下,啟動linux。之後的過程如下:

/ # cd /home

/home # insmod leds_test.ko

lxz led test driver.

virtual addr base = 0xc485e010

gpbcon = 0x44555

gpbdat = 0x540

seting led test driver...

gpbcon = 0x155555

gpbdat = 0x7ff

led test driver initiated.

/home # mknod /dev/leds c 231 0

/home # ./leds 0 1

led test driver opened!

led test - ioctl: param 1 0

gpbcon = 0x155555

gpbdat = 0x77f

led test - write: user_data 1234567890

led test - read

user proled test driver released!

gram read: gpbdat = 0x77f

/home #

這裡有個非常有趣的事情,你會發現核心的printk函式比客戶程式的printf函式列印時出現一些混亂,我想應該是因為linux不是乙個實時系統,核心和使用者程式分時執行的結果。

如果要解除安裝驅動模組,如下:

/ # rmmod leds_test

led test driver unloaded!

/ #

Linux2 6塊裝置驅動程式

一 塊裝置的操作的處理體系結構 1.vfs 虛擬檔案系統 vfs位於塊裝置的處理體系結構的上層,提供乙個通用的檔案模型。vfs和塊裝置的關係見linux2.6裝置管理 系統呼叫的服務例程呼叫乙個合適的vfs函式,將檔案描述符和檔案內的偏移量傳遞給它。2.磁碟快取記憶體 vfs函式確定所請求的資料是否...

linux2 6字元裝置驅動開發模板

cpp view plain copy include include include include include 字元裝置驅動模板開始 define char dev device name char dev 是應當連線到這個編號範圍的裝置的名字,出現在 proc devices和sysfs中...

Linux裝置驅動程式學習(1) 字元裝置驅動程式

linux裝置驅動程式學習 1 字元裝置驅動程式 一 分配裝置號 1 對字元裝置的訪問是通過檔案系統內的裝置名稱進行的 dev ttys0 在核心中,include dev t 用來儲存裝置編號 包括主裝置號和次裝置號。由dev t獲得主次裝置號 major dev t dev minor dev ...