【驱动开发】基于GPIO子系统编写LED驱动,编写应用程序进行测试设置定时器,5秒钟打印一次hello world

基于GPIO子系统编写LED驱动,编写应用程序进行测试,设置定时器,5秒钟打印一次hello world

驱动程序:

cpp 复制代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/timer.h>
/*
myled
    {
        led1-gpio=<&gpioe 10 0>;
        led2-gpio=<&gpiof 10 0>;
        led3-gpio=<&gpioe 8 0>;
    };
*/

// 分配定时器对象
struct timer_list mytimer;
struct device_node *dnode;
int gpiono1, gpiono2, gpiono3;

// 定时器处理函数
int n = 1;
int count = 0;
int trigger_count = 5;
void mytimer_function(struct timer_list *timer)
{
    count++;
    if (count == trigger_count)
    {
        printk("Hello World\n");
        count = 0;
    }
    mod_timer(timer, jiffies + 5 * HZ);

    switch (n)
    {
    case 1:
        gpio_set_value(gpiono1, !gpio_get_value(gpiono1));
        n++;
        break;
    case 2:
        gpio_set_value(gpiono2, !gpio_get_value(gpiono2));
        n++;
        break;
    case 3:
        gpio_set_value(gpiono3, !gpio_get_value(gpiono3));
        n = 1;
        break;
    default:
        break;
    }
    mod_timer(timer, jiffies + HZ);
}

int gpio_led1(int gpiono, struct device_node *dnode)
{
    // 根据设备树节点解析gpio编号
    gpiono = of_get_named_gpio(dnode, "led1-gpio", 0);
    if (gpiono < 0)
    {
        printk("解析led1_gpio编号失败\n");
        return -EIO;
    }
    printk("解析led1_gpio编号成功\n");
    // 申请gpio编号
    gpio_request(gpiono, NULL);
    // 设置gpio为输出并且初始化数值为0
    gpio_direction_output(gpiono, 0);
    return gpiono;
}

int gpio_led2(int gpiono, struct device_node *dnode)
{
    // 根据设备树节点解析gpio编号
    gpiono = of_get_named_gpio(dnode, "led2-gpio", 0);
    if (gpiono < 0)
    {
        printk("解析led2_gpio编号失败\n");
        return -EIO;
    }
    printk("解析led2_gpio编号成功\n");
    // 申请gpio编号
    gpio_request(gpiono, NULL);
    // 设置gpio为输出并且初始化数值为0
    gpio_direction_output(gpiono, 0);
    return gpiono;
}

int gpio_led3(int gpiono, struct device_node *dnode)
{
    // 根据设备树节点解析gpio编号
    gpiono = of_get_named_gpio(dnode, "led3-gpio", 0);
    if (gpiono < 0)
    {
        printk("解析led3_gpio编号失败\n");
        return -EIO;
    }
    printk("解析led3_gpio编号成功\n");
    // 申请gpio编号
    gpio_request(gpiono, NULL);
    // 设置gpio为输出并且初始化数值为0
    gpio_direction_output(gpiono, 0);
    return gpiono;
}

static int __init mycdev_init(void)
{
    // 解析设备树节点信息
    dnode = of_find_node_by_path("/myled");
    if (dnode == NULL)
    {
        printk("解析设备树节点失败\n");
        return -ENXIO;
    }
    gpiono1 = gpio_led1(gpiono1, dnode);
    gpiono2 = gpio_led2(gpiono2, dnode);
    gpiono3 = gpio_led3(gpiono3, dnode);
    // 初始化定时器对象
    timer_setup(&mytimer, mytimer_function, 0);
    mytimer.expires = jiffies + HZ; // 定时1s
    // 注册定时器
    add_timer(&mytimer);
    return 0;
}

static void __exit mycdev_exit(void)
{
    //注销定时器
    del_timer(&mytimer);
    gpiod_set_value(gpiono1,0);
    //释放GPIO编号
    gpiod_put(gpiono1);

    //注销定时器
    del_timer(&mytimer);
    gpiod_set_value(gpiono2,0);
    //释放GPIO编号
    gpiod_put(gpiono2);

    //注销定时器
    del_timer(&mytimer);
    gpiod_set_value(gpiono3,0);
    //释放GPIO编号
    gpiod_put(gpiono3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
相关推荐
DeeplyMind12 小时前
第二章:模块的编译与运行-7 Loading and Unloading Modules
linux·驱动开发
非凡ghost18 小时前
猫眼浏览器(Chrome内核增强版浏览器)官方便携版
前端·网络·chrome·windows·软件需求
熊文豪1 天前
Windows安装RabbitMQ保姆级教程
windows·分布式·rabbitmq·安装rabbitmq
搬砖的小码农_Sky1 天前
Windows操作系统上`ping`命令的用法详解
运维·网络·windows
Kiri霧1 天前
Rust模式匹配详解
开发语言·windows·rust
程序设计实验室1 天前
使用命令行删除 Windows 网络映射驱动器
windows
用户31187945592181 天前
Windows 电脑安装 XTerminal 1.25.1 x64 版(带安装包下载关键词)
windows
Logintern091 天前
windows如何设置mongodb的副本集
数据库·windows·mongodb
Chandler242 天前
一图掌握 操作系统 核心要点
linux·windows·后端·系统
ajassi20002 天前
开源 C# 快速开发(十七)进程--消息队列MSMQ
windows·开源·c#