linux驱动分离分层的概念

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

这次先上代码在解释整体构架。

devic.c

#include <linux/module.h>
#include <linux/version.h>#include <linux/init.h>#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>static void led_release(struct device * dev)
{
}static struct resource led_resource[] = {[0] = {.start = 0x56000010,             /* TQ2440的LED是GPB5,6,7,8, GPBCON地址是0x56000010 */.end   = 0x56000010 + 8 - 1,.flags = IORESOURCE_MEM,},[1] = {.start = 5,                      /* LED1 */.end   = 5,.flags = IORESOURCE_IRQ,}
};//首先要声明这么一个结构体   并且填充里面的一些东西     name是很重要的  
//它是两个文件相互匹配的依据 第二总要的就是resource 这个是声明你的硬件资源的
static
struct platform_device led_dev = {.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(&led_dev);return 0; }static void led_dev_exit(void) {platform_device_unregister(&led_dev);return ; }module_init(led_dev_init); module_exit(led_dev_exit); MODULE_LICENSE("GPL");

 

 

drive.c

#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 struct class *cls;
static struct class_device    *dev;
static volatile unsigned long *gpio_con;
static volatile unsigned long *gpio_dat;
static int pin;
int major;static int led_open(struct inode *inode, struct file *file)
{*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;//printk("first_drv_write\n");
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)
{printk("led_probe!\n");/*从这里获取在dev文件里面注册的资源*/struct resource * res;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;/*回到前面的驱动程序,注册字符设备驱动程序*/major = register_chrdev(0, "myled", &led_fops);cls = class_create(THIS_MODULE, "myled");dev = class_device_create(cls, NULL, MKDEV(major, 0), NULL, "led");return 0;
}static int led_remove(struct platform_device *pdev)
{printk("led_remove!\n");class_device_unregister(dev);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);return ; }module_init(led_drv_init); module_exit(led_drv_exit);MODULE_LICENSE("GPL");


首先  这个模型是依赖于内核里面的platform.c这个文件的。

和输入子系统相比    这个模型的两边都要我们自己写。

先看看device这边,这边全部都是与硬件相关的代码。

我们可以看到  这个文件主要就是声明了一个结构体  然后填充结构体里面的一些值

最重要的就是两个东西   一个name 一个就是resource

填充完了之后告诉给这个模型的老大     也就是platform.c这个文件啦  

 

再看drive这边。  drive这边也填充了一个结构体  并且向老大注册了这个结构体(platform_driver)

我们知道   如果匹配两边的name匹配上了之后就会调用drive里面的led_probe 函数

在看看led_probe函数:

在里面取出了再device那边注册的硬件资源   然后再做各种处理 

余下的就和一般的驱动程序没什么区别啦

 

这说的也是一点皮毛   要深入的了解还是要看内核的代码   :

platform.c

 

转载于:https://www.cnblogs.com/pslfree/p/3355531.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IOS-企业开发人员账号amp;邓白氏码申请记录

Apple开发人员账号分三种&#xff0c;个人。公司&#xff0c;还有企业。个人和公司都称为标准账号。另一种是教育机构的账号。 账号介绍 个人和公司的就不说了。如今仅仅说企业账号 首先是申请企业账号的地址&#xff1a; https://developer.apple.com/programs/ios/enterpri…

wordpress置顶文章调用与设置

文章来源: https://www.xuewangzhan.net/wpbbs/15737.html wordpress网站后台允许我们设置一些置顶文章&#xff0c;然后通过调用置顶文章的代码把它调用到自己的网站前台。 下面是最常用的wordpress调用置顶文章代码&#xff0c;适用于所有模板使用。 <?php $sticky g…

【联盛德W806上手笔记】六、7816/UART 控制器

目录7816/UART 控制器串口功能7816 接口功能下载口库函数函数参数宏Demo中的测试程序main.cwm_hal_msp.cwm_it.cfifo.cfifo.hWindows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》 7816/UART 控制器 设备端…

数据库去重查询问题详解

预算2014年院线预算 影城&#xff08;多选&#xff09;北京CBD影城 查询 科目蚌埠万达广场店北京CBD影城  营业收入11 票房收入11 卖品收入00 逾期收入00 广告收入00 映前广告00 LCD广告00 阵地收入00 IMAX广告收入00 其他广告收入00 其…

MySQL5.7更改用户名密码

ALTER USER test% IDENTIFIED BY 123456; https://www.cnblogs.com/paul8339/p/9054497.html 更改用户名密码&#xff0c;官方推荐使用alter ALTER USER test% IDENTIFIED BY 123456; 还有一种 update mysql.user set authentication_stringpassword("新密码") …

python 装饰器 三 (带有参数的装饰器)

#接受装饰器的参数def deco_arg(deco_arg):#接受函数 此列为func1def deco_func(*argv,**kwag):#接受函数的方法 此列为 a bdef _deco_func(*argv,**kwarg):print "before -------执行函数前"print "%s -------打印装饰器的参数"% deco_argret deco_f…

jQuery、jQury UI、jQuery Mobile----读书笔记

