bus_drv_dev模型:功能改写只需改dev硬件代码即可,drv不需改写。

LED例子

下面用一个点亮LED的例子来说明这个分离的的例子:

led_dev.c  定义这个平台设备的资源:

static struct resource led_resource[] = {

   [0] = {

    .start  = 0x56000010,  //GPFCON的物理地址

     .end    = 0x56000010 + 8 - 1,

      .flags  = IORESOURCE_MEM,

    },

   [1] = {

     .start  = 6,// F6引脚

    .end    = 6,

     .flags  = IORESOURCE_IRQ,

    },

};

定义一个平台设备:

struct platform_device device_led = {

    .name       = "myled",

    .id         = -1,

     .num_resources  = ARRAY_SIZE(led_resource),

     .resource       = led_resource,

     .dev={

         .release = led_release,

    },

};

在入口函数中 注册 这个 “平台设备”

static int led_dev_init(void)

{

   platform_device_register(&device_led);

   return 0;  
}

出口函数是卸载这个平台设备

static void led_dev_exit(void)

{

   platform_device_unregister(&device_led);

}

led_drv.c  定义一个平台driver

static struct platform_driver led_drv = {

.probe      = led_probe,

.remove     = led_remove,

.driver     = {

   .name   = "myled",

      }

};  

这里需要注意的是这个平台的name和dev的平台设备的名字要一致。如果平台设备和平台driver匹配的上,就会调用这个led_driver这个函数。

/* 分配/设置/注册一个platform_driver */

#include <linux/module.h>
#include <linux/version.h>

#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>

static int major;

static struct class *cls;
static volatile unsigned long *gpio_con;
static volatile unsigned long *gpio_dat;
static int pin;

static int led_open(struct inode *inode, struct file *file)
{
//printk("first_drv_open\n");
/* 配置为输出 */
*gpio_con &= ~(0x3<<(pin*2));
*gpio_con |= (0x1<<(pin*2));
return 0;
}

static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int val;

copy_from_user(&val, buf, count); // copy_to_user();

if (val == 1)
{
// 点灯
*gpio_dat &= ~(1<<pin);
}
else
{
// 灭灯
*gpio_dat |= (1<<pin);
}

return 0;
}

static struct file_operations led_fops = {
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = led_open,
.write = led_write,
};

static int led_probe(struct platform_device *pdev)
{
struct resource *res;

/* 根据platform_device的资源进行ioremap */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
gpio_con = ioremap(res->start, res->end - res->start + 1);
gpio_dat = gpio_con + 1;

res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
pin = res->start;

/* 注册字符设备驱动程序 */

printk("led_probe, found led\n");

major = register_chrdev(0, "myled", &led_fops);

cls = class_create(THIS_MODULE, "myled");

class_device_create(cls, NULL, MKDEV(major, 0), NULL, "led"); /* /dev/led */

return 0;
}

static int led_remove(struct platform_device *pdev)
{
/* 卸载字符设备驱动程序 */
/* iounmap */
printk("led_remove, remove led\n");

class_device_destroy(cls, MKDEV(major, 0));
class_destroy(cls);
unregister_chrdev(major, "myled");
iounmap(gpio_con);

return 0;
}

struct platform_driver led_drv = {
.probe = led_probe,
.remove = led_remove,
.driver = {
.name = "myled",
}
};

static int led_drv_init(void)
{
platform_driver_register(&led_drv);
return 0;
}

static void led_drv_exit(void)
{
platform_driver_unregister(&led_drv);
}

module_init(led_drv_init);
module_exit(led_drv_exit);

MODULE_LICENSE("GPL");

这个驱动程序分为左右两边,即dev与drv,在led_dev.中分配,设置,注册一个platform_device,在led_drv中分配,设置,注册一个platform_driver。

