C语言运用中断子系统用驱动控制led实验,c语言串口led点灯实验(驱动+应用层)

news2024/11/25 3:56:49

中断子系统用驱动控制led实验

驱动代码

#include <linux/init.h>
#include <linux/module.h>

#include<linux/interrupt.h>
#include<linux/gpio.h>
#include<linux/timer.h>

#include<linux/of.h>
#include<linux/of_irq.h>
#include<linux/of_gpio.h>


/*

    myirq{
		compatible = "hqyj,myirq";
		interrupt-parent=<&gpiof>;
        interrupts=<9 0>,<7 0>,<8 0>;
      led1-gpio=<&gpioe 10 0>;
	  led2-gpio=<&gpiof 10 0>;
	  led3-gpio=<&gpioe 8 0>;
	};

*/
  struct device_node *dnode;
 
  struct gpio_desc *lednode1;
  struct gpio_desc *lednode2;
  struct gpio_desc *lednode3;

  unsigned int irq_id1;
  unsigned int irq_id2;
  unsigned int irq_id3;
  
  //中断处理函数
  irqreturn_t myirq_handle1(int irq,void *dev)
  {
    
     //反转电平
    gpiod_set_value(lednode1,!gpiod_get_value(lednode1));
    //防止其他灯亮
    gpiod_set_value(lednode2,0);
    gpiod_set_value(lednode3,0);
      
      return IRQ_HANDLED;
  }
  irqreturn_t myirq_handle2(int irq,void *dev)
  {
   
    //反转电平
     gpiod_set_value(lednode2,!gpiod_get_value(lednode2));
     //防止其他灯亮
     gpiod_set_value(lednode1,0);
     gpiod_set_value(lednode3,0);
      
      return IRQ_HANDLED;
  }
  
   irqreturn_t myirq_handle3(int irq,void *dev)
  {
    
    //反转电平
     gpiod_set_value(lednode3,!gpiod_get_value(lednode3));
    //防止其他灯亮
     gpiod_set_value(lednode1,0);
     gpiod_set_value(lednode2,0);
      
      return IRQ_HANDLED;
  }

