Chinaunix首页 | 论坛 | 博客
  • 博客访问: 218909
  • 博文数量: 39
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 584
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-18 20:24
个人简介

学习总结,分享快乐。 望指正错误, 共同提高!!!

文章分类

全部博文(39)

分类: 嵌入式

2015-06-08 15:12:22

0>目标:

接合上一篇,学习platform框架。



Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1>总线:内核已创建好


点击(此处)折叠或打开

  1. /*platform总线抽象*/

  2. /*drivers/base/platform.c*/

  3. struct bus_typeplatform_bus_type= {

  4.         .name ="platform",//总线注册后新建目录sys/bus/platform

  5.         .match = platform_match,//指定配对函数

  6. };


点击(此处)折叠或打开

  1. static intplatform_match(struct device *dev, struct device_driver *drv)
  2. {

  3.         struct platform_device *pdev = to_platform_device(dev);
  4.         struct platform_driver *pdrv = to_platform_driver(drv);


  5. /*很少用*/
  6.         if (of_driver_match_device(dev, drv))
  7.             return 1;


  8. /*通过id_table匹配*/
  9.         if (pdrv->id_table)
  10.                 return platform_match_id(pdrv->id_table, pdev) != NULL;


  11. /*通过名字匹配*/
  12.             return (strcmp(pdev->name, drv->name) == 0);

  13. }


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

2>设备:


点击(此处)折叠或打开

  1. struct platform_device {

  2. const char* name;     //设备的名字,用作sys/device下显示的目录名

  3. intid;    //设备id,用于给插入给该总线并且具有相同name的设备编号,如果只有一个设备的话填-1。

  4. struct devicedev;    //结构体中内嵌的device结构体。还是这个方法

  5. u32 num_resources;    //资源数。

  6. struct resource * resource;     //用于存放资源的数组。

  7. }

/*linux/ioport.h"*/

点击(此处)折叠或打开

  1. structresource {

  2.         resource_size_t start;
  3.         resource_size_t end;

  4.         const char *name;

  5.         unsigned long flags;

  6.         struct resource *parent, *sibling, *child;
  7. };

瞧:内核抽象的设备结构体可以包罗万象,解决了上篇留下的思考。

常用的就是红色标记的三个,分别是资源的开始值,结束值和类型。

常见的flags有IORESOURCE_MEM和IORESOURCE_IRQ。其他的可以自己查看include/linux/ioport.h

如果fiags为IORESOURCE_MEM,start和end分别是该设备的连续的开始和结束地址,如果不连续你可以定义两个或者更多的资源结构体。

如果flags为IORESOURCE_IRQ,start和end分别是该设备连续的开始和结束的连续中断号,如果不连续可以分开定义。

当然,如果地址或者中断只有一个,你可以将start和end定义成一样。


/*注册与移出设备暂不深究,假想为与上篇相同*/

int platform_device_register(struct platform_device *pdev);

void platform_device_unregister(struct platform_device *pdev)



XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

3>驱动:


点击(此处)折叠或打开

  1. /*platform驱动的类型*/

  2. structplatform_driver{

  3. int(*probe) (structplatform_device*);    //添加自己probe();最终调这个。

  4. int(*remove) (structplatform_device*);

  5. void(*shutdown) (structplatform_device*);


  6. structdevice_driverdriver;     //嵌入标准的驱动结构体,又是这种方法。

  7. };





点击(此处)折叠或打开

  1. static int platform_drv_probe(struct device *_dev)

  2. {

  3. struct platform_driver *drv = to_platform_driver(_dev->driver);

  4. struct platform_device *dev = to_platform_device(_dev);


  5. return drv->probe(dev);      //调自己的probe()

  6. }



点击(此处)折叠或打开

  1. /*驱动注册*/

  2. int platform_driver_register(struct platform_driver *drv)
  3. {

  4.         drv->driver.bus = &platform_bus_type;//绑定总线

  5.         if (drv->probe)   //上1篇没写判断,还是内核考虑周全。

  6.                     drv->driver.probe = platform_drv_probe;

  7.         if (drv->remove)

  8.                     drv->driver.remove = platform_drv_remove;

  9.         if (drv->shutdown)

  10.                     drv->driver.shutdown = platform_drv_shutdown;


  11.         return driver_register(&drv->driver);           //调标准的驱动注册

  12. }


  13. /*移除驱动*/
  14. void platform_driver_unregister(struct platform_driver *drv)
  15. {

  16.             driver_unregister(&drv->driver);

  17. }



与上一篇我们模仿的一个样。

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx



阅读(2049) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~