关于第一个linux内核驱动的代码总结

驱动源码如下:

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/uaccess.h>
#include <linux/slab.h>

#define DRIVER_NAME "gpio_demo"
#define GPIO_PIN 17  // 使用GPIO17作为示例

static dev_t dev_num;
static struct cdev gpio_cdev;
static struct class *gpio_class;
static struct device *gpio_device;

static int gpio_demo_open(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "GPIO demo device opened\n");
    return 0;
}

static int gpio_demo_release(struct inode *inode, struct file *file)
{
    printk(KERN_INFO "GPIO demo device closed\n");
    return 0;
}

static ssize_t gpio_demo_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
    char value;
    int ret;
    
    value = gpio_get_value(GPIO_PIN) ? '1' : '0';
    
    ret = copy_to_user(buf, &value, 1);
    if (ret < 0)
        return -EFAULT;
    
    return 1;
}

static ssize_t gpio_demo_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
    char value;
    int ret;
    
    if (count != 1)
        return -EINVAL;
    
    ret = copy_from_user(&value, buf, 1);
    if (ret < 0)
        return -EFAULT;
    
    if (value == '0')
        gpio_set_value(GPIO_PIN, 0);
    else if (value == '1')
        gpio_set_value(GPIO_PIN, 1);
    else
        return -EINVAL;
    
    return 1;
}

static const struct file_operations gpio_fops = {
    .owner = THIS_MODULE,
    .open = gpio_demo_open,
    .release = gpio_demo_release,
    .read = gpio_demo_read,
    .write = gpio_demo_write,
};

static int __init gpio_demo_init(void)
{
    int ret;
    
    // 分配设备号
    ret = alloc_chrdev_region(&dev_num, 0, 1, DRIVER_NAME);
    if (ret < 0) {
        printk(KERN_ERR "Failed to allocate device number\n");
        return ret;
    }
    
    // 初始化字符设备
    cdev_init(&gpio_cdev, &gpio_fops);
    gpio_cdev.owner = THIS_MODULE;
    
    // 添加字符设备
    ret = cdev_add(&gpio_cdev, dev_num, 1);
    if (ret < 0) {
        printk(KERN_ERR "Failed to add cdev\n");
        goto err_cdev;
    }
    
    // 创建设备类
    gpio_class = class_create(DRIVER_NAME);
    if (IS_ERR(gpio_class)) {
        printk(KERN_ERR "Failed to create device class\n");
        ret = PTR_ERR(gpio_class);
        goto err_class;
    }
    
    // 创建设备文件
    gpio_device = device_create(gpio_class, NULL, dev_num, NULL, DRIVER_NAME);
    if (IS_ERR(gpio_device)) {
        printk(KERN_ERR "Failed to create device\n");
        ret = PTR_ERR(gpio_device);
        goto err_device;
    }
    
    // 申请GPIO
    if (!gpio_is_valid(GPIO_PIN)) {
        printk(KERN_ERR "GPIO %d is not valid\n", GPIO_PIN);
        ret = -ENODEV;
        goto err_gpio;
    }
    
    ret = gpio_request(GPIO_PIN, "gpio_demo");
    if (ret) {
        printk(KERN_ERR "Failed to request GPIO %d\n", GPIO_PIN);
        goto err_gpio;
    }
    
    // 设置为输出模式,初始低电平
    ret = gpio_direction_output(GPIO_PIN, 0);
    if (ret) {
        printk(KERN_ERR "Failed to set GPIO direction\n");
        goto err_dir;
    }
    
    printk(KERN_INFO "GPIO demo driver initialized\n");
    return 0;
    
err_dir:
    gpio_free(GPIO_PIN);
err_gpio:
    device_destroy(gpio_class, dev_num);
err_device:
    class_destroy(gpio_class);
err_class:
    cdev_del(&gpio_cdev);
err_cdev:
    unregister_chrdev_region(dev_num, 1);
    return ret;
}

static void __exit gpio_demo_exit(void)
{
    gpio_free(GPIO_PIN);
    device_destroy(gpio_class, dev_num);
    class_destroy(gpio_class);
    cdev_del(&gpio_cdev);
    unregister_chrdev_region(dev_num, 1);
    printk(KERN_INFO "GPIO demo driver exited\n");
}

module_init(gpio_demo_init);
module_exit(gpio_demo_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Simple GPIO driver demo for Raspberry Pi");

以上是经过编译验证的,需要的拿走,不谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值