Linux驱动 | debugfs接口创建

简介: Linux驱动 | debugfs接口创建

上篇介绍了procfs接口的创建,今天再介绍一种debugfs接口的创建。

实现效果

/sys/kernel/debug/目录下创建一个ion/test文件,通过catecho的方式进行读写操作:

前期准备

内核配置打开debugfs:

CONFIG_DEBUG_FS=y

挂载debugfs文件系统:

mount -t debugfs none /sys/kernel/debug

代码实现

读写变量:

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/types.h>
static struct dentry *ion_dir;
static u64 test_u64 = 0;
static int __init debugfs_init(void)
{
    //创建一个/sys/kernel/debug/ion目录
    ion_dir = debugfs_create_dir("ion", NULL);
    if (!ion_dir) {
        printk("ion_dir is null\n");
        return -1;
    }
    /* 创建/sys/kernel/debug/ion/test_u64文件 */
    debugfs_create_u64("test_u64", 0644,
                        ion_dir, &test_u64);
    return 0;
}
static void __exit debugfs_exit(void)
{
    debugfs_remove_recursive(ion_dir);
}
module_init(debugfs_init);
module_exit(debugfs_exit);
MODULE_LICENSE("GPL");

运行结果:

读写字符串:

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/dcache.h>
#include <linux/types.h>
static char ion_buf[512] = "hello\n";
static struct dentry *ion_dir;
static int ion_open(struct inode *inode, struct file *filp)
{
    //printk("ion open\n");
    return 0;
}
ssize_t ion_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
{
    int retval = 0;
    if ((*offp + count) > 512)
        count = 512 - *offp;
    if (copy_to_user(buf, ion_buf+*offp, count)) {
        printk("copy to user failed, count:%ld\n", count);
        retval = -EFAULT;
        goto out;
    }
    *offp += count;
    retval = count;
out:
    return retval;
}
ssize_t ion_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp)
{
    int retval;
    if (*offp > 512)
        return 0;
    if (*offp + count > 512)
        count = 512 - *offp;
    if (copy_from_user(ion_buf+*offp, buff, count)) {
        printk("copy from user failed, count:%ld\n", count);
        retval = -EFAULT;
        goto out;
    }
    *offp += count;
    retval = count;
out:
    return retval;
}
struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .read = ion_read,
    .write = ion_write,
    .open = ion_open,
};
static int __init debugfs_init(void)
{
    printk("INIT MODULE\n");
    //创建一个/sys/kernel/debug/ion目录
    ion_dir = debugfs_create_dir("ion", NULL);
    if (!ion_dir) {
        printk("ion_dir is null\n");
        return -1;
    }
    /* 创建/sys/kernel/debug/ion/test文件 */
    struct dentry *filent = debugfs_create_file("test", 0644, ion_dir, NULL, &my_fops);
    if (!filent) {
        printk("test file is null\n");
        return -1;
    }
    return 0;
}
static void __exit debugfs_exit(void)
{
    debugfs_remove_recursive(ion_dir);
}
module_init(debugfs_init);
module_exit(debugfs_exit);
MODULE_LICENSE("GPL");

运行结果:

函数接口说明

创建目录、文件函数:

/* 创建目录 */
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
/*创建节点 */
struct dentry *debugfs_create_file(const char *name, umode_t mode,
                                   struct dentry *parent, void *data,
                                   const struct file_operations *fops);

name:要创建的/sys/kernel/debug下的目录名

parent:父目录,用struct dentry结构体表示。如果直接在/sys/kernel/debug/下创建文件,则为NULL

创建不同大小的文件:

//创建十进制的无符号文件
void debugfs_create_u8(const char *name, umode_t mode,
                       struct dentry *parent, u8 *value);
void debugfs_create_u16(const char *name, umode_t mode,
                        struct dentry *parent, u16 *value);
void debugfs_create_u32(const char *name, umode_t mode,
                        struct dentry *parent, u32 *value);
void debugfs_create_u64(const char *name, umode_t mode,
                        struct dentry *parent, u64 *value);
//创建十六进制的无符号文件
void debugfs_create_x8(const char *name, umode_t mode,
                       struct dentry *parent, u8 *value);
void debugfs_create_x16(const char *name, umode_t mode,
                        struct dentry *parent, u16 *value);
void debugfs_create_x32(const char *name, umode_t mode,
                        struct dentry *parent, u32 *value);
void debugfs_create_x64(const char *name, umode_t mode,
                        struct dentry *parent, u64 *value);

更详细的debugfs用法请参考官方文档:Documentation/filesystems/debugfs.txt

end

猜你喜欢

Linux驱动 | procfs接口创建

Linux驱动 | 在驱动中创建sysfs接口

Linux reset子系统及驱动实例

Linux clock子系统及驱动实例

Linux内核中常用的C语言技巧

Linux内核死锁检测工具——Lockdep

Linux内核基础篇——常用调试技巧汇总

Linux内核基础篇——动态输出调试

Linux内核基础篇——printk调试

Linux内核基础篇——initcall

写给新手的MMU工作原理


相关文章
|
2月前
|
Linux 程序员 编译器
Linux内核驱动程序接口 【ChatGPT】
Linux内核驱动程序接口 【ChatGPT】
|
3月前
|
Java Linux API
Linux设备驱动开发详解2
Linux设备驱动开发详解
44 6
|
3月前
|
消息中间件 算法 Unix
Linux设备驱动开发详解1
Linux设备驱动开发详解
49 5
|
3月前
|
Ubuntu NoSQL Linux
Linux内核和驱动
Linux内核和驱动
29 2
|
3月前
|
监控 Linux
在Linux中,如何查看网络接口的状态?
在Linux中,如何查看网络接口的状态?
|
3月前
|
数据采集 Linux
Linux源码阅读笔记20-PCI设备驱动详解
Linux源码阅读笔记20-PCI设备驱动详解
|
4月前
|
存储 JSON Linux
|
4月前
|
Oracle 关系型数据库 Linux
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
通过这一连串的步骤,可以专业且有效地在Linux下为Qt编译Oracle驱动库 `libqsqloci.so`,使得Qt应用能够通过OCI与Oracle数据库进行交互。这些步骤适用于具备一定Linux和Qt经验的开发者,并且能够为需要使用Qt开发数据库应用的专业人士提供指导。
149 1
讲解linux下的Qt如何编译oracle的驱动库libqsqloci.so
|
2月前
|
域名解析 负载均衡 网络协议
Linux网络接口配置不当所带来的影响
总而言之,Linux网络接口的恰当配置是保证网络稳定性、性能和安全性的基础。通过遵循最佳实践和定期维护,可以最大程度地减少配置错误带来的负面影响。
144 0
|
2月前
|
Linux API
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】
Linux里的高精度时间计时器(HPET)驱动 【ChatGPT】

热门文章

最新文章