一、platform设备模型

从Linux 2.6起引入了一套新的驱动管理和注册机制,platform_device和platform_driver,Linux中大部分的设备驱动都可以使用这套机制。platform是一条虚拟总线。设备用platform_device表示,驱动用platform_driver进行注册,linux platform driver机制和传统的device driver机制(通过driver_register进行注册)相比,一个明显的优势在于platform机制将设备本身的资源注册进内核,由内核统一管理,在驱动中使用这些资源时通过platform device提供的标准结构进行申请并使用。这样提高了驱动和资源的独立性,并且具有较好的可移植性和安全性(这些标准接口是安全的)。当我们将设备和驱动注册到虚拟总线上(内核)时,会互相寻找一次对方。如果device和driver中的name这个字符串是想相同的话platform_bus就会调用driver中的.probe函数。设备和驱动的关系是多对一的关系,即多个相同设备可使用一个driver,靠device(设备)中的id号来区别。

通过platform机制开发底层驱动的大致流程为:

定义platform_deviece -->注册platform_device -->定义platform_driver --> 注册platform_driver。

二、注册platform_device

在内核源码中添加arch/arm/mach-s5pv210/include/mach/leds-gpio.h文件

/* arch/arm/mach-s5pv210/include/mach/leds-gpio.h** Copyright (c) 2006 Simtec Electronics*   http://armlinux.simtec.co.uk/*  Ben Dooks <ben@simtec.co.uk>** s5pv210 - LEDs GPIO connector** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License version 2 as* published by the Free Software Foundation.
*/#ifndef __ASM_ARCH_LEDSGPIO_H
#define __ASM_ARCH_LEDSGPIO_H "leds-gpio.h"#define S5PV210_LEDF_ACTLOW    (1<<0)        /* LED is on when GPIO low */
#define S5PV210_LEDF_TRISTATE   (1<<1)        /* tristate to turn off */struct s5pv210_led_platdata {unsigned int      gpio;unsigned int       flags;char         *name;char          *def_trigger;
};#endif /* __ASM_ARCH_LEDSGPIO_H */

在内核arch/arm/mach-s5pv210/mach-x210.c文件中添加如下代码

/* LEDS */
static struct s5pv210_led_platdata x210_led1_pdata = {.name        = "led1",.gpio       = S5PV210_GPJ0(3),.flags       = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct s5pv210_led_platdata x210_led2_pdata = {.name      = "led2",.gpio       = S5PV210_GPJ0(4),.flags       = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct s5pv210_led_platdata x210_led3_pdata = {.name      = "led3",.gpio       = S5PV210_GPJ0(5),.flags       = S5PV210_LEDF_ACTLOW | S5PV210_LEDF_TRISTATE,.def_trigger = "",
};static struct platform_device x210_led1 = {.name     = "s5pv210_led",.id      = 0,.dev       = {.platform_data  = &x210_led1_pdata,},
};static struct platform_device x210_led2 = {.name     = "s5pv210_led",.id      = 1,.dev       = {.platform_data  = &x210_led2_pdata,},
};static struct platform_device x210_led3 = {.name     = "s5pv210_led",.id      = 2,.dev       = {.platform_data  = &x210_led3_pdata,},
};static struct platform_device *smdkc110_devices[] __initdata = {...&x210_led1,&x210_led2,&x210_led3,
};

重新编译内核,三个led设备就会被注册到platform中,在/sys/bus/platform/devices中可以进行查看

三、注册platform_driver

#include <linux/module.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <mach/gpio.h>
#include <linux/platform_device.h>
#include <mach/leds-gpio.h>
#include <linux/slab.h>struct s5pv210_gpio_led {struct led_classdev        cdev;struct s5pv210_led_platdata   *pdata;
};static inline struct s5pv210_gpio_led *pdev_to_gpio(struct platform_device *dev)
{return platform_get_drvdata(dev);
}static inline struct s5pv210_gpio_led *to_gpio(struct led_classdev *led_cdev)
{return container_of(led_cdev, struct s5pv210_gpio_led, cdev);
}static void s5pv210_led_set(struct led_classdev *led_cdev, enum led_brightness value)
{struct s5pv210_gpio_led *led = to_gpio(led_cdev);struct s5pv210_led_platdata *pd = led->pdata;printk(KERN_INFO "s5pv210_led_set\n");/* 设置gpio状态 */if (value == LED_OFF)gpio_set_value(pd->gpio, 1);elsegpio_set_value(pd->gpio, 0);
}static int s5pv210_led_probe(struct platform_device *dev)
{struct s5pv210_led_platdata *pdata = dev->dev.platform_data;struct s5pv210_gpio_led *led;int ret = -1;printk(KERN_INFO "s5pv210_led_probe\n");led = kzalloc(sizeof(struct s5pv210_gpio_led), GFP_KERNEL);if (led == NULL) {dev_err(&dev->dev, "No memory for device\n");return -ENOMEM;}platform_set_drvdata(dev, led);/* 申请gpio资源 */if (gpio_request(pdata->gpio, pdata->name)){printk(KERN_ERR "gpio_request failed\n");return -EINVAL;}/* 设置gpio方向为输出 */gpio_direction_output(pdata->gpio, 1);led->cdev.name = pdata->name;led->cdev.brightness = 0;   led->cdev.brightness_set = s5pv210_led_set;led->pdata = pdata;/* 注册led设备 */ret = led_classdev_register(&dev->dev, &led->cdev);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}return 0;
}static int s5pv210_led_remove(struct platform_device *dev)
{struct s5pv210_gpio_led *led = pdev_to_gpio(dev);struct s5pv210_led_platdata *pd = led->pdata;/* 注销led设备 */led_classdev_unregister(&led->cdev);/* 释放gpio资源 */gpio_free(pd->gpio);kfree(led);return 0;
}static struct platform_driver s5pv210_led_driver = {.probe        = s5pv210_led_probe,.remove        = s5pv210_led_remove,.driver       = {.name       = "s5pv210_led",.owner       = THIS_MODULE,},
};static int __init s5pv210_led_init(void)
{return platform_driver_register(&s5pv210_led_driver);
}static void __exit s5pv210_led_exit(void)
{platform_driver_unregister(&s5pv210_led_driver);
}module_init(s5pv210_led_init);
module_exit(s5pv210_led_exit);// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");                            // 描述模块的许可证
MODULE_AUTHOR("lsm");                         // 描述模块的作者
MODULE_DESCRIPTION("s5pv210 led driver");     // 描述模块的介绍信息
MODULE_ALIAS("s5pv210_led");                  // 描述模块的别名信息

