com android brnting,字符设备驱动框架 - osc_6nx63520的个人空间 - OSCHINA - 中文开源技术交流社区...

ae4c4d1656c1d1a72780fd8d10b5a66f.png

应用程序通过标准接口(C Library)调用驱动程序。

C Library 通过swi 指令进入内核。

字符设备的注册

intregister_chrdev(unsigned intmajor, const char *name, const structfile_operations *fops)

a、函数说明:

Param1:主设备号

Param2:设备名字

Param3:文件操作结构体指针

Return:当传入的主设备号为0时(系统自动分配主设备号),函数返回值为系统自动分配的主设备号

b、这个函数在内核中最简单的实现方式:

171697ff86f4fd3ee223a7b3966f1ec3.png

猜想:在内核里,声明一个struct file_operations类型的chrdev的数组,以major为下标;

当调用这个函数时,在指定下标的数组成员内,填充file_operations结构,实现驱动设备的注册。

驱动的使用方法

动态加载驱动的方法:

insmod *.ko

手动创建设备节点:

mknod /dev/xxx c 111 0

应用程序怎么操作底层设备呢?

①fd =open("/dev/xxx", O_RDWR);

②write(fd, &val, 4);

通过文件描述符,实现对底层设备的操作

如何自动创建设备节点?

mdev根据系统信息自动创建设备节点。

如何生成系统信息?

在加载驱动时生成,在入口函数实现。

为什么系统可以根据系统的设备信息动态生成/删除设备节点?

/etc/init.d/rcS 脚本文件,有如下内容:

echo /sbin/mdev > /proc/sys/kernel/hotplug

系统设备信息:

/sys/class/class_dev

class目录下,每一个class_dev存储一个设备驱动信息,mdev根据这个信息生成设备节点。

实际上,

对于驱动程序:(主设备号)

①由系统自动分配主设备号

②由用户指定主设备号

对于应用程序:(设备节点)

①手动创建设备节点

②由系统自动创建/删除设备节点

六、驱动程序基本框架

①实现驱动程序;

②声明并初始化file_operations结构体;(把驱动程序的函数指针填充到结构体中)

③编写入口函数,并在入口函数中注册设备驱动(register_chrdev(0, "drv_name", drv_fops););

④编写出口函数,并在出口函数中卸载驱动(unregister_chrdev(major, "drv_name"););

⑤修饰入口函数(module_init("入口函数"););

⑥修饰出口函数(module_exit("出口函数"););

七、实例

driver.c

1#include

2#include

3#include

4#include

5#include

6#include

7#include

8#include

9#include

10#include

11

12int major;

13static struct class *simple_class;

14static struct class_device *simple_class_dev;

15

16staticint simple_open(struct inode *inode, struct file *file);17staticssize_t simple_write(struct file *file, constchar __user *buf, size_t count, loff_t *ppos);18

19static struct file_operations simple_fops = {

20         .open = simple_open,

21         .write = simple_write,

22         .owner = THIS_MODULE,

23 };

24

25staticint simple_open(struct inode *inode, struct file *file)26 {

27         printk("simple_open\n");28         return0;

29 }

30

31

32staticssize_t simple_write(struct file *file, constchar __user *buf,33 size_t count, loff_t *ppos)

34 {

35         printk("simple_write\n");36         return0;

37 }

38

39staticint __init simple_init(void)

40 {

41         major = register_chrdev(0, "simple", &simple_fops);

42         simple_class = class_create(THIS_MODULE, "myDrv");

43         simple_class_dev = class_device_create(simple_class, NULL, MKDEV(major, 0), NULL, "simple");

44

45         return0;

46 }

47

48staticvoid __exit simple_exit(void)

49 {

50         unregister_chrdev(major, "simple");

51         class_device_unregister(simple_class_dev);

52         class_destroy(simple_class);

53         return;

54 }

55

56 module_init(simple_init);

57 module_exit(simple_exit);

58

59 MODULE_LICENSE("GPL");

app.c

1 #include

2 #include

3 #include

4 #include

5

6 int main (void)

7 {

8         int fd;

9         int val = 1;

10

11         printf("test app:\n");12

13         fd = open("/dev/simple", O_RDWR);

14         if(fd < 0)

15         {

16                 printf("open failed!---%d---\n", fd);17                 return0;

18         }

19         write(fd, &val, 4);

20

21         return0;

22 }

Makefile

1 KERN_DIR = /work/system/linux-2.6.22.6

2

3 all: 4         make -C $(KERN_DIR)M=`pwd` modules 5 6 clean: 7         make -C $(KERN_DIR)M=`pwd` modules clean 8rm -rf modules.order 9

10 obj-m += simple.o

79034d1065474a5f59522d7034db4eeb.png

0e88a1082cf78cb1f59102e3d8e16a89.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值