static int __init mycdev_init(void)
{
    //根据compatible解析设备节点
    dnode=of_find_compatible_node(NULL,NULL,"hqyj,myirq");
    if(NULL==dnode)
    {
        printk("of_find_compatible_node error\n");
        return -ENXIO;
    }
     
    printk("解析设备节点成功\n");
   //设备树节点解析
   lednode1=gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode1==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
     //设备树节点解析
   lednode2=gpiod_get_from_of_node(dnode,"led2-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode2==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
     //设备树节点解析
    lednode3=gpiod_get_from_of_node(dnode,"led3-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode3==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
    //解析按键1的软中断
     irq_id1=irq_of_parse_and_map(dnode,0);
     if(!irq_id1)
     {
        printk("解析软中断失败\n");
        return -ENXIO;
     }
     //解析按键2的软中断
     irq_id2=irq_of_parse_and_map(dnode,1);
     if(!irq_id2)
     {
        printk("解析软中断失败\n");
        return -ENXIO;
     }
     //解析按键3的软中断
     irq_id3=irq_of_parse_and_map(dnode,2);
     if(!irq_id3)
     {
        printk("解析软中断失败\n");
        return -ENXIO;
     }
      printk("解析软中断成功\n");
      
      //注册按键1请求中断
     int ret=request_irq(irq_id1,myirq_handle1,IRQF_TRIGGER_FALLING,"key1",(void*)1); 
     if(ret)
     {
       printk("注册按键请求中断失败\n");
       return ret;
     }
      //注册按键2请求中断
     ret=request_irq(irq_id2,myirq_handle2,IRQF_TRIGGER_FALLING,"key2",(void*)2); 
     if(ret)
     {
       printk("注册按键请求中断失败\n");
       return ret;
     }
     //注册按键3请求中断
     ret=request_irq(irq_id3,myirq_handle3,IRQF_TRIGGER_FALLING,"key3",(void*)3); 
     if(ret)
     {
       printk("注册按键请求中断失败\n");
       return ret;
     }
     printk("注册按键请求中断成功\n");
    return 0;
}
static void __exit mycdev_exit(void)
{ 
  //关灯
   gpiod_set_value(lednode1,0);
   gpiod_set_value(lednode2,0);
   gpiod_set_value(lednode3,0);
   //清空中断号
   free_irq(irq_id1,(void*)1);
   free_irq(irq_id2,(void*)2);
   free_irq(irq_id3,(void*)3);
   //释放设备树节点空间
   gpiod_put(lednode1);
   gpiod_put(lednode2);
   gpiod_put(lednode3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

串口led点灯实验(驱动+应用层)

驱动代码

#include <linux/init.h>
#include <linux/module.h>

#include<linux/fs.h>
#include<linux/io.h>
#include<linux/device.h>

#include<linux/gpio.h>
#include<linux/of.h>
#include<linux/of_gpio.h>

#include"head.h"

int major;
char kbuf[128]={0};

struct class *cls;
struct device *dev;

struct device_node *dnode;

struct gpio_desc *lednode1;
struct gpio_desc *lednode2;
struct gpio_desc *lednode3;

int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

ssize_t mycdev_read(struct file *file, char  *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
     unsigned long ret;
    //向用户空间读取拷贝
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_to_user(ubuf,kbuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}

ssize_t mycdev_write(struct file *file, const char  *ubuf, size_t size, loff_t *lof)
{
    unsigned long ret;
    //从用户空间读取数据
    if(size>sizeof(kbuf))//用户空间期待读取的大小内核满足不了,那就给内核支持的最大大小
        size=sizeof(kbuf);
    ret=copy_from_user(kbuf,ubuf,size);
    if(ret)//拷贝失败
    {
        printk("copy_to_user filed\n");
        return ret;
    }
    return 0;
}

long mycdev_ioctl (struct file * file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
        case LED_OFF:
            switch (arg)
            {
            case 1:
            gpiod_set_value(lednode1,0);
            break;
            case 2:
            gpiod_set_value(lednode2,0);
            break;
            case 3:
            gpiod_set_value(lednode3,0);
            break;
           
            }
        break;
        case LED_ON:
             switch (arg)
             {
            case 1:
            gpiod_set_value(lednode1,1);
            break;
            case 2:
            gpiod_set_value(lednode2,1);
            break;
            case 3:
            gpiod_set_value(lednode3,1);
            break;
             }
        break;
    
        default:
        break;
    }
    return 0;
}

int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    return 0;
}

//定义操作方法结构体变量并赋值
struct file_operations fops={

    .open=mycdev_open,
    .read=mycdev_read,
    .write=mycdev_write,
    .unlocked_ioctl=mycdev_ioctl,
    .release=mycdev_close,
};

static int __init mycdev_init(void)
{
    //字符设备驱动注册
    major=register_chrdev(0,"mychrdev",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功:major=%d\n",major);
    //向上提交目录
    cls=class_create(THIS_MODULE,"mychrdev");
    if(IS_ERR(cls))
    {
        printk("向上提交目录失败\n");
        return -PTR_ERR(cls);
    }
    printk("向上提交目录成功\n");

     int i;//向上提交三次设备节点信息
    for(i=0;i<3;i++)
    {
        dev=device_create(cls,NULL,MKDEV(major,i),NULL,"myled%d",i);
        if(IS_ERR(dev))
        {
            printk("向上提交设备节点失败\n");
            return -PTR_ERR(dev);
        }
    }
    printk("向上提交设备节点成功\n");
    dnode=of_find_compatible_node(NULL,NULL,"hqyj,myirq");
    if(NULL==dnode)
    {
        printk("of_find_compatible_node error\n");
        return -ENXIO;
    }
     printk("解析设备节点成功\n");
   //设备树节点解析
   lednode1=gpiod_get_from_of_node(dnode,"led1-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode1==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
     //设备树节点解析
   lednode2=gpiod_get_from_of_node(dnode,"led2-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode2==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
     //设备树节点解析
    lednode3=gpiod_get_from_of_node(dnode,"led3-gpio",0,GPIOD_OUT_LOW,NULL);
     if(lednode3==NULL)
    {
        printk("设备树节点解析失败\n");
        return ENXIO;
    }
    printk("设备树节点解析成功\n");
    return 0;
}
static void __exit mycdev_exit(void)
{ 
     
   //关灯
   gpiod_set_value(lednode1,0);
   gpiod_set_value(lednode2,0);
   gpiod_set_value(lednode3,0);
    
   //释放设备树节点空间
   gpiod_put(lednode1);
   gpiod_put(lednode2);
   gpiod_put(lednode3);

    int i;
    for(i=0;i<3;i++)
    {
        device_destroy(cls,MKDEV(major,i));
    }

    //销毁目录
    class_destroy(cls);
    //注销字符设备驱动
    unregister_chrdev(major,"mychrdev");

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

头文件

#ifndef __HEAD_H__
#define __HEAD_H__

#define LED_ON  _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)
#endif

应用层

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include<fcntl.h>
#include<unistd.h>

#include<sys/types.h>
#include<sys/stat.h>
#include<sys/ioctl.h>

#include"head.h"



int main(int argc, char const *argv[])
{
    int fd;
    fd=open("/dev/myled0",O_RDWR);
    if(fd<0)
    {
        perror("open error:");
        return -1;
    }
    int a;
    int b;
while (1)
{
  

    out:
    printf("选择要实现的功能\n");
    printf("请输入0关灯 1开灯\n");
    scanf("%d",&a);
    printf("LED 1,LED 2 LED 3");
    printf("请输入:");
    scanf("%d",&b);
    switch (a)
    {
    case 0:
        ioctl(fd,LED_OFF,b);  
        break;
     case 1:
        ioctl(fd,LED_ON,b);  
        break;
    default:
            printf("输入错误请重新输入\n");
            goto out;
    break;
    }
}
    return 0;
}

中断运用驱动控制led实验

串口led点灯实验结果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QQ防红跳转短网址生成网站完整源码

使用此源码可以生成QQ自动跳转到浏览器的短链接&#xff0c;无视QQ报毒&#xff0c;任意网址均可生成。 全新界面&#xff0c;网站背景图采用Bing随机壁纸 支持生成多种短链接 兼容电脑和手机页面 生成网址记录功能&#xff0c;域名黑名单功能 网站后台可管理数据 安装说明&am…

《图解HTTP》笔记2:http的构成

1&#xff0c;查看浏览器上面一个具体的http请求 浏览器地址栏输入网址&#xff1a;https://news.baidu.com/ 使用浏览器的开发者工具&#xff0c;查看网络中发送和接受的数据。 可以看到输入一个网址&#xff0c;浏览器和服务器进行了很多的交互。&#xff08;绿色部分&#…

【深蓝学院】移动机器人运动规划--第6章 模型预测控制(MPC)与运动规划--笔记

0. Outline 1. Reactive Control&#xff08;反应式控制&#xff09; 控制学中的 “Reactive Control” 通常指的是一种控制策略&#xff0c;它依赖于系统对特定事件或变化的即时反应&#xff0c;而不是按照预定的计划或策略行动。这种控制往往是基于当前的传感器输入来做出决…

盘点自动化汽车生产线设备 数据采集分析联合各设备

1.机器人自动装配线 机器人自动装配线已成为汽车制造业中的常见场景。这些机器人在汽车组装的各个环节发挥关键作用&#xff0c;从焊接和铆接到零部件组装。它们不仅提高了装配速度&#xff0c;还确保了产品的一致性&#xff0c;降低了废品率。 2.3D打印技术 3D打印技术正在汽车…

电商API接口接入|电子商务市场最简单的数据采集方法,你学到了吗?

小刘从某职业院校电子商务专业毕业后&#xff0c;-直在某品牌电商部负责运营工作&#xff0c;近期&#xff0c;同班同学小王邀请小刘加入创业大军&#xff0c;共同开设网店&#xff0c;销售家乡的螃蟹、鲜虾、扇贝等生鲜水产。 运营经验丰富的小刘决定&#xff0c;在创业开始前…

Jenkins的使用GIT(4)

Jenkins的使用GIT 20211002 我们使用 Jenkins 集成外部 Git 仓库&#xff0c;实现对真实代码的拉取和构建。在这里&#xff0c;我们选用 Coding/Github/Gitee 等都可以作为我们的代码源 1 生成公钥私钥 首先&#xff0c;我们先来配置公钥和私钥。这是 Jenkins 访问 Git 私有库…

mysql 事务详解一

前言 提到事务&#xff0c;大家肯定不陌生。在我们现实生活中也是存在的&#xff0c;比如我们去超市购物&#xff0c;然后去支付。虽然是两个步骤&#xff0c;必须保证同时成功&#xff0c;这个交易才可以完成。 如果这个场景&#xff0c;拿到我们购物系统&#xff0c;就是几…

智能高压森林应急消防泵|保障森林安全|深圳恒峰

随着科技的不断发展&#xff0c;我们的生活质量得到了显著提升。在森林保护领域&#xff0c;一项创新技术正在发挥着关键作用——智能高压森林应急消防泵。这种设备不仅提高了灭火效率&#xff0c;更为森林资源的安全保驾护航。 在过去&#xff0c;面对森林火灾&#xff0c;消防…

AIDL的工作原理与使用示例 跨进程通信 远程方法调用RPC

AIDL的介绍与使用 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android中用于定义客户端和服务端之间通信接口的一种接口定义语言。它允许你定义客户端和服务的通信协议&#xff0c;用于在不同的进程间或同一进程的不同组件间进行数据传递。AIDL通过…

LDR6020芯片驱动未来:TYPE-C桌面显示器的新篇章

TYPE-C接口桌面显示器&#xff0c;与传统显示器截然不同。它不仅在视频传输方面表现出色&#xff0c;还融入了创新的充电功能。利用显示器的DC电源&#xff0c;可以轻松转换成PD协议&#xff0c;为笔记本、任天堂等HOST设备提供稳定的充电服务。 兼容性&#xff1a;连接无忧 …

redis GEO 类型原理及命令详解

目录 前言 一、GeoHash 的编码方法 二、Redis 操作GEO类型 前言 我们有一个需求是用户搜索附近的店铺&#xff0c;就是所谓的位置信息服务&#xff08;Location-Based Service&#xff0c;LBS&#xff09;的应用。这样的相关服务我们每天都在接触&#xff0c;用滴滴打车&am…

文件夹无法压缩是怎么回事?分享3种简单的方法~

在日常使用电脑的过程中&#xff0c;我们经常需要对文件夹进行压缩&#xff0c;以节省存储空间或方便传输。然而&#xff0c;有时候我们可能会遇到文件夹无法压缩的情况&#xff0c;这可能会让人感到困惑。本文将探讨文件夹无法压缩的原因&#xff0c;并提供解决方法&#xff0…

谷粒商城-nginx搭建域名访问环境性能压测

nginx搭建域名访问环境 正向代理与反向代理 正向代理&#xff1a;客户端向代理服务器发请求并指定目标服务器&#xff0c;代理向目标服务器转交请求并将获得的内容返回给客户端。 反向代理&#xff1a;用户直接访问反向代理服务器就可以获得目标服务器的资源。反向代理服务器…

基于EasyCVR视频汇聚系统的公安网视频联网共享视频云平台建设思路分析(二)

一、需求分析 随着科技的飞速发展&#xff0c;视频监控联网技术在公安工作中发挥着越来越重要的作用。为了提高公安部门对各类事件的响应速度和处理能力&#xff0c;建设一个高效、稳定的公安视频联网共享云平台显得尤为重要。通过建设开放的视频联网共享云平台&#xff0c;实…

Android相机调用-libusbCamera【外接摄像头】【USB摄像头】 【多摄像头预览】

有的自定义系统&#xff0c;对于自己外接的USB摄像头&#xff0c;android原生的camera和camera2都无法打开&#xff0c;CameraX也用不了。这时候就要用libusbCamera&#xff0c;这个库可以打开摄像头&#xff0c;还可以多摄像头同时预览。本文主要是同时打开3个USB摄像头的项目…

C语言第二十九弹---浮点数在内存中的存储

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、浮点数在内存中的存储 1.1、练习 1.2、浮点数怎么转化为二进制 1.3、浮点数的存储 1.3.1、浮点数存的过程 1.3.2、浮点数取的过程 1.3、题目解析…

配置开机自启

进入任务计划程序 点击创建基本任务&#xff0c;按照向导一步一步进行下去

【数据结构】排序(1)

目录 一、概念&#xff1a; 二、直接插入排序&#xff1a; 三、希尔排序&#xff1a; 四、直接选择排序&#xff1a; 五、堆排序&#xff1a; 六、冒泡排序&#xff1a; 一、概念&#xff1a; 排序的概念&#xff1a; 使一串记录&#xff0c;按照其中的某个或某些关键字…

阿里巴巴店铺宝藏全揭秘:一键获取所有商品信息,电商业务效率飙升

阿里巴巴店铺所有商品API接口技术全解析 一、引言 在阿里巴巴这个全球领先的电商平台上&#xff0c;店铺所有商品API接口&#xff08;item_search_shop&#xff09;为开发者提供了一个便捷的途径&#xff0c;能够获取店铺的所有商品信息。通过这一接口&#xff0c;无论是数据…

PostgreSQL教程(十一):SQL语言(四)之数据类型

一、数值类型 数值类型由 2 字节、4 字节或 8 字节的整数以及 4 字节或 8 字节的浮点数和可选精度的十进制数组成。 下表列出了所有可用类型。 数值类型 名字存储长度描述范围smallint2 字节小范围整数-32768 到 32767integer4 字节常用的整数-2147483648 到 2147483647bigi…