linux驱动的分离分层概念之LED的更多相关文章

  1. Linux驱动之平台设备驱动模型简析(驱动分离分层概念的建立)

    Linux设备模型的目的:为内核建立一个统一的设备模型,从而有一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要 ...

  2. Linux驱动之内核自带的S3C2440的LCD驱动分析

    先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...

  3. linux驱动分离分层的概念

    这个分离分层的概念和输入子系统有点像,但不是完全一样的.为什么会再弄一个这个模型出来我也没有搞懂,现在我的学习还停留在把知识学懂的层面上.至于为什么会产生这种知识,现在我还无从解释,还需时日成长. 这 ...

  4. linux驱动分层分离思想

    转:https://blog.csdn.net/zqixiao_09/article/details/51088887 前面我们学习I2C.USB.SD驱动时,有没有发现一个共性,就是在驱动开发时,每 ...

  5. 四、分离分层的 platform驱动

    学习目标: 学习实现platform机制的分层分离,并基于platform机制,编写led设备和驱动程序: 一.分离分层 输入子系统.usb设备比驱动以及platform类型的驱动等都体现出分离分层机 ...

  6. 超简单易用的 “在 pcduino 开发板上写 Linux 驱动控制板载 LED 的闪烁”

    版权声明:本文为博主原创文章,未经博主同意不得转载.转载联系 QQ 30952589,加好友请注明来意. https://blog.csdn.net/sleks/article/details/251 ...

  7. 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  8. 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  9. Linux驱动之LED驱动编写

    从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...

随机推荐

  1. performSelector和performSelectorInBackground

    前者是在主线程下完成的, 不会自动创建一个线程. 后者会创建一个新的线程.

  2. TEA,XXTEA介绍,对称加密

    总结:在使用加密的时候,我们可以加入随机数,这样相同的明文,每次加密后得到不同的密文,同时可以在密文中加入密文有效期,控制密文的有效时间长度. 针对有的功能扩展使用,很好的思想. TEA对 64 位数 ...

  3. MySql学习(二) —— where / having / group by / order by / limit 简单查询

    注:该MySql系列博客仅为个人学习笔记. 这篇博客主要记录sql的五种子句查询语法! 一个重要的概念:将字段当做变量看,无论是条件,还是函数,或者查出来的字段. select五种子句 where 条 ...

  4. MongoDB 驱动以及分布式集群读取优先级设置

    本文主要介绍使用MongoDB C驱动读取分布式MongoDB集群时遇到的坑,主要在读取优先级和匹配tag上:同时简单介绍Python驱动.Node.js驱动.Mongoose驱动如何使用读取优先级和 ...

  5. IOS跳转到设置特定项

    App如何跳转到系统Settings 标签: IOS开发App转到Settings 2015-12-04 15:56 550人阅读 评论(1) 收藏 举报  分类: IOS开发(21)  版权声明:本 ...

  6. ASCII、UNICODE、UTF-8等关系

    参考如下: 网址1:http://blog.csdn.net/lx697/article/details/5914417 网址2:http://www.php100.com/html/it/bianc ...

  7. spider_text

    __author__ = 'sus'import urllibimport urllib2import re def getPage(url):        #获取网页 request = urll ...

  8. hdoj 5124lines

    题意:给你n条线段,求被最多的线段覆盖的点被覆盖的次数 解法:我们可以将一条线段[xi,yi]分为两个端点xi和(yi)+1,在xi时该点会新加入一条线段,同样的,在(yi)+1时该点会减少一条线段, ...

  9. VBA续嘘嘘

    什么是VBA?它有什么作用? A.实现Excel中没有实现的功能. B.提高运行速度. C.编写自定义函数. D.实现自动化功能. E.通过插入窗体做小型管理软件. VBA在哪里存放的?怎么运行? A ...

  10. struts文件上传、文件下载

    文件上传 如果在表单中上传文件,表单的enctype属性为multipart/form-data struts默认上传文件大小为2M,如果需要修改,在配置文件中设置 <constant name ...