首页 > 系统相关 >fmql之Linux设备驱动框架

fmql之Linux设备驱动框架

时间:2024-10-09 14:19:52浏览次数:15  
标签:led struct 框架 fmql cdev Linux myled include data

设备驱动框架

正点原子第39章---LED驱动框架

 

 

 

 

测试

成功:

贴代码

(不需要测试APP)

/***************************************************************
 Copyright © ALIENTEK Co., Ltd. 1998-2029. All rights reserved.
 文件名    : leds-atk.c
 作者      : Skylar
 版本      : V1.0
 描述      : LED设备驱动框架
 其他      : 
 论坛      : www.openedv.com
 日志      : 初版V1.0 2024/10/8 创建
 ***************************************************************/

#include <linux/module.h>
#include <linux/of_gpio.h>
// #include <linux/cdev.h>
// #include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/leds.h>

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <linux/kern_levels.h>

#define MYLED_CNT   1
#define MYLED_NAME  "myled"

struct myled_data {
/*	
	dev_t		devid;
	struct		cdev cdev;
	struct		class *class;
	struct		device *device;
	int			led_gpio;
*/
	struct led_classdev cdev;
	int gpio;
};

/* 静态内敛函数
 * @ 通过struct myled_data结构体中的cdev变量的地址,
 *   得到struct myled_data结构体变量的地址
 * @ led_cdev: struct myled_data结构体中的cdev变量的地址
 * @ 执行成功返回struct myled_data结构体变量的地址
 */
static inline struct myled_data * cdev_to_led_data(struct led_classdev *led_cdev)
{
	return container_of(led_cdev, struct myled_data, cdev);
}

/* LED相关初始化操作
 * @ pdev: struct platform_device指针
 * 		   platform设备指针
 * @ 成功返回0,失败返回负数
 */
static int myled_init(struct platform_device *pdev)
{
	struct myled_data *led_data = platform_get_drvdata(pdev);
	struct device *dev = &pdev->dev;
	int ret;

	led_data->gpio = of_get_named_gpio(dev->of_node, "led-gpio", 0);
	if(!gpio_is_valid(led_data->gpio)){
		dev_err(dev, "Failed t oget gpio");
		return -EINVAL;
	}

	ret = devm_gpio_request(dev, led_data->gpio, "fmql-led Gpio");
	if(ret){
		dev_err(dev, "Failde to request gpio");
		return ret;
	}

	gpio_direction_output(led_data->gpio, 0);

	return 0;
}

/* 设置LED的亮度
 * @ 不可休眠
 * @ led_cdev: struct led_classdev类型的指针
 * @ 无返回值
 */
static void myled_brightness_set(struct led_classdev *led_cdev,
								enum led_brightness value)
{
	struct myled_data *led_data = cdev_to_led_data(led_cdev);
	int level;

	if(value == LED_OFF)
		level = 0;
	else
		level = 1;
	
	gpio_set_value(led_data->gpio, level);
}

/* 设置LED亮度
 * @ 可以休眠
 * @ led_cdev: struct led_classdev类型指针
 * @ value: 亮度值
 * @ 无返回值
 */
static int myled_brightness_set_blocking(struct led_classdev *led_cdev,
						enum led_brightness value)
{
	myled_brightness_set(led_cdev, value);
	return 0;
}

/* platform驱动的probe函数
 * @ 当驱动与设备匹配成功后此函数会执行
 * @ pdev: platforme设备指针
 * @ 成功返回0, 失败返回负值
 */
static int myled_probe(struct platform_device *pdev)
{
	struct myled_data *led_data;
	struct led_classdev *led_cdev;
	int ret;

	dev_info(&pdev->dev, "Led driver and device have been matched\n");

	/* 为led_data指针分配内存 */
	led_data = devm_kzalloc(&pdev->dev, sizeof(struct myled_data), GFP_KERNEL);
	if(!led_data)
		return -ENOMEM;
	
	platform_set_drvdata(pdev, led_data);

	/* 初始化LED */
	ret = myled_init(pdev);
	if(ret){
		return ret;
	}
	
	/* 初始化led_cdev变量 */
	led_cdev							= &led_data->cdev;
	led_cdev->name						= "myled";	// 设备名字
	led_cdev->brightness				= LED_OFF;	// LED初始亮度
	led_cdev->max_brightness			= LED_FULL;	// LED最大亮度
	led_cdev->brightness_set			= myled_brightness_set;	// LED亮度设置函数-不可休眠
	led_cdev->brightness_set_blocking	= myled_brightness_set_blocking; // LED亮度设置函数-可休眠
	
	/* 注册LED设备 */
	return led_classdev_register(&pdev->dev, led_cdev);
}

/* platform驱动模块卸载时
 * 此函数i执行
 * @ dev: platform设备指针
 * @ 成功返回0, 失败返回负值
 */