加载驱动之后,在/sys/bus/platform/drivers中可以进行查看

四、测试

加载好led驱动之后,进入/sys/class/leds

platform平台总线相关推荐

  1. Linux设备驱动模型3——platform平台总线工作原理

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 四.platform平台总线工作原理1 1.何为平台总线? (1)属于总线中的一种,相对于usb.pci.i2c等物理总线来说,platfo ...

  2. Linux设备驱动模型之platform(平台)总线详解

    /********************************************************/ 内核版本:2.6.35.7 运行平台:三星s5pv210 /*********** ...

  3. 【Kernel】驱动开发学习之Platform平台总线模型

    Platform平台总线模型 一.前言 二.注册Device文件 三.注册Driver文件 四.编写Probe函数 五.完整代码示例 驱动部分 应用部分 一.前言 平台总线模型也交platform总线 ...

  4. 正点原子linux阿尔法开发板使用——platform平台总线模型

    Linux驱动分离与分层 目的:为了提高软件的重用,跨平台性能!!! 控制器驱动和设备驱动分离!!! 将驱动分离:主机控制器驱动和设备驱动,主机控制器驱动一般是半导体厂家写的.在linux驱动框架下编 ...

  5. Linux设备驱动-platform虚拟总线dya01

    参考连接:https://www.cnblogs.com/deng-tao/p/6026373.html 参考书:<Linux设备驱动开发详解>宋宝华 根据参考资料和同事讨论总结. 摘要: ...

  6. platform平台驱动模型简述(linux驱动开发篇)

    此篇是驱动分离(总线.驱动和设备模型)的应用扩展,主要简述platform虚拟总线平台 一个现实的Linux设备和驱动通常挂接在一种总线上,对于本身依附于PCI.USB.I2C.SPI等的设备而言,这 ...

  7. platform平台工作原理

    平台总线体系的工作流程: 1.1 第一步:系统启动时在bus系统中注册platform 1.2 第二步:内核移植的人负责提供platform_device 1.3 第三步: 写驱动的人负责提供plat ...

  8. Linux设备驱动模型4——平台总线实践

    以下内容源于朱有鹏<物联网大讲堂>课程的学习,如有侵权,请告知删除. 参考http://www.cnblogs.com/deng-tao/p/6033571.html 一.平台总线实践环节 ...

  9. Platform平台设备驱动框架

    Platform 平台设备驱动框架 platform平台设备驱动是基于设备驱动模型的,它将总线结构体struct bus_type封装为struct bus_type platform_bus_typ ...

最新文章

  1. 在温系统下制作马克系统引导安装镜像启动U盘安装马克OS
  2. Vmware linux 无法上网
  3. linux 文本处理 awk 几个特殊的内置变量
  4. BindingException: Invalid bound statement (not found)问题排查:SpringBoot集成Mybatis重点分析...
  5. 爬取虎牙之三:通过json数据获取所有直播情况
  6. Python教程:序列的增量赋值
  7. 原型与原型链的简单理解
  8. jenkins X 和k8s CI/CD
  9. 亚马逊云科技成为Meta关键长期战略云服务提供商;触宝科技延伸业务布局聚焦元宇宙 | 全球TMT...
  10. 使用C++Test进行白盒测试
  11. matlab LSB算法的三种改进
  12. Python 函数的使用和内嵌函数
  13. 【转载】mysql语句写作顺序以及执行顺序
  14. Windows CMD 访问UCN路径
  15. 萝卜家园 Win XP 极速安装版 3.0
  16. 硕士研究生毕业计算机水平,计算机硕士毕业论文答辩自述
  17. web界面测试用例(shelley_shu)
  18. jstack详细介绍
  19. 想要从编程小白成为达人,这些你必须知道!(附STM32学习指南)
  20. 苹果开发者账号续费不成功的解决方案

热门文章

  1. 丘成桐中学计算机科学奖,丘成桐中学科学奖
  2. xp系统的WINS服务器设置,WindowsXP系统设置
  3. netcore 编译 html dll,ASP.NET Core Razor 视图预编译、动态编译
  4. HTML跳转为啥会404,为什么网页会出现404 not found?
  5. linux强制关机启动后是白屏,解决安装Ubuntu后,启动出现屏幕空白(全黑,无内容)...
  6. 深度linux magento,linux下安装magento
  7. python编辑器背景设置为黑色_VScode 配置为Python编辑器
  8. i2c通信 msp430g2553_msp430g2553的IIC通信
  9. linux下安装TensorFlow(centos)
  10. libevent的vs2013的源码工程 以及两个demo地址