linux驱动的分离分层概念之LED
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的更多相关文章
- Linux驱动之平台设备驱动模型简析(驱动分离分层概念的建立)
Linux设备模型的目的:为内核建立一个统一的设备模型,从而有一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要 ...
- Linux驱动之内核自带的S3C2440的LCD驱动分析
先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...
- linux驱动分离分层的概念
这个分离分层的概念和输入子系统有点像,但不是完全一样的.为什么会再弄一个这个模型出来我也没有搞懂,现在我的学习还停留在把知识学懂的层面上.至于为什么会产生这种知识,现在我还无从解释,还需时日成长. 这 ...
- linux驱动分层分离思想
转:https://blog.csdn.net/zqixiao_09/article/details/51088887 前面我们学习I2C.USB.SD驱动时,有没有发现一个共性,就是在驱动开发时,每 ...
- 四、分离分层的 platform驱动
学习目标: 学习实现platform机制的分层分离,并基于platform机制,编写led设备和驱动程序: 一.分离分层 输入子系统.usb设备比驱动以及platform类型的驱动等都体现出分离分层机 ...
- 超简单易用的 “在 pcduino 开发板上写 Linux 驱动控制板载 LED 的闪烁”
版权声明:本文为博主原创文章,未经博主同意不得转载.转载联系 QQ 30952589,加好友请注明来意. https://blog.csdn.net/sleks/article/details/251 ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- Linux驱动之LED驱动编写
从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...
随机推荐
- jfinal基本应用 --报主键重复
在使用jfinal 的Model过程中有一个很怪异的问题,发布到服务器上,只要是往表中添加字段,就报主键重复. 1.我添加表的时候调用了 public void create(Map map){ St ...
- iOS沙盒(sandbox)
iOS沙盒 每个ios应用都有自己的应用沙盒,应用沙盒就是文件系统目录,默认下iOS应用只能访问自己的沙盒 extenaion是iOS8新开放的一种对几个固定系统区域的扩展机制,它可以在一定程度上弥补 ...
- ecshop后台新功能及权限的添加
1.在后台"推荐管理"里添加"推荐人分成"."会员分成"两个操作功能以及权限 index.php?act=menu incluedes/in ...
- Java面试常见各种概念区别比较
Hashtable 和 HashMap之间的区别 Hashtable是继承了Dictionary,是线程安全的.HashMap实现了Map接口,不是线程安全的.HashMap是Hashtable的轻量 ...
- 立体角的单位——立体弧度(sr)
国际单位制(SI)中,关于物理量 发光强度 的介绍: 1cd(坎德拉)为一光源在给定方向的发光强度,该光源发出频率为540×1012Hz(赫兹)的单色辐射,且在此方向上的辐射强度为 1/683 W/s ...
- 腾讯的一道JavaScript面试题
//题目:分别弹出什么内容? <!-- function test(){ this.a = 1; alert(this); //[object Window] } test(); var t = ...
- 用HTML做的简单的个人简历
<html> <head> <title>table表格</title> <style type="text/css"> ...
- 面试复习(C++)之直接选择排序
#include <iostream> using namespace std; void Selection(int *a,int len) { ;i<len;i++) { int ...
- ubuntu关于apache服务命令
一.Start Apache 2 Server /启动apache服务 # /etc/init.d/apache2 startor$ sudo /etc/init.d/apache2 start 二. ...
- Basic linux command
1. useradd 解释:添加新用户,在/etc/password文件中添加一行记录. 参数: -g 用于添加账户时指定该账户的私有组,如果不指定-g参数,useradd命令会自动创建与该用 ...