基于GPIO子系统编写LED驱动

编写应用程序进行测试

设置定时器,每5秒打印一次hello world

驱动程序

#include <linux/init.h>
#include <linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/fs.h>
#include<linux/io.h>
#include<linux/gpio.h>
/*       myled
    {
        led1-gpio=<&gpioe 10 0>; 
        led2-gpio=<&gpiof 10 0>;
        led3-gpio=<&gpioe 8 0>;           
    }; 
*/
struct device_node *dnode;
unsigned int gpiono;
unsigned int gpiono2;
unsigned int gpiono3;
struct timer_list mytimer;
char kbuf[128]={0};
int major;

//定时器处理函数
 void mytimer_function(struct timer_list *timer)
 {
    //打印
    printk("hello world\n");
    //再次启用定时器
    mod_timer(timer,jiffies+5*HZ);
 }

ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
     int net = copy_from_user(kbuf, ubuf, size);
      if (net)
    {
        printk("copy_from_user filed\n");
        return -EIO;
    }
	 switch(kbuf[0]){
        case '1'://LED1
            if(kbuf[1]=='0')//关灯           
                gpio_set_value(gpiono,0);
            else
                //灯亮
                gpio_set_value(gpiono,1);
            break;
        case '2'://LED2
            if(kbuf[1]=='0')//关灯
                gpio_set_value(gpiono2,0);
            else
                //灯亮
                gpio_set_value(gpiono2,1);
            break;
        case '3'://LED3
            if(kbuf[1]=='0')//关灯
                gpio_set_value(gpiono3,0);
            else
                //灯亮
                gpio_set_value(gpiono3,1);
            break;
    }
    return 0;
}

struct file_operations fops={
    .write=mycdev_write,
};

