LED驱动框架代码的实现

2023-12-24 05:51:06

一.? 简介

本文在上一篇文章学习的基础上,文章地址如下:

LED灯驱动模块加载与卸载代码框架-CSDN博客

本文来学习 编写 LED灯驱动框架代码。

二.? LED驱动框架代码的实现

上一篇文章创建了 2_led工程,设置了 可能会调用到的 Linux内核源码路径。初步编写了 Led灯驱动模块的加载与卸载代码框架。

这里在 前面代码实现的基础上,继续进行代码编写。

这里可以参考 Linux内核源码中驱动模块的代码实现 进行编写。可以在( NXP官方提供的) Linux 内核源码中找一个包含 驱动模块注册与卸载的代码实现。

注册字符设时这里选择使用 register_chrdev()函数,注册字符设备时可以参考 Linux内核源码中的驱动模块如何注册。例如,这里我参考drivers/block/paride/pg.c 文件中注册字符设备时 register_chrdev() 函数调用:

err = register_chrdev(major, name, &pg_fops);

卸载字符设备时调用:

	unregister_chrdev(major, name);

或者直接找到 函数定义处,进行编写。 register_chrdev()函数在 内核源码 根目录下 /include/linux/fs.h 文件中。

关于 Led灯需要实现的函数

结构体file_operations中函数集,根据需求实现相应的函数,不需要全部实现。

这里 Led灯驱动实验,我们这里只需要设置电平,也就是写入数据,不需要读数据。所以, file_operations结构体不需要进行 read函数实现。

参考 结构体file_operations 关于 函数操作集 的框架实现:

static const struct file_operations pg_fops = {
	.owner = THIS_MODULE,
	.read = pg_read,
	.write = pg_write,
	.open = pg_open,
	.release = pg_release,
	.llseek = noop_llseek,
};

static ssize_t pg_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
............................
    returncopy + hs;
}

static ssize_t pg_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
............................
}

static int pg_open(struct inode *inode, struct file *file)
{
............................
}

static int pg_release(struct inode *inode, struct file *file)
{
............................
}

led.c 驱动框架代码如下:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
  
#define  LED_DEVICE_NUMBER  200   //Led的主设备号
#define  LED_NAME           "led" //Led灯的名字

 //打开Led设备
static int led_open(struct inode *inode, struct file *file)
{
    return 0;
}

// 向Led设备写数据
static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
{
    return 0;
}

 //关闭/释放设备
static int led_release(struct inode *inode, struct file *file)
{
    return 0;
}

static const struct file_operations led_fops=
{
	.owner = THIS_MODULE,
	.open = led_open,
    .write = led_write,
	.release = led_release,
 };

//Led驱动模块入口函数
static int __init led_init(void)
{  
    int ret = 0;
    printk("led_init!\r\n");
    //注册字符设备
    ret = register_chrdev(LED_DEVICE_NUMBER, LED_NAME, &led_fops);
	if(ret < 0)
    {
        printk("led device register failed!\r\n");
        return -EIO;
    }		  
    return 0;
}

//Led驱动模块出口函数
static void __exit led_exit(void)
{
    printk("led_exit!\r\n");
    //卸载字符设备
    unregister_chrdev(LED_DEVICE_NUMBER, LED_NAME);
}

module_init(led_init); //入口
module_exit(led_exit); //出口

MODULE_LICENSE("GPL"); //模块 licence
MODULE_AUTHOR("lingxuewu"); //模块作者

文章来源:https://blog.csdn.net/wojiaxiaohuang2014/article/details/135176183
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。