Linux驱动开发之platform设备驱动实验【完整教程】

为了方便驱动的编写,提高软件的重用性和跨平台性能,于是就提出了Linux驱动的分离和分层

  驱动的分层,分层的目的时为了在不同的层处理不同的内容,最简单的驱动分层是input子系统负责管理所有跟输入有关的驱动、最底层的就是设备原始驱动,负责获取输入设备的原始值,获取到的输入时间上报给input核心层。input核心层会处理各种IO模型,并且提供file_operations操作集合。
                  input核心层----提供统一的框架
                    👆
                   input层
                    👆
                  最底层(设备原始驱动)----不同的设备使用统一的框架

根据驱动的分离和分层衍生出总线–驱动–设备驱动框架。总线代码由Linux内核提供。当向总线注册驱动的时候,会检测当前总线下的所有设备有没有和此驱动匹配的设备,如果有,就会执行probe函数(probe函数需要我们自己编写)。如果先安装设备就设备去找驱动,如果先安装驱动就驱动去找设备。

  

platform

  Linux内核提供了一个虚拟总线:platform。相应的就有platform_driver 和 platform_device。
platform驱动就是platform_driver。这个属于一个结构体,定义在include/linux/platform_device.h

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 (*resume)(struct platform_device *);
	struct device_driver driver;
	const struct platform_device_id *id_table;
	bool prevent_deferred_probe;
};

结论:向内核注册platform驱动的时候,如果驱动和设备匹配成功,最终会执行platform_driver的probe函数 ,无设备树的时候,此时需要驱动开发人员编写设备注册文件,使用platform_device_register函数注册设备;有设备树时,只需要修改设备树的设备节点即可。

platform的匹配过程:platform总线下的match就是platform_mach函数。

无设备树设备驱动框架编写:

本来打算把点灯的功能加上的,但是再把点灯的步骤加上去会导致文章过于冗杂,于是设备文件中有点灯的代码,但是驱动文件中没有写上去。

1.搭建好基本的框架,这里就用到以前所需要的头文件

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/platform_deivce.h>

/*设备加载*/
static int __init leddevice_init(void)
{
   
	return 0;
}
/*设备卸载*/
static void __exit leddevice_exit(void)
{
   

}

module_init(leddevice_init);
module_exit(leddevice_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kong");

2.添加一个空的设备结构体,并且在设备加载和卸载中执行platform的注册和注销

static struct platform_device leddevice = {
   

};

/*设备加载*/
static int __init leddevice_init(void)
{
   
	/*注册platform设备*/

	return platform_device_register(&leddevice);
}
/*设备卸载*/
static void __exit 
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拼个世界给自己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值