static int myled_remove(struct platform_device *pdev)
{
	struct myled_data *led_data = platform_get_drvdata(pdev);
	led_classdev_unregister(&led_data->cdev);
	dev_info(&pdev->dev, "LED driver was removed\n");

	return 0;
}

/* 匹配列表 */
static const struct of_device_id led_of_match[] = {
	{.compatible = "fmql,led"},
	{/* Sentinel */}
};

static struct platform_driver myled_driver = {
	.driver = {
		.name			= "fmql-led3",		/* platform_driver name*/
		.of_match_table	= led_of_match,
	},
	.probe = myled_probe,
	.remove = myled_remove,
};


module_platform_driver(myled_driver);

MODULE_AUTHOR("Skylar <[email protected]>");
MODULE_DESCRIPTION("FMQL LED Driver Framework");
MODULE_LICENSE("GPL");

代码解析

 

 内核自带的LED驱动

正点原子第40章内容

compatible属性一定要是“gpio-leds”

驱动名称为“leds-gpio”        在/sys/bus/platform/drivers目录下

fmql自带的内核源码:

解析gpio和gpios开头的属性

我自己改的dts如下:

标签:led,struct,框架,fmql,cdev,Linux,myled,include,data
From: https://blog.csdn.net/qq_41656020/article/details/142762077

相关文章

  • 笔记--(5)、Linux硬盘管理与文件系统基础
    一、挂载、卸载在linux中所有的存储设备有需要挂载才可以使用lsblk查看硬盘信息mount挂载命令mount-tsdb/mydisk/挂载sdb硬盘到mydisk目录中umount卸载挂载设备命令umountsdb取消挂载sdb硬盘umount/mydisk/输入挂载路径也能取消二、硬盘分区结构硬盘中......
  • linux_ssh免密登录
    SSH(SecureShell)协议是一种安全的网络协议,认证原理是基于用户名密码和基于密钥对两种认证方式,本次讲解基于密钥对的认证方式,也就是免密登录免密登录原理.ssh文件夹下的文件功能解释.ssh路径一般在用户的家目录下文件解释known_hosts记录ssh访问过计算机的公钥(publi......
  • Linux 中6种查看日志命令
    Linux查看日志的命令有多种:tail、cat、head、echo等,本文只介绍几种常用的方法。1、tailtail-n10test.log查询日志尾部最后10行的日志;tail-n+10test.log查询10行之后的所有日志;tail-fn10test.log循环实时查看最后1000行记录(最常用的)一般还会配合着......
  • 【Linux】yum、vim、gcc/g++
    文章目录1.Linux软件管理包yum什么是软件包rzsz查看软件包如何安装软件如何卸载软件Linux开发工具2.Linux编译器vimvim的基本概念vim的基本操作3.Linux编译器gcc/g++背景知识在这里涉及到一个重要的概念:函数库函数库一般分为静态库和动态库两种。gcc选项1.Linux软......
  • 基于python+flask框架的研招信息管理和预测系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育普及率的提升和就业竞争的加剧,越来越多的学生选择继续深造,报考研究生的人数逐年攀升。然而,研究生招生信息的管理和获取却面临......
  • 基于python+flask框架的中医古方名方信息管理系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景中医作为中华民族的传统医学,承载着千年的智慧与经验。在浩瀚的中医典籍中,古方名方犹如璀璨的星辰,闪烁着独特的光芒。这些古方名方不仅蕴含......
  • 基于python+flask框架的医院门诊预约挂号系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着医疗技术的不断进步和人们健康意识的日益增强,医院门诊的就诊需求呈现出快速增长的趋势。传统的挂号方式往往存在排队时间长、挂号效率......
  • Linux练习题(一)
    1、在/zhangsan目录下建立pc目录mkdir-p/zhangsan/pc2、在zhangsan/pc目录下完成以下目录结构创建ceshi、ceshi/ceshi1、ceshi/ceshi1/ceshi1-1mkdir-p/zhangsan/pc/ceshi/ceshi1/ceshi1-13、在zhangsan/pc/目录下分别建立以下文件1、2、3、4cdzhangsan/pctouch......
  • 服装生产管理的数字化转型:SpringBoot框架
    4系统设计4.1系统结构设计在结构设计过程中,首先对系统进行需求分析,然后进行系统初步设计,将系统功能模块细化,具体分析每一个功能模块具体应该首先哪些功能,最后将各个模块进行整合,实现系统结构的最终设计。本协力服装厂服装生产管理系统结构设计如图4-1所示。图4-1系......
  • Linux 网络管理-ip命令
    Linux网络管理-ip命令ip--helpUsage:ip[OPTIONS]OBJECT{COMMAND|help}ip[-force]-batchfilenamewhereOBJECT:={address|addrlabel|amt|fou|help|ila|ioam|l2tp|link|macsec|maddress|monitor|mptcp......