static int __init mycdev_init(void)
{
        //字符设备驱动注册
    major=register_chrdev(0,"mychrdev",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n",major);


    //解析设备树节点信息
    dnode=of_find_node_by_path("/myled");
    if(dnode==NULL)
    {
        printk("解析设备树节点失败\n");
        return -ENXIO;
    }
    //获取LED1 GPIO编号
    gpiono=of_get_named_gpio(dnode,"led1-gpio",0);
    if(gpiono<0)
    {
        printk("获取GPIO编号失败\n");
          return -ENXIO;
    }
    gpiono2=of_get_named_gpio(dnode,"led2-gpio",0);
    if(gpiono2<0)
    {
        printk("获取GPIO编号失败\n");
          return -ENXIO;
    }
    gpiono3=of_get_named_gpio(dnode,"led3-gpio",0);
    if(gpiono3<0)
    {
        printk("获取GPIO编号失败\n");
          return -ENXIO;
    }
    //申请gpio编号
    int ret=gpio_request(gpiono,NULL);
    if(ret)
    {
        printk("申请GPIO编号失败\n");
        return -ENXIO;
    }
    printk("申请GPIO编号成功:%d\n",gpiono);
     //申请gpio编号
    int ret2=gpio_request(gpiono2,NULL);
    if(ret2)
    {
        printk("申请GPIO编号失败\n");
        return -ENXIO;
    }
    printk("申请GPIO编号成功:%d\n",gpiono2);
     //申请gpio编号
    int ret3=gpio_request(gpiono3,NULL);
    if(ret3)
    {
        printk("申请GPIO编号失败\n");
        return -ENXIO;
    }
    printk("申请GPIO编号成功:%d\n",gpiono3);

    //初始化定时器对象
    timer_setup(&mytimer,mytimer_function,0);
    mytimer.expires=jiffies+5*HZ;//定时1s;
    //注册定时器
    add_timer(&mytimer);

    //设置GPIO为输出
    ret=gpio_direction_output(gpiono,0);
    if(ret)
    {
        printk("GPIO输出设置失败\n");
        return -1;
    }
    //设置GPIO为输出
    ret2=gpio_direction_output(gpiono2,0);
    if(ret2)
    {
        printk("GPIO输出设置失败\n");
        return -1;
    }
    //设置GPIO为输出
    ret3=gpio_direction_output(gpiono3,0);
    if(ret3)
    {
        printk("GPIO输出设置失败\n");
        return -1;
    }
    // //灯亮
    // gpio_set_value(gpiono,1);
    //     //灯亮
    // gpio_set_value(gpiono2,1);
    //     //灯亮
    // gpio_set_value(gpiono3,1);
    return 0;
}
static void __exit mycdev_exit(void)
{
        //注销定时器
    del_timer(&mytimer);
    //gpiod_set_value(gpiono,0);
    gpio_set_value(gpiono,0);
    gpio_set_value(gpiono2,0);
    gpio_set_value(gpiono3,0);
    //释放GPIO编号
    gpio_free(gpiono);
       //释放GPIO编号
    gpio_free(gpiono2);
       //释放GPIO编号
    gpio_free(gpiono3);
     //注销字符设备驱动
    unregister_chrdev(major,"mychrdev");

}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");


应用程序

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>


int main(int argc, char const *argv[])
{
    char buf[128]={0};
    int fd=open("/dev/mychrdev",O_RDWR);
    if(fd<0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }
    while(1)
    {
        //从终端读取
        printf("请输入两个字符\n");
        printf("第一个字符:1(LED1) 2(LED2) 3(LED3)\n");
        printf("第二个字符:0(关灯) 1(开灯)\n");
        printf("请输入>");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        //向设备文件中写
        write(fd,buf,sizeof(buf));
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/108075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode——哈希表(Java)

哈希表 简介242. 有效的字母异位词349. 两个数组的交集202. 快乐数 简介 记录一下自己刷题的历程以及代码&#xff0c;会尽量把在本地测试包含main函数的完整代码贴上&#xff0c;以及一些注释掉的输出语句。写题过程中参考了 代码随想录。会附上一些个人的思路&#xff0c;如…

再畅通工程(最小生成树)

题目描述&#xff1a;还是畅通工程 某省调查乡村交通状况&#xff0c;得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通&#xff08;但不一定有直接的公路相连&#xff0c;只要能间接通过公路可达即可&#xff09;&…

NewStarCTF2023week4-Nmap

题目要我们找出Nmap扫描得到所有的开放端口 Nmap通常用于直接扫描目标主机&#xff0c;而不是直接扫描pcap文件。 那么这里我们还是使用wireshark来分析&#xff0c;使用过滤器&#xff1a; tcp.flags.syn 1 and tcp.flags.ack 1 这个过滤条件可以筛选出TCP端口开放的数据…

测开 (Junit 单元测试框架)

目录 了解 Junit 引入相关依赖 1、Junit注解 Test BeforeEach、BeforeAll AfterEach && AfterAll 2、断言 1、Assertions - assertEquals 方法 2、Assertions - assertNotEquals 方法 3、Assertions - assertTrue && assertFalse方法 4、Assertions…

DeOldify 接口化改造 集成 Flask

类似的图片修复项目 GFPGAN 的改造见我另一篇文 https://blog.csdn.net/weixin_43074462/article/details/132497146 DeOldify 是一款开源软件&#xff0c;用于给黑白照片或视频上色&#xff0c;效果还不错。 安装部署教程请参考别的文章&#xff0c;本文基于你给项目跑通&…

Chapter1:C++概述

此专栏为移动机器人知识体系的 C {\rm C} C基础&#xff0c;基于《深入浅出 C {\rm C} C》(马晓锐)的笔记&#xff0c; g i t e e {\rm gitee} gitee链接: 移动机器人知识体系. 1.C概述 1.1 C概述 计算机系统分为硬件系统和软件系统。 硬件系统&#xff1a;指组成计算机的电子…

【Matlab2016】Matlab中文版的下载、安装、激活(不建议安装过高版本!!)

这里写目录标题 首先双击R2016_win64.iso加载镜像文件双击setup.exe开始安装选择使用文件密钥安装填入密钥修改安装路径并记住此路径建议全部勾选等待安装完成 激活复制补丁到matlab路径下 创建快捷方式进入bin目录&#xff0c;找到matlab.exe 安装包 首先双击R2016_win64.iso加…

08.K8S高可用方案

K8S高可用方案 1、高可用部署方式 官方提供两种高可用实现方式: 堆叠etcd 拓扑,其中 etcd 节点与控制平面节点共存;外部 etcd 节点,其中 etcd 与控制平面在不同的节点上运行;1.1、堆叠 etcd 拓扑 主要特点: 每个 master 节点上运行一个 apiserver 和 etcd, etcd 只与本…

MySQL总结 (思维导图,常用)

一、常见的增删改查 二、约束&#xff08;五种&#xff09; 三、聚合查询 1、聚合函数 2、group by 和 having 3、联合查询 案例表&#xff1a; drop table if exists classes; create table classes (id int primary key auto_increment,name varchar(20) ); insert into …

高可用系统架构——关于语雀宕机的思考

语雀系统崩溃了&#xff0c;并且经过8个多小时才恢复&#xff0c;估计语雀的小伙伴们已经哭晕在厕所里了。 本次稳定性故障再次给架构师敲响警钟&#xff1a;系统高可用一直是架构的重点&#xff0c;它涉及到系统的方方面面&#xff0c;并且是一件持续性的长期工作。 故障起因…

Spring Security: 整体架构

Filter Spring Security 是基于 Sevlet Filter 实现的。下面是一次 Http 请求从 client 出发&#xff0c;与 Servlet 交互的图&#xff1a; 当客户端发送一个请求到应用&#xff0c;容器会创建一个 FilterChain&#xff0c;FilterChain 中包含多个 Filter 和 Servlet。这些 Fi…

代码训练营第53天:动态规划part12|leetcode309买卖股票的最佳时期含冷静期|leetcode714买卖股票的最佳时机含手续费

leetcode309&#xff1a;买卖股票的最佳时机含冷冻期 文章讲解&#xff1a;leletcode309 leetcode714&#xff1a;买卖股票的最佳时机含手续费 文章讲解&#xff1a;leetcode714 目录 1&#xff0c;leetcode309 买卖股票的最佳时机含冷冻期 2&#xff0c;leetcode714 买卖股票…

荣耀推送服务消息分类标准

前言 为了提升终端用户的推送体验、营造良好可持续的通知生态&#xff0c;荣耀推送服务将对推送消息进行分类管理。 消息分类 定义 荣耀推送服务将根据应用类型、消息内容和消息发送场景&#xff0c;将推送消息分成服务通讯和资讯营销两大类别。 服务通讯类&#xff0c;包…

Linux学习第26天:异步通知驱动开发: 主动

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 在正式开启今天的学习前&#xff0c;讲一讲为什么标题中加入了【主动】俩字。之前学习的阻塞和非阻塞IO&#xff0c;都是在被动的接受应用程序的操作。而今天的学…

深入浅出排序算法之计数排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 首先看一个题目&#xff0c;有n个数&#xff0c;取值范围是 0~n&#xff0c;写出一个排序算法&#xff0c;要求时间复杂度和空间复杂度都是O(n)的。 为了达到这种效果&#xff0c;这一篇将会介绍一种不基于比较的排序方法。这…

python,pandas ,openpyxl提取excel特定数据,合并单元格合并列,设置表格格式,设置字体颜色,

python&#xff0c;pandas &#xff0c;openpyxl提取excel特定数据&#xff0c;合并单元格合并列&#xff0c;设置表格格式&#xff0c;设置字体颜色&#xff0c; 代码 import osimport numpy import pandas as pd import openpyxl from openpyxl.styles import Font from op…

【鸿蒙软件开发】ArkTS基础组件之TextClock(时间显示文本)、TextPicker(滑动选择文本)

文章目录 前言一、TextClock1.1 子组件1.2 接口参数TextClockController 1.3 属性1.4 事件1.5 示例代码 二、TextPicker2.1 子组件2.2 接口参数 2.3 属性2.4 事件2.5 示例代码 总结 前言 TextClock组件:通过文本将当前系统时间显示在设备上。支持不同时区的时间显示&#xff0…

uni-app中tab选项卡的实现效果 @click=“clickTab(‘sell‘)“事件可传参数

一、效果图 二、代码 <template><view><view class"choose-tab"><view class"choose-tab-item" :class"chooseTab 0 ? active : " data-choose"0" click"clickTab">选项1</view><view …

docker部署prometheus+grafana服务器监控(三) - 配置grafana

查看 prometheus 访问 http://ip:9090/targets&#xff0c;效果如下&#xff0c;上面我们通过 node_exporter 收集的节点状态是 up 状态。 配置 Grafana 访问 http://ip:3000&#xff0c;登录 Grafana&#xff0c;默认的账号密码是 admin:admin&#xff0c;首次登录需要修改…

【C++初阶(三)】引用内联函数auto关键字

目录 前言 1. 引用 1.1 引用的概念 1.2 引用的特性 1.3 引用的权限 1.4 引用的使用 1.5 引用与指针的区别 2. 内联函数 2.1 什么是内联函数 2.2 内联函数的特性 3. auto关键字 3.1 auto简介 3.2 auto使用规则 3.3 auto不能使用的场景 4. 基于范围的for循环 4.1 范围for…
最新文章