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...