linux驱动开发 使用设备树编写一个led驱动程序

简介: linux驱动开发 使用设备树编写一个led驱动程序

前言

本文将带大家学习如何使用设备树编写一个LED的驱动程序。

我这里使用的开发板是百问网的imx6ull。

一、设备树的配置

1.进入设备树目录查看设备树文件

0fcbac1d763d409db7f60286df331a74.png

2.添加led子节点的信息

972c047baea44afd9dce6386cf496fa3.png

3.返回源码目录生成dtb文件

a8d9575bc60e46a793bbc0878608e2b0.png

4.将生成的dtb文件拷贝到开发板的网络文件系统

ddc5e0e1e5a34ff7b3e24ff8e83c7f39.png

5.将dtb文件拷贝到开发板的/boot目录下重新启动开发板

二、重新启动后查看设备信息

1.查看创建出的平台设备

进入/sys/bus/platform/devices/目录可以查看根据设备树生成的平台设备

220a398d8c6647d98c6f83bf736b512b.png

2.查看节点

进入/sys/firmware/devicetree/base目录查看生成的节点

ba28d8e6823244b59899377009ebb448.png

3.编写驱动程序

#include <linux/module.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <asm/current.h>
#include <linux/delay.h>
#include <linux/timex.h>
int major=0;
static struct class *led_class;
static struct gpio_desc *led_gpio;
static ssize_t led_read (struct file *file, char __user *buf, size_t size, loff_t *off)
{
  return 0;
}
static int led_open (struct inode *inode, struct file *file)
{
  gpiod_direction_output(led_gpio, 0);
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  return 0;
}
static ssize_t led_write (struct file *file, const char __user *buf, size_t size, loff_t *off)
{
  char val;
  int err;
  err = copy_from_user(&val, buf, 1);
  gpiod_set_value(led_gpio, val);
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  return 1;
}
static struct file_operations led_ops={
  .owner    = THIS_MODULE,
  .open   = led_open,
  .read   = led_read,
  .write    = led_write,  
};
static int led_probe(struct platform_device *pdev)
{
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  /*1.获取硬件信息*/
  led_gpio=gpiod_get(&pdev->dev, NULL, 0);
  if (IS_ERR(led_gpio)) {
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  }
  /*2.创建设备节点*/  
  device_create(led_class,NULL, MKDEV(major, 0), NULL, "100askled");
    return 0;
}
static int led_remove(struct platform_device *pdev)
{   
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  gpiod_put(led_gpio);
  return 0;
}
static const struct of_device_id my_led[] = {
    { .compatible = "100ask,led" },
    { },
};
static struct platform_driver led={
  .driver = {
    .name = "led",
    .of_match_table = my_led, 
  },
  .probe = led_probe,
  .remove = led_remove, 
};
static int __init led_init(void)
{
  int err;
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  /*确定主设备号*/
  major=register_chrdev(major, "myled", &led_ops);
  /*创建类*/
  led_class=class_create(THIS_MODULE, "led");
  if (IS_ERR(led_class)) {
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    unregister_chrdev(major, "myled");
    return PTR_ERR(led_class);
  }
  err=platform_driver_register(&led);
  return 0;
}
static void __exit led_exit(void)
{
  printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
  device_destroy(led_class, MKDEV(major, 0));
  class_destroy(led_class);
  unregister_chrdev(major, "myled");
  platform_driver_unregister(&led);
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

总结

使用设备树来编写驱动程序极大的方便了我们写驱动程序,如果不使用设备树去编写驱动程序的话那只能使用寄存器操作硬件。

有了设备树后操作硬件就变得非常简单了。

相关文章
|
7天前
|
Linux SoC
Linux设备树(DTS)
Dts:DTS即Device Tree Source,是一个文本形式的文件,用于描述硬件信息。一般都是固定信息,无法变更,无法overlay。 设备树由来 linux内核源码中,之前充斥着大量的平台相关(platform Device)配置,而这些代码大多是杂乱且重复的,这使得ARM体系结构的代码维护者和内核维护者在发布一个新的版本的时候有大量的工作要做,以至于LinusTorvalds 在2011年3月17日的ARM Linux邮件列表中宣称“Gaah.Guys,this whole ARM thing is a f*cking pain in the ass”这使得整个ARM社区不得不
17 1
Linux设备树(DTS)
|
7天前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
|
14天前
|
存储 Unix Linux
揭秘Linux硬件组成:从内核魔法到设备树桥梁,打造你的超级系统,让你的Linux之旅畅通无阻,震撼体验来袭!
【8月更文挑战第5天】Linux作为顶级开源操作系统,凭借其强大的功能和灵活的架构,在众多领域大放异彩。本文首先概述了Linux的四大核心组件:内核、Shell、文件系统及应用程序,并深入探讨了内核的功能模块,如存储、CPU及进程管理等。接着介绍了设备树(Device Tree),它是连接硬件与内核的桥梁,通过DTS/DTB文件描述硬件信息,实现了跨平台兼容。此外,还简要介绍了Linux如何通过本地总线高效管理硬件资源,并阐述了文件系统与磁盘管理机制。通过这些内容,读者可以全面了解Linux的硬件组成及其核心技术。
30 3
|
18小时前
|
Linux SoC
Linux设备树(DTS)
Dts:DTS即Device Tree Source,是一个文本形式的文件,用于描述硬件信息。一般都是固定信息,无法变更,无法overlay。 设备树由来 linux内核源码中,之前充斥着大量的平台相关(platform Device)配置,而这些代码大多是杂乱且重复的,这使得ARM体系结构的代码维护者和内核维护者在发布一个新的版本的时候有大量的工作要做,以至于LinusTorvalds 在2011年3月17日的ARM Linux邮件列表中宣称“Gaah.Guys,this whole ARM thing is a f*cking pain in the ass”这使得整个ARM社区不得不
7 0
|
30天前
|
Linux SoC
Linux设备树(DTS)介绍
**设备树(DTS)是Linux中用于描述硬件信息的文本文件,旨在减少内核与平台相关代码的耦合。DTS文件包含静态硬件配置,不支持动态变更。它被编译成DTB二进制文件,供内核在启动时解析以了解硬件布局。设备树解决了ARM体系结构代码维护的复杂性问题,通过解耦实现vendor修改的独立和共二进制目标。设备树overlay允许对配置进行增量修改,遵循特定规则,如dts覆盖dtsi,先引用后修改。调试时,可使用内置工具反编译dtb或dtbo映像为dts文本以检查内容。**
79 7
|
1月前
|
弹性计算 运维 自然语言处理
阿里云OS Copilot测评:重塑Linux运维与开发体验的智能革命
阿里云OS Copilot巧妙地将大语言模型的自然语言处理能力与操作系统团队的深厚经验相结合,支持自然语言问答、辅助命令执行等功能,为Linux用户带来了前所未有的智能运维与开发体验。
|
29天前
|
Ubuntu Linux Docker
Java演进问题之Alpine Linux创建更小的Docker镜像如何解决
Java演进问题之Alpine Linux创建更小的Docker镜像如何解决
|
Ubuntu Linux 芯片
史上最全的LED点灯程序—使用STM32、FPGA、Linux点亮你的LED灯
不知道小伙伴们点亮过多少板子的LED灯,有很多小伙伴留言说讲一下stm32、fpga、liunx他们之间有什么不同,不同点很多,口说无凭,今天就来点亮一下stm32、fpga和liunx板子的led灯,大家大致看一下点灯流程和点灯环境以及点灯流程,就能大概的了解一下三者的区别,可以有选择的去学习!
355 0
史上最全的LED点灯程序—使用STM32、FPGA、Linux点亮你的LED灯
|
5天前
|
NoSQL 关系型数据库 MySQL
Linux学习记录---(1、基本命令)
该博客文章提供了Linux系统中基本命令的使用记录,包括文件和目录操作、Redis服务管理、MySQL数据库操作以及Tomcat服务器的启动和检查。
Linux学习记录---(1、基本命令)
|
3天前
|
Linux
会玩这10个Linux命令,一定是个有趣的IT男!
会玩这10个Linux命令,一定是个有趣的IT男!