1. 平台总线(Platform bus)是linux2.6内核加入的一种虚拟总线,其优势在于采用了总线的模型对设备(没有挂到真实总线的设备)与驱动进行了管理,这样提高了程序的可移植性。

2. 平台总线开发设备驱动流程

(1)定义平台设备

(2)注册平台设备

(3)定义平台驱动

(4)注册平台驱动

3. 平台设备使用struct platform_device来描述

struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
};

① name:设备名

② id:设备ID:配合设备名使用,以区分不同设备

③ dev:

④ num_resources:硬件资源个数

⑤ resource:硬件资源

struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};

(1) 注册平台设备:int platform_device_register(struct platform_device *pdev);

(2) 注销平台设备:void platform_device_unregister(struct platform_device *pdev);

4. 平台驱动使用struct platform_driver描述

struct platform_driver {
int (*probe)(struct platform_device *);
int (*remove)(struct platform_device *);
void (*shutdown)(struct platform_device *);
int (*suspend)(struct platform_device *, pm_message_t state);
int (*suspend_late)(struct platform_device *, pm_message_t state);
int (*resume_early)(struct platform_device *);
int (*resume)(struct platform_device *);
struct device_driver driver;
};

(1)平台驱动注册: int platform_driver_register(struct platform_driver *)

(2)平台驱动注销:void platform_driver_unregister(struct platform_driver *)

5. 简单示例

① PlatformKeyDevice.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h> MODULE_LICENSE("GPL"); #define GPGCON 0x56000060 void key_release(struct device *dev)
{
printk("dev->init_name = %s release!\n", dev->init_name);
} static struct resource key_resource[] = {
[] = {
.start = GPGCON,
.end = GPGCON + ,
.flags = IORESOURCE_MEM,
},
[] = {
.start = IRQ_EINT8,
.end = IRQ_EINT11,
.flags = IORESOURCE_IRQ,
},
[] = {
.start = IRQ_EINT13,
.end = IRQ_EINT14,
.flags = IORESOURCE_IRQ,
},
[] = {
.start = IRQ_EINT15,
.end = IRQ_EINT19,
.flags = IORESOURCE_IRQ,
},
}; struct platform_device key_device = {
.name = "my-key",
.id = ,
.dev = {
.init_name = "init_key",
.release = key_release,
},
.num_resources = ARRAY_SIZE(key_resource),
.resource = key_resource,
}; static int button_init(void)
{
platform_device_register(&key_device); return ;
} static void button_exit(void)
{
platform_device_unregister(&key_device);
} module_init(button_init);
module_exit(button_exit);

② PlatformKeyDriver.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h> MODULE_LICENSE("GPL"); struct timer_list buttons_timer; unsigned int key_num = ; wait_queue_head_t key_wait_queue; unsigned int *key_base = NULL; void buttons_timer_function(unsigned long data)
{
printk("keys_timer_function\n"); key_num = ; printk("data = %lx\n", data); switch(data)
{
case IRQ_EINT8:
key_num = ;
break; case IRQ_EINT11:
key_num = ;
break; case IRQ_EINT13:
key_num = ;
break; case IRQ_EINT14:
key_num = ;
break; case IRQ_EINT15:
key_num = ;
break; case IRQ_EINT19:
key_num = ;
break; default:
break;
} printk("key_num = %d\n", key_num); wake_up(&key_wait_queue);
} irqreturn_t key_int(int irq, void *dev_id)
{
//1. 检测是否发生了按键中断 //2. 清除已经发生的按键中断 //3. 提交下半部
buttons_timer.data = irq;
mod_timer(&buttons_timer, jiffies + (HZ /)); //return 0;
return IRQ_HANDLED;
} void key_hw_init(void)
{
unsigned int config_data; if(key_base != NULL)
{
config_data = readl(key_base);
config_data &= 0b001111110000001100111100;
config_data |= 0b100000001010100010000010; writel(config_data, key_base);
}
} int key_open(struct inode *node,struct file *filp)
{
return ;
} ssize_t key_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
{
wait_event(key_wait_queue, key_num); copy_to_user(buf, &key_num, ); key_num = ; return ;
} struct file_operations key_fops =
{
.open = key_open,
.read = key_read,
}; struct miscdevice key_miscdev = {
.minor = ,
.name = "key",
.fops = &key_fops,
}; int key_probe(struct platform_device *pdev)
{
int ret, size; struct resource *resources;
struct resource *resources_irq; ret = misc_register(&key_miscdev); if (ret != )
printk("register fail!\n"); //注册中断处理程序
resources_irq = platform_get_resource(pdev, IORESOURCE_IRQ, ); request_irq(resources_irq->start, key_int, IRQF_TRIGGER_LOW, "key1", );
request_irq(resources_irq->end, key_int, IRQF_TRIGGER_LOW, "key2", ); resources_irq = platform_get_resource(pdev, IORESOURCE_IRQ, ); request_irq(resources_irq->start, key_int, IRQF_TRIGGER_LOW, "key3", );
request_irq(resources_irq->end, key_int, IRQF_TRIGGER_LOW, "key4", ); resources_irq = platform_get_resource(pdev, IORESOURCE_IRQ, ); request_irq(resources_irq->start, key_int,IRQF_TRIGGER_LOW, "key5", );
request_irq(resources_irq->end, key_int,IRQF_TRIGGER_LOW, "key6", ); //按键初始化
resources = platform_get_resource(pdev, IORESOURCE_MEM, );
size = (resources->end - resources->start) + ;
key_base = ioremap(resources->start, size); key_hw_init(); /* 初始化定时器 */
init_timer(&buttons_timer);
buttons_timer.function = buttons_timer_function; /* 向内核注册一个定时器 */
add_timer(&buttons_timer); /*初始化等待队列*/
init_waitqueue_head(&key_wait_queue); return ;
} int key_remove(struct platform_device *pdev)
{
struct resource *resources_irq;
int i = ; printk("PlatformKeyDriver: key_remove!\n"); for(i = ; i <= ; i++)
{
resources_irq = platform_get_resource(pdev, IORESOURCE_IRQ, i); free_irq(resources_irq->start, );
free_irq(resources_irq->end, );
} iounmap(key_base);
misc_deregister(&key_miscdev); return ;
} static struct platform_driver key_driver = {
.probe = key_probe,
.remove = key_remove,
.driver = {
.owner = THIS_MODULE,
.name = "my-key",
},
}; static int button_init(void)
{
return platform_driver_register(&key_driver);
} static void button_exit(void)
{
platform_driver_unregister(&key_driver);
} module_init(button_init);
module_exit(button_exit);

