1.内核模块编译进内核:
主要修改 Kconfig/Makefile
2.设备号作用
.主设备号:用来反映设备类型
.次设备号:区分同类型的设备
3.主次设备号实现
dev_t MKDEV(ma,mi)--创建设备号
MAJOR(dev_t dev)--主设备号
MINOR(dev_t dev)--次设备号
4.分配主设备号
a--静态分配
. int register_chrdev_region(dev_t first, unsigned int count, char *name)
.查看已被分配的主设备号 Documentation/devices.txt
b--动态分配
. int alloc_chrdev_region(dev_t *dev,unsigned int firstminor,unsigned int count,char *name)
动态分配的设备号,可以从/proc/devices中取到
c--注销设备号
. void unregister_chrdev_region(dev_t first, unsigned int count)
5.创建设备文件
mknod filename type major minor
6.三个重要的内核数据结构
struct file_operations,struct file,struct inode
7.字符设备的注册步骤(字符设备使用struct cdev来描述)
a--.分配 struct cdev *cdev_alloc(void)
b--.初始化 void cdev_init(struct cdev *cdev,const struct file_operations *fops)
*fops设备对应的操作函数集
c--.添加 int cdev_add(struct cdev *p, dev_t dev,unsigned count)
d--.注销 int_del(struct cdev *p)
8.合理使用Printk
.全局关闭/打开
9.并发控制
--信号量使用(<asm/semaphore.h)
.定义信号量 struct semaphore sem;
.初始化信号量 void sema_init(struct semaphore *sem,int val)
--初始化一个互斥锁,把信号量值设为1 :void init_MUTEX(struct semaphore *sem)
把信号量值设为0 :void init_MUTEX_LOCKED(struct semaphore *sem)
*DECLARE_MUTEX(name)
*DECLARE_MUTEX_LOCKED(name)
.获取信号量
---void down(struct semaphore *sem)
---int down_interruptible(struct semaphore *sem)
---down_killable(struct semaphore *sem)
.释放信号量 void up(struct semaphore *sem)
-----自旋锁
*spin_lock_init(x)
*spin_lock(lock)
*spin_trylock(lock)
*spin_unlock(lock)
10.驱动ioctl方法
int (*ioctl)(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
--ioctl(Type--幻数/Number--第几个命令/Direction--_IOC_NONE _IOC_READ _IOC_WRITE/Size--用户
数据大小)
*定义命令
_IO(type,nr)/_IOR(type,nr,datatype)/_IOW(type,nr,datatype)/_IOWR(type,nr,datatype)
*实现命令
--返回值(每个命令对应才正确,不对应返回-EINVAL)
--参数 int access_ok(int type,const void *addr,unsigned long size)
--命令操作
11.等待队列(阻塞型字符设备驱动)
*定义等待队列
wait_queue_head_t my_queue
*初始化等待队列
init_waitqueue_head(&my_queue)
*定义并初始化
DECLARE_WAIT_QUEUE_HEAD(my_queue)
*有条件睡眠
wait_event(queue,condition) -----TASK_UNINTERRUPTIBLE
wait_event_interruptible(queue,condition)-----TASK_INTERRUPTIBLE
int wait_event_killable(wait_queue_t queue,condition)-----TASK_KILLABLE
*无条件睡眠
sleep_on(wait_queue_head_t *q)
interruptible_sleep_on(wait_queue_head_t *q)
*从等待队列中唤醒进程
wake_up(wait_queue_t *q) ----唤醒状态为TASK_UNINTERRUPTIBLE、TASK_INTERRUPTIBLE、
TASK_KILLABLE
wake_up_interruptible(wait_queue_t *q)----TASK_INTERRUPTIBLE
驱动程序不是进程,而是一个函数。。。??
12.Select 系统调用--多路监控
int select(int maxfd,fd_set *readfds,fd_set *writefds,fe_set *exceptfds,const struct
timeval *timeout)
驱动实现:unsigned int(*poll)(struct file *filp,poll_table *wait)
*把进程添加到等待队列 poll_wait
*返回掩码---设备可读(POLLIN|POLLRDNORM)/设备可写(POLLOUT|POLLWRNORM)
13.自动创建设备文件
*devfs_register(devfs_handle_t dir,const char *name,unsigned int flags,unsigned int
major,unsigned int minor,umode_t mode,void *ops,void *info)--------2.4内核
*struct class *myclass = class_create(THIS_MODULE,"my_device_driver");
device_create(myclass,NULL,MKDEV(major_num,0),NULL,"my_device");
udev/mdev---------2.6内核