linux驱动程序开发2

驱动程序设备号
1 驱动程序有主设备号,次设备号之分,主设备号是区分设备属于哪个驱动的标志,次设备号是驱动程序用来区别多个设备的。
2 设备号的内部表示:
   typedef unsigned long dev_t;其中搞12位为主设备号,低20位为次设备号。
   已知dev_t类型的变量,要想获取主设备号或者次设备号,使用宏:MAJOR(dev_t dev)  MINOR(dev_t dev)
   已知主次设备号,生成dev_t类型变量,使用宏:MKDEV(int major, int minor);
3 分配主次设备号的方法
   一般请求分配设备号的时机应该是在驱动程序的初始化函数中,内核API有:
   int register_chrdev_region(dev_t first, unsigned int count, char *name)
   静态请求设备号,失败返回负数,dev_t为要申请的主次设备号,count为总共要申请的设备个数,name为驱动的名称
   int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name)
   动态申请设备号,失败返回负数,dev保存得到的设备号,firstminor为第一个要求申请的次设备号,count为申请的设备个数,name为驱动名称
   例子:
   int scull_major=0;
   int scull_minor=0;
   if(scull_major)
   {
      dev=MKDEV(scull_major, scull_minor);
      result=register_chrdev_region(dev, scull_nr_devs,  "scull");
   }
   else
   {
      result=alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
    }
   if(result<0)
   {
      printk("cannot get major");
      return result;
   }
4 释放设备号
unregister_chrdev_region(devno, scull_nr_devs);
5 创建设备文件
#mknod /dev/scull0 c 252 0
c为字符设备文件
6 注册设备驱动到内核
cdev_init(&dev->cdev, &scull_fops);
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&scull_fops;
err=cdev_add(&dev->cdev, devno, 1);
if(err)
   printk("add scull fail");
其中cdev_init和下面的两行代码都是初始化各个cdev的字段,cdev_add是将这个设备加入到操作系统字符设备链表中。
7 注销字符设备
cdev_del(&scull_devices[i].cdev);
cdev_del是将字符设备从字符设备链表中移除。
8 实现驱动中的重要功能函数
struct file_operations scull_fops = {
 .owner =    THIS_MODULE,
 .llseek =   scull_llseek,
// .llseek = no_llseek,
 .read =     scull_read,
 .write =    scull_write,
 .compat_ioctl =    scull_ioctl,
 .open =     scull_open,
 .release =  scull_release,
};
int scull_open(struct inode *inode, struct file *filp)
用户程序调用open的时候系统会调用驱动的open
int scull_release(struct inode *inode, struct file *filp)
用户调用close的时候一般会调用函数,是当文件表被释放的时候调用的,如果close的时候文件表没有被释放,则不会调用release函数
ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
                loff_t *f_pos)
用户调用read的时候,系统会调用驱动中的read函数,filp为文件表指针,buf,count为用户调用时传入的,f_pos为文件表中的f_pos字段
ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
                loff_t *f_pos)
loff_t scull_llseek(struct file *filp, loff_t off, int whence)
int scull_ioctl(struct inode *inode, struct file *filp,
                 unsigned int cmd, unsigned long arg)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值