新闻中心

EEPW首页>嵌入式系统>设计应用> 面对不断升级的内核如何学习linux设备驱动

面对不断升级的内核如何学习linux设备驱动

作者: 时间:2013-03-18 来源:网络 收藏

  如何应对不断升级的内核

  内核升级对驱动的影响主要体现在,(1)驱动接口定义的变化(2)内核的一些功能函数的名称、参数、头文件、宏定义的变化(3)平台代码关于硬件操作方面封装的一些函数的变化(4)设备模型的影响。下面探讨一下,如何应对这几个方面的问题:

  驱动接口定义的变化

  如:2.4内核中字符的注册接口是

  int register_chrdev(unsigned int major, const char * name, struct file_operations *fops)

  而2.6内核中已经不建议使用这种方法了,改为:

  int cdev_add(struct cdev *p, dev_t dev, unsigned count)

  又如:2.6.27内核中网卡接口的net_device结构成员和低版本的net_device结构成员也发生了一些变化。

  这种接口定义及注册方法带来的变化,发生的并不频繁。解决方案是:参考内核中的代码。这种接口定义及注册方法在内核中非常容易找到,如:字符的注册方法及接口定义可以参照内核driver/char/目录下的很多实例。

  内核的一些功能函数的名称、参数、头文件、宏定义的变化

  如:中断注册函数的格式及参数在2.4内核、2.6内核低版本和高版本之间都存在差别

  在2.6.8中,中断注册函数的定义为:

  int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long irq_flags, const char * devname, void *dev_id)

  irq_flags的取值主要为下面的某一种或组合:

  SA_INTERRUPT、SA_SAMPLE_RANDOM、SA_SHIRQ

  在2.6.26中,中断注册函数的定义为:

  int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)

  typedef irqreturn_t (*irq_handler_t)(int, void *);

  irq_flags的取值主要为下面的某一种或组合:(功能和2.6.8的对应)

  IRQF_DISABLED、IRQF_SAMPLE_RANDOM、IRQF_SHARED

  当出现这些问题时,编译过程中,编译器会给我们比较明确的错误提示,根据这些提示你可以判断出是否是缺少头问题、是否是函数参数定义有误等。解决问题的最好办法还是到你的目标内核中找信息。此时找问题的方法可以借助于搜索,如:你可以在新的内核中搜索request_irq,看新内核中的驱动是如何使用它的。这种方法非常有效。

  平台代码关于硬件操作方面封装的一些函数的变化

  内核中,硬件平台相关的代码在内核更新过程中变化比较频繁。和我们的也是息息相关。所以在针对一个新内核编写设备驱动前,一定要熟悉你的平台代码的结构。有时平台虽然提供了内核要求的接口函数,但使用起来功能却并不完善。下面还是先举个例子说明平台代码更新对设备驱动的影响。

  如:在-2.6.8内核中,调用set_irq_type(IRQ_EINT0, IRQT_FALLING);去设置的IRQ_EINT0的中断触发信号类型,你会发现不会有什么效果。跟踪代码发现内核的set_irq_type函数需要平台提供一个针对硬件平台的实现函数

  static struct irqchip s3c_irqext_chip = {

  .mask = s3c_irqext_mask,

  .unmask = s3c_irqext_unmask,

  .ack = s3c_irqext_ack,

  .type = s3c_irqext_type

  };

  s3c_irqext_type就是内核需要的实现函数,而s3c_irqext_type在2.6.8中的实现为:

  static int s3c_irqext_type(unsigned int irq, unsigned int type)

  {

  irqdbf("s3c_irqext_type: called for irq %d, type %d", irq, type);

  return 0;

  }

  原来并没有实现。而在较高版本的内核,如2.6.26内核中,这个函数是实现了的。所以你一定要小心。当平台函数不好用时,一定要查查原因,或者直接操作硬件寄存器来达到目的。

  2.6内核设备模型对驱动的影响

  在2.6内核中写设备驱动和在2.4内核中有着很大的不同,就是在设备驱动中融入了比设备驱动本身结构还复杂,难以理解的设备模型。初学驱动时你可以不理会设备模型,但你会发现内核里的驱动代码基本上都是融入了设备模型的了。所以很多时候你不得不面对现实,还是要弄懂它,并且它也的注册方法也会随着内核的升级而发生变化。解决此类问题的最好方法还是参考目标内核驱动代码。

  总结:

  开始学习设备驱动时,选择一个当前比较流行的内核版本和硬件平台。不着急追赶最新潮流。这样你可以找到的网络资源会比较多,不至于有孤军奋战的感觉。我想这个过程应该不低于1年。当过了这个过程后,尝试将你编写过的驱动移植到各个目标平台上。上面的一些建议、和应对方法是本人的一些经验总结,仅供参考。

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux相关文章:linux教程



上一页 1 2 下一页

评论


相关推荐

技术专区

关闭