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");

总结

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

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

相关文章
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
5053 77
|
Ubuntu 搜索推荐 Linux
详解Ubuntu的strings与grep命令:Linux开发的实用工具。
这就是Ubuntu中的strings和grep命令,透明且强大。我希望你喜欢这个神奇的世界,并能在你的Linux开发旅程上,通过它们找到你的方向。记住,你的电脑是你的舞台,在上面你可以做任何你想做的事,只要你敢于尝试。
547 32
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
882 15
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
901 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
Linux 程序员 编译器
Linux内核驱动程序接口 【ChatGPT】
Linux内核驱动程序接口 【ChatGPT】
|
存储 Linux 开发工具
如何进行Linux内核开发【ChatGPT】
如何进行Linux内核开发【ChatGPT】
|
9月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
984 1
二、Linux文本处理与文件操作核心命令
|
9月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
582 137
|
9月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1518 58