linux核心字元裝置驅動之讀操作

2021-08-08 07:04:29 字數 2924 閱讀 8880

char rbuf[1024] = ; //分配緩衝區,儲存讀取的資料;

ret = read(fd, rbuf, 1024);//讀裝置,將從裝置讀取的資料儲存在rbuf緩衝區中,要讀1024位元組;

ret儲存實際讀取的位元組數;

struct file_operations ;
read介面作用:用於讀取裝置,並且將讀取的資料上報給使用者;

與應用程式read的呼叫關係;

應用程式呼叫read->…->呼叫驅動read介面

引數:

file:檔案指標

buf:儲存使用者緩衝區的首位址(rbuf),在驅動程式中不能直接訪問這個buf(*buf = 1不允許),如果驅動程式要向使用者緩衝區寫入資料,必須利用核心提供的記憶體拷貝函式,將核心驅動的資料拷貝到使用者緩衝區中;

count:使用者要讀取的位元組數,例如1024位元組

ppos:儲存讀的位置資訊,例如

獲取上一次的讀位置:

loff_t pos = *ppos;

假如這次成功讀了1024位元組;

更新讀位置資訊:

*ppos = pos + 1024;

切記:對於read介面的第二個引數buf,這個buf指標儲存的是使用者緩衝區的首位址,在核心空間不能直接訪問操作,需要利用核心的記憶體拷貝函式,將核心的資料拷貝到使用者緩衝區中,這個記憶體拷貝函式:

unsigned

long copy_to_user(void __user *to,

const

void *from,

unsigned

long n)

作用:將核心驅動的資料拷貝到使用者緩衝區中

引數:

to:目的位址,傳遞使用者緩衝區的首位址(buf)

from:源位址,傳遞核心緩衝區的首位址

n:要拷貝的位元組數

只要看到__user修飾的指標,就不能在驅動中直接訪問操作,必須利用記憶體拷貝函式

1.mkdir /opt/drivers/2.0

2.cd /opt/drivers/2.0

3.vim led_drv.c

4.vim led_test.c

5.vim makefile

6.make

7.arm-linux-gcc -0 led_test led_test.c

8.cp led_test led_drv.ko /opt/rootfs

arm:

1.insmod led_drv.ko

2.cat /proc/devices //獲取主裝置號

3.mknod /dev/myled c 主裝置號 0

4../led_test

#include 

#include

#include //struct file_operations

#include //struct cdev + 裝置號

#include

#include

#include //copy_to_user

//宣告描述led硬體相關的資料結構

struct led_resource

;//定義初始化led硬體資訊

static

struct led_resource led_info =

, [1] =

};//定義裝置號

static dev_t dev;

//定義字元裝置物件

static

struct cdev led_cdev;

//呼叫關係:應用程式open->....->led_open

static

int led_open(struct inode *inode, struct file *file)

//呼叫關係:應用程式close->...->led_close

static

int led_close(struct inode *inode, struct file *file)

//呼叫關係:應用程式read->...->led_read

static ssize_t led_read(struct file *file,

char __user *buf,

size_t count,

loff_t *ppos)

//定義初始化硬體操作方法

static

struct file_operations led_fops =

;static

int led_init(void)

return0;}

static

void led_exit(void)

//解除安裝字元裝置物件

cdev_del(&led_cdev);

//釋放裝置號

unregister_chrdev_region(dev, 1);

}module_init(led_init);

module_exit(led_exit);

module_license("gpl");

應用程式:

#include 

#include

#include

#include

int main(void)

read(fd, &udata, sizeof(udata));

printf("從驅動讀取的資料為:udata = %#x\n", udata);

//關閉裝置

//close->...->呼叫led_close

close(fd);

return

0;}

Linux核心之字元裝置驅動

學習計畫 1.vfs 虛擬檔案系統 vfs的作用就是採用標準的unix系統呼叫讀寫位於不同物理介質上的不同檔案系統。vfs是乙個可 以讓open read write 等系統呼叫不用關心底層的儲存介質和檔案系統型別就可以工作的 粘合層。在古老的dos作業系統中,要訪問本地檔案系統之外的檔案系統需要使...

Linux驅動開發之字元裝置讀操作

1 驅動源 include include include include include include static int hello major 248 主裝置號 static int hello minor 0 次裝置號 static int number of devices 1 字元裝...

Linux裝置驅動之《字元裝置驅動》

linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是乙個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open close read write 等。下面是乙個字元裝置驅動程式的簡單實現test.c 模組分析 1.初始化裝置驅動的結構體 struct fil...