Linux平台总线设备驱动的更多相关文章

  1. 芯灵思SinlinxA33开发板 Linux平台总线设备驱动

    1.什么是platform(平台)总线? 相对于USB.PCI.I2C.SPI等物理总线来说,platform总线是一种虚拟.抽象出来的总线,实际中并不存在这样的总线. 那为什么需要platform总 ...

  2. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

  3. Linux的总线设备驱动模型

    裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...

  4. Linux I2C总线设备驱动模型分析(ov7740)

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...

  5. Linux学习 : 总线-设备-驱动模型

    platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...

  6. Linux下 USB设备驱动分析(原创)

    之前做过STM32的usb HID复合设备,闲来看看linux下USB设备驱动是怎么一回事, 参考资料基于韦东山JZ2440开发板,以下,有错误欢迎指出. 1.准备知识 1.1USB相关概念: USB ...

  7. Linux和Windows设备驱动架构比较

    毕业后一直在学操作系统, 有时候觉得什么都懂了,有时候又觉得好像什么都不懂,但总体来说自认为对操作系统实现机制的了解比周围的人还是要多一些.去年曾花了几个星期的晚上时间断断续续翻译了这篇对Linux和 ...

  8. usb驱动开发4之总线设备驱动模型

    在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...

  9. 总线设备驱动模型---platform篇

    总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...

随机推荐

  1. Web测试-day

    昨天太忙忘了写博客,今天补上: 这两天完成的工作: 我们组选定了博客园和CSDN作为对比,进行Web测试. 胡俊辉--找到了10个网页的bug,并完成了bug记录文档,并且对CSDN和博客园进行功能分 ...

  2. 改善C#公共程序类库质量的10种方法(转)

    出处:http://www.cnblogs.com/JamesLi2015/p/3140897.html 最近重构一套代码,运用以下几种方法,供参考. 1  公共方法尽可能的使用缓存 public s ...

  3. Animation(动画效果)

    Ctrl+6打开Animation窗口.选择物体,点击录制,保存录制文件后即为给该物体添加了动画效果. Animation可以修改某时间点的物体位置.大小.材质球上的所有属性.碰撞器等等. 可以通过修 ...

  4. Python + HTMLTestRunner + smtplib 完成测试报告生成及发送测试报告邮件

    一下代码是自己结合教材,并结合以往用到的实例编写的代码,可以做为参考 import smtplib from email.mime.text import MIMEText from email.mi ...

  5. Python下载网页图片

    有时候不如不想输入路径,那就需要用os模块来修改当前路径 下面是从其他地方看到的一个例子,就是把图片url中的图片名字修改,然后就可以循环保存了,不过也是先确定了某个url 来源:http://www ...

  6. js webstrom中svn的配置及使用

    js  webstorm中svn的配置及使用 一.webstorm配置svn: 1.在webstorm工具中找到file(文件)-setting(设置)菜单按钮: 2.在左边菜单中找到plus(插件) ...

  7. Redis!

    在安装redis完成时,使用windows管理redis工具时(例如RedisDesktopManager)时出现连接不上的问题时 ping一下你的ip 和 talnet ip  看看通不通. 如果不 ...

  8. BF、kmp算法

    第七周 字符串匹配 BF算法,kmp算法 BF:时间复杂度为 O(m*n) int Index_BF(SString S, SString T, int pos) { ; while (i <= ...

  9. 多线程DP

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  10. img标签中onerror用法

    <img src="/statics/bazi/images/150x100.jpg" alt="#" onerror="this.style. ...