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);

最新文章

  1. 【兼容写法】HttpServerUtility.Execute 在等待异步操作完成时被阻止。关键词:MVC,分部视图,异步
  2. phpinfo有mysqlnd没有mysql
  3. C语言的基本输入与输出函数(全解)
  4. JS中级 - 03:文档宽高及窗口事件(选)
  5. JAVA多线程实现的四种方式
  6. C# MD5加密的方法+一般处理程序使用Session+后台Json序列化
  7. 修改Broforce无限人数,死亡不减反加
  8. Iterator&lt;转&gt;
  9. 前端开发与Seo基础
  10. Android Activity 阻止软键盘自动弹出
  11. SelectionKey理解(总结)
  12. 解决Sublime Text 3中文显示乱码(tab中文方块)问题,sublime tab乱码
  13. sonarqube6.7部署文档
  14. python可以提高程序执行速度N倍你知道吗?
  15. MySQL修改编码为UTF-8无效果解决办法
  16. eclipse 把鼠标指针放在错误的语句上 提示快速修正 不见了的解决方法
  17. linux 《vmware下克隆的centos无法配置固定ip》
  18. 8 -- 深入使用Spring -- 3...1 Resource实现类InputStreamResource、ByteArrayResource
  19. 成为java高级程序员需要掌握哪些
  20. 用python开发了一个简单apache web服务端范例,在win10 + apache2.4.9 + python3.5 测试成功

热门文章

  1. [原创]升级SOUI WKE以支持_blank
  2. Smarty配置与实例化
  3. mysql json格式数据处理
  4. org.springframework.beans.factory.BeanCreationException: Error creating bean with name &#39;deptDao_a&#39; defined in class path resource [beansAndHibernate.xml]: Cannot resolve reference to bean &#39;sessionFact
  5. 编写高质量代码改善C#程序的157个建议——建议90:不要为抽象类提供公开的构造方法
  6. ACM 韩信点兵 、n的另一种阶乘、6174的问题
  7. SOAP协议初级指南 (一)
  8. poj2480——Longge&#39;s problem(欧拉函数)
  9. bootstrap css排版
  10. Java集合框架(Collection Framework)学习之 HashMap