一些笔记

本文详细介绍了Linux驱动程序的编译、设备文件的注册与管理,包括使用misc_register函数建立设备文件、static修饰符优化驱动效率、非阻塞I/O应用与类设备创建流程。同时,解释了字符设备编号的注册方式以及Java中static、public、private的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

make -C /usr/src/linux-2.6.33 -M /home/kylin/qudong/hello

单独编译一个驱动指令,无须在Makefile中指定KERNEL_DIR


设备文件与普通文件不同,不能使用IO函数建立,需要使用misc_register函数建立设备文件。设备文件位于/dev目录下。

extern int misc_register(struct miscdevice * misc);

extern int misc_deregister(struct miscdevice *misc);


注册设备文件需要声明一个设备文件的结构体来描述相关信息,即miscdevice结构体。

static struct file_operations dev_fops={.owner=THIS_MODULE};

static struct miscdevice misc={.minor=MISC_DYNAMIC_MINOR, .name=DEVICE_NAME,.fops=&dev_fops};

然后在init函数中ret=misx_register(&misc);



驱动中函数用static修饰,会和全局变量一起放在单独的内存中,除非卸载或者关机,这样就不用再进栈、出栈提高了驱动效率。

read函数分析:


ssize dev_write(struct file *file,const char _user *buf,size_t count,loff_tppos)中的const char _user*buf代表不能修改的数据,其中_user宏代表buf的内存区域位于用户空间。



*************************************************************************************************************************************************************


使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问,这两个系统调用最终又会引发设备驱动中的poll()函数被执行。

原函数:unsigned int (*poll)(struct file *filp, struct poll_table *wait);

其中:typedef struct poll_table_struct { poll_queue_proc qproc; unsigned long key; } poll_table; 经过以上驱动程序的poll()函数应该返回设备资源的可获取状态,即POLLIN,POLLOUT,POLLPRI,POLLERR,POLLNVAL等宏的位"或"结果.每个宏的含义都表示设备的一种状态,如:

常量 说明
POLLIN 普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级数据可读
POLLOUT 普通数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起
POLLNVAL 描述字不是一个打开的文件

***********************************************************************************


韦老师是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;

二、入口函数里

firstdrv_class = class_create(THIS_MODULE, "firstdrv");
firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */

三、出口函数里

class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);


而在linux2.6.30.4里,并没有class_device_createclass_device_unregister函数

我是这样子创建类和创建类的设备:

一、定义

static struct class *firstdrv_class;
static struct device *firstdrv_device;

二、入口函数里

/* 创建firstdrv类 */

firstdrv_class = class_create(THIS_MODULE, "firstdrv");


/* 在firstdrv类下创建xxx设备,供应用程序打开设备*/
firstdrv_device = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xxx");

三、出口函数里

device_unregister(firstdrv_device);  //卸载类下的设备
class_destroy(firstdrv_class); //卸载类


linux2.6.30.4使用device_create函数替代class_device_create函数;

使用device_unregister函数替代class_device_unregister函数。




******************************************************************************


内核提供了三个函数来注册一组字符设备编号,这三个函数分别是 register_chrdev_region()、alloc_chrdev_region() 和 register_chrdev()。其中,register_chrdev_region()是为提前知道

设备的主次设备号的设备分配设备编号。alloc_chrdev_region() 是动态分配主次设备号。register_chrdev()。是老版本的设备号注册方式,他只分配主设备号。从设备号在mknod的时候指定。

内核中所有已分配的字符设备编号都记录在一个名为 chrdevs 散列表里。该散列表中的每一个元素是一个 char_device_struct 结构。只为为一组对应同一个字符设备驱动的设备编号范围定义一个 char_device_struct 结构。


使用cdev_add注册字符设备前应该先调用register_chrdev_region或alloc_chrdev_region分配设备号。register_chrdev_region函数用于指定设备号的情况,alloc_chrdev_region函数用于动态申请设备号,系统自动返回没有占用的设备号


*************************************************************************************



java中static、public、private区别:
static修饰的可以不用实例化类就可以直接访问,直接常驻内存,public修饰的需要实例化类才能访问,一般修饰类的成员函数。private只能在本类中使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值