流程:
init
{
}
exit
{
}
申請設備號 (動態注冊/靜態注冊) 創建一個字符設備 cdev_alloc
初始化字符設備 cdev_init
設備號和字符設備關聯 cdev_add
銷毀字符設備 cdev_del
解注冊設備號 unregister_chrdev_region
1 設備號
設備號分為主設備號和次設備號主設備號表示一類設備
次設備號表示一類設備中的一個設備
#include
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) typedef u_long dev_t;
2 申請設備號
靜態注冊
#include
extern int register_chrdev_region(dev_t, unsigned, const char *);
函數實現在char_dev.c
int register_chrdev_region(dev_t from, unsigned count, const char *name)
from : 設備號 通過 MKDEV 生成count : 子設備個數
name : 設備名
返回值: 成功返回0, 失敗返回負數錯誤碼
動態注冊
#include
extern int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *);
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
const char *name) dev : 設備號指針
baseminor : 子設備第一個編號count : 子設備個數
name : 設備名
返回值: 成功返回0, 失敗返回負數錯誤碼
注銷設備號
#include
void unregister_chrdev_region(dev_t from, unsigned count) from : 設備號
count: 子設備個數
3 創建字符設備
struct cdev *cdev_alloc(void)
分配一個cdev結構體,使用此結構體描述一個字符設備成功返回一個指針,否則返回NULL
#include
void cdev_del(struct cdev *p) 刪除字符設備結構體#include
void cdev_init(struct cdev *cdev, const struct file_operations
*fops)
初始化一個字符設備
cdev :被初始化的字符設備指針fops :字符設備操作函數指針集
int cdev_add(struct cdev *p, dev_t dev, unsigned count) 講字符設備添加到內核
體指針
p :字符設備結構體指針,cdev_alloc函數成功返回的結構
dev : 設備號 通過動態或靜態成功分配的設備號count :子設備個數
返回值:成功返回0, 出錯返回負數的錯誤碼
4 創建設備文件
sudo mknod /dev/haha0 c 250 0
/dev/haha0 創建的子設備文件名
c 字符設備
250 主設備號
0 次設備號
會在 /dev 下創建一個haha0的一個字符設備文件,主設備號
250,次設備號0
5 數據拷貝
char user *buf : user 指用戶空間的指針
從內核空間向用戶空間拷貝數據
static inline long copy_to_user(void user *to, const void *from, unsigned long n)
to :用戶空間指針( user) from :數據源
n :拷貝的字節數返回值 0 成功
從用戶空間向內核空間拷貝數據
static inline long copy_from_user(void *to, const void user * from, unsigned long n) to :內核buf指針
form:用戶空間數據源指針n : 拷貝字節數
返回值 0 成功
注:字符設備驅動測試步驟:
1 編譯出hello.ko(make)和test 2 sudo insmod hello.ko
3 cat /proc/devices 查看設備號
4 sudo mknod /dev/haha0 c 250 0
5 sudo ./test
如果打印open /dev/haha0 ok 則驅動正常否則驅動有錯,需改正
6 sudo rmmod hello
7 sudo rm -rf /dev/haha0