<!DOCTYPE html> <html> <head><meta charset"utf-8"> <meta name keywords content""> <meta name descriptioon content“jQuery、jQury UI、jQuery Mobile”> <title>jQuery、jQury UI、jQuery …

【联盛德W806上手笔记】七、I2C

目录WM_SDK_W806_v0.6.0的库函数函数参数宏应用示例初始化使用测试I2C 控制器功能概述主要特性功能描述传输速率选择中断及启动停止可控快速输出及检测信号寄存器描述寄存器列表时钟分频寄存器_1时钟分频寄存器_2控制寄存器数据寄存器收发控制寄存器TXR 读出寄存器CR 读出寄存器…

WordPress如何获取文章所属分类ID、名称或别名?

https://boke112.com/bkwd/4269.html 在 wordpress 主题制作过程中&#xff0c;我们可能会经常用到当前分类 ID&#xff0c;如&#xff1a;在文章页获取该文章分类下的相关文章&#xff0c;这时就可能用到当前分类 ID&#xff0c;即当前文章所在的分类 ID。那么&#xff0c;wor…

【联盛德W806上手笔记】八、SPI及其DMA

目录高速 SPI 设备控制器库函数函数参数宏应用示例初始化引脚复用中断相关使用注意事项DataAlignmentDirection测试main.cwm_hal_msp.cwm_it.c其他改动实验现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书…

安装配置 radicale

为什么80%的码农都做不了架构师&#xff1f;>>> 可以直接pip安装,也可以下载源码安装,如果要存储到sql里面,则需要下载源码包,用里面的schema.sql 建表 默认安装后没有相应的配置文件,源码包里面也包含了 logging 和config,放到/etc/radicale 下 安装没什么说的,下…

散分,并如何判断时间段上有重叠冲突。

比如某个会议室的预订信息表 roomBookInfo(id,title,beginTime,endTime), 现在有一个新的预订请求 bTime, eTIme 分别 代表 开始、结束时间。请检查下表中的记录&#xff0c;查看是否有时间上的冲突。create table roomBookInfo (id int auto_increment primary key, title var…

wordpress 根据文章ID获取分类ID和标签ID

//wordpress 根据文章ID获取分类ID $categoryget_the_category( $post_ID ); $catid$category[0]->term_id; //wordpress 根据文章ID获取标签ID $tagswp_get_post_tags( $post_ID ); $tagid$tags[0]->term_id; 查看完整内容&#xff1a;http://web.zhaicool.net/366…

实现复选框的单选效果

<!DOCTYPE><html><head><title>实现复选框的单选效果</title></head><body><form methodpost action""><input type"checkbox" name"aa" οnclick"bb(this)"><input type&q…

【联盛德W806上手笔记】九、DMA

目录DMA 控制器功能概述功能描述DMA 通道DMA 数据流DMA 循环模式DMA 传输模式DMA 外设选择DMA 链表模式DMA 中断中断请求库函数函数参数宏应用Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 摘自《W806 MCU 芯片规格书 V2.0》、《WM_W800_寄存器手册 V2.1》 DMA 控制…

MySql创建一个存储过程

MySQL 存储过程是从 MySQL 5.0 新功能。存储过程的长处有一箩筐。只是最基本的还是运行效率和SQL 代码封装。特别是 SQL 代码封装功能&#xff0c;假设没有存储过程&#xff0c;在外部程序訪问数据库时&#xff08;比如 PHP&#xff09;&#xff0c;要组织非常多 SQL 语句。特别…

attr与prop的区别

我们在获取checked属性值的时候&#xff0c;如果被选中则值为"checked"没选中获取值就是undefined. &#xff08;引述他人&#xff09;因为在有些浏览器中比如说只要写disabled&#xff0c;checked就可以了&#xff0c;而有的要写成disabled "disabled"&a…

定制化WordPress后台的6个技巧

WordPress后台并非千篇一律&#xff0c;你可以通过一些代码定制化一个你喜欢的后台&#xff0c;本文所述代码都应写在主题的functions.PHP中。 移除后台某些菜单 如果你不想客户因为点了错误的菜单选项而删除付费主题&#xff0c;或者搞乱后台的设置&#xff0c;那么把你不希望…

SNF快速开发平台MVC-自由排序组件

1. 自由排序功能使用 在一些需要排序优先级的数据进行调整处理&#xff0c;如民族数据&#xff0c;在北方实施的时候汉族比较多&#xff0c;希望把汉族放在第一位。在蒙古实施项目时&#xff0c;蒙古族人最多把蒙古族放在第一选择位。 1.1. 效果展示 图 1.1 1.2. …

Tip:强制执行exchange DAG节点之间的数据库副本移动

当exchange后端服务器MBX的小版本号不一致&#xff0c;比如都是exchange 2010 SP3 RU8的版本&#xff0c;但是小版本号不一致&#xff0c;这个时候我们去运行平衡exchange DAG分布的脚本的时候&#xff0c;低版本服务器上面的DAG数据库可能无法正常转移到优选节点&#xff0c;这…