LED驱动 中断

news2024/10/5 15:34:24

1、用字符设备驱动框架和平台设备驱动框架实现LED驱动

1.1 用字符设备驱动框架-----》led2

        控制led2闪烁

        1.应用层:

                1 open(“/dev/haha0”)

                2 while(1)

                        ioctl(fd,LED_ON);

                        sleep();

                        ioctl(fd,LED_OFF);

                        sleep(1);

        2. 驱动层:        

                HelloIoctl(pFile,cmd,arg)

                {

                        switch(cmd)

                                case LED_ON:

                                        {

                                                led_on();-------》点灯 内核函数  设备树文件

                                                 gpio_set_value_cansleep()(gpio管脚编号,1)

                                           }

                                case LED_OFF:

                                            {

                                                 led_off();

                                                 gpio_set_value_cansleep()(gpio管脚编号,0)

                                            }

                    }

                    1  操作LED-----》设备树文件-----》增加LED节点--》make dtbs--》新exynos4412

                    2  如何操作led硬件地址?使用内核提供的函数

                        struct device_node  *p=of_find_node_by_path(“/fs4412-led”)

                        gpi管脚编号 = of_get_named_gpio(p, "led", 0)

                        gpio_set_value_cansleep(gpio管脚编号, val)

虚拟机:

        1.修改设备树文件---》添加led2节点--》make dtbs---》exynos4412---fs4412

        2.cp exynos4412-fs4412.dtb  /tftpboot

        3.修改hello.c----》使用linux3.14下的Makefile编译---》hello.ko

        4.cp hello.ko  /source4/rootfs

        5.arm-none-linux-gnueabi-gcc  -o test test.c

        6.cp test /source4/rootfs

开发板:

        1.启动开发板,进入u-boot模式

           修改ipaddr   serverip   gatewayip  bootargs参数

        2.重启开发板,加载内核设备树,挂接网络文件系统

        3.root@farsight#insmod hello.ko

                                   dmsg |tail       

                                   ./test-----------》观察led2是否闪烁?

1.2 平台设备驱动框架(ioremap)-----》led2

        ioremap-----》内核函数---------》内核&驱动

        作用:将物理地址映射到内核虚拟地址

        void _iomem *ioremap(unsigned long paddr,unsigned long size)

                 paddr:需要映射的物理地址

                 size:需要映射的字节数

                 返回值:映射成功后生产内核虚拟地址 

        cpu为IO外设提供了两种编址方式:

                第一种:IO映射方式(IO外设独立编址),cpu为外设专门实现了一个单独的地址空间,为IO地址空间,cpu通过专门的IO指令来访问这一地址空间。

                第二种:内存映射方式(IO外设统一编址),RISC系统的CPU通常会对IO外设统一编址,通常只实现一个物理地址空间,IO外设端口像内存一样被统一编址,CPU可以像访问内存一样访问IO端口。

 static inline void writel(u32b,volatile void _iomem *addr)

 作用:将数据写入到内核虚拟地址

b:通过内核虚拟地址向物理地址写入的值

*addr:指向内核虚拟地址的指针

static inline unsigned int readl(const volatile void _iomem *addr)  

作用:通过内核虚拟地址读取对应物理地址的值

*addr:指向内核虚拟地址的指针

返回值:从内核虚拟地址读到的对应物理地址的值

led2_on()
            writel(1,内核虚拟地址)

         驱动层:
            HelloIoctl(pfile,cmd,arg)
            {
                switch(cmd)
                    case LED_ON:
                        {
                        led_on();--->点灯  内核函数  设备树文件
                        writel(g_buf,1)
                        }
                    case LED_OFF:
                        {
                        led_off()
                        gpio_set_value_cansleep(gpio管脚编号,0)
                        }
            }
    helloprobe(struct platform_device *pdev)-->pdev->resource
                ioremap(pdev->resource[0].start,g_buf)

2、中断

        定义:是指CPU在执行程序的过程中插入了另外一段程序的执行过程。

        发起中断的方式:1 软中断---》通过软件的方式发起的,是可控的

                                     2 硬件中断---》由于硬件故障产生的,不可控的

 裸机中断:k2按键接到了一个gpio管脚,这个管脚是个gic(中断控制器)的入口相连的,当按下k2按键发出一个信号,这个信号到达gpio管脚,这个管脚被识别为一个中断信号,中断信号被送到gic内部,gic对这个中断信号做出处理,将中断信号送到cpu,cpu处理k2对应的中断程序。

系统中断:

功能:按下k2按键 触发中断

在Linux设备驱动中,要使用中断的设备需要申请中断和释放中断

request_irq----》给设备请求一个中断

free_irq----》释放中断

static inline int_must check

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)

作用:请求中断,给指定的中断号对应的外设请求一个中断处理函数

irq:从设备资源中获取到中断号

handler:中断处理程序 typedef irqreturn_t (*irq_handler_t) (int, void *);

flags:中断属性,可以指定中断的触发方式和处理方式

*name:请求中断的设备名称

*dev:NULL

void free_irq (unsigned int irq, void *dev_id)

作用:释放中断

irq:从设备资源中获取到的中断号

*dev_id: NULL

platfrom_get_resource(pdev,IOERSOURCE_IRQ,0)-->获取资源
        struct resource *platform_get_resource(struct platform_device *dev,
                       unsigned int type, unsigned int num)
            作用:从平台设备中获取资源
            *dev:指向平台设备的指针
             type:资源类型
            num:资源索引
            返回值:返回得到的资源

测试步骤:
            虚拟机:
            1 修改设备树文件--》添加fs4412-key节点 --》make dtbs
                cp exynos4412-fs4412.dtb  /tftpboot
            2 编译hello.c-->交叉编译---》hello.ko
            3 cp hello.ko  /source4/rootfs
            开发板:
            1 启动开发板 配置ip相关项 配置bootarg为nfs
            2 重启开发板
                root@farsight#insmod hello.ko
                    手动按下开发板上的k2按键
                root@farsight#dmesg |tail-->查看中断处理函数的打印

中断下半部

        一般来说,操作系统中的中断越短越好,如果系统中的中断处理时间过长,可以将中断处理过程分为两部分来处理。

        第一部分,专门接收和响应中断请求(登记中断)-----》上半部

        第二部分,专门来处理中断的耗时业务逻辑(处理耗时操作)----》下半部

        Linux系统中的中断处理也是分成上半部和下半部来完成的。下半部的处理方法有以下:

        tasklet(小片任务)、工作队列、内核定时器

        1.1 tasklet---------》小“片”任务        

                1 声明一个tasklet

                DECLARE_TASKLET(name,unfc,data) 用这个宏函数声明一个小任务

                name:小任务的名称

                func:小任务对应的处理函数 void (*func)(unsigned long);

                data:传给func函数的入参

        2. 调度小任务-------》handler

                tasklet_schedule(&name)

                static inline void tasklet_schedule(struct tasklet_struct *t)

                作用:调度小任务

                *t : 指向小任务名称的指针

                

        1.2 工作队列

                是指在中断处理中可以把耗时的操作推出执行,可以把耗时的操作交到工作队列中等待被执行,内核中有一个线程events会去工作队列中找等待被执行的工作,然后执行这个等待的工作(工作:中断处理中耗时的那部分操作)。

        1 定义一个工作队列

                struct work_struct my_wq;

        2 初始化工作队列

                INIT_WORK(_work, _func)

                _work:指向工作队列的指针

                _func:工作队列对应的处理函数

                typedef void (*work_func_t)(struct work struct *work);

        3 调度工作队列

                schedule_work(&my_wq);

        1.3 内核定时器

        1  struct time_list mytimer;定义一个内核定时器

        2  helloprobe:

                init_timer(mytimer);初始化内核定时器

                mytimer.funcion = my_func;------》用来处理耗时的操作

                mytimer.expires------》时间值------》表示超时时间

                add_timer(&mytimer)-------》启动定时

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

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

相关文章

java的社区养老服务系统 ssm空巢老人

创新点: 1、根据时间、类型统计用户下单记录,形成可视化图形(饼状图) 2、根据用户爱好推荐项目 包含模块:关于我们、联系我们、外链信息、资讯类型、服务资讯、服务类型、服务项目、案例类型、服务案例、讨论类型、讨论…

引入Tuning function design的自适应反步控制方法 上篇

引入Tuning function design的自适应反步控制方法 上篇 目录 引入Tuning function design的自适应反步控制方法 上篇尝试用推迟参数设计解决高阶不匹配系统的控制器设计问题问题描述控制器设计小结上一篇文章写了如何通过推迟参数设计的方法来解决不匹配条件下的系统反步控制设…

【原型设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

简介 原型模式(Prototype Pattern)是一种创建型设计模式,使你能够复制已有对象,而无需使代码依赖它们所属的类,同时又能保证性能。 这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创…

IT项目管理之软件测试

1. 定义 软件测试是使用人工或者自动的手段来运行或者测定某个软件系统的过程,其目的在于检验它是否满足规定的需求或弄清预期结果与实际结果之间的差别。 在软件投入使用前,要经过一系列的严格测试,才能保证交付质量。 2. QC & QA &a…

会声会影导入视频是黑色的 会声会影导入视频只有声音

会声会影是一款功能很成熟的视频编辑软件,其友好的界面设计能照顾到初学者的需求,同时配置的强大功能可满足进阶者的需要。不过由于或硬件或软件的原因,可能会出现会声会影导入视频是黑色的,会声会影导入视频只有声音的问题。本文…

Docker的实际应用

一、 数据持久化 我们什么情况下要做数据持久化呢? 一定是在做容器之前先预判好哪些文件是要永久存储的, 而不会跟着它容器的一个生命周期而消失。 比如说配置文件、 日志文件、 缓存文件或者应用数据等等。 数据初始化有三种类型。 第一种 volumes&…

浏览器缓存策略:强缓存和协商缓存

浏览器缓存:其实就是在本地使用的计算机中开辟一个内存区,同时也开辟一个硬盘区,作为数据传输的缓冲区,然后利用这个缓冲区来暂时保护用户以前访问的信息通常浏览器的缓存策略分为两种:强缓存和协商缓存,强…

Vmware 搭建 Bitnami GitLab CE

Vmware 搭建 Bitnami GitLab CE 下载 Bitnami GitLab CE导入到 Vmwaressh 登录到虚拟机获取 root 用户密码访问 GitLab CE关机命令扩展磁盘配置 tls 证书安装 GitLab Runner注册 GitLab Runner其他,配置 docker 信任自签名证书 下载 Bitnami GitLab CE 下载地址&am…

Photoshop如何使用基础功能?

文章目录 0.引言1.菜单栏2.工具箱 0.引言 笔者从开始科研时就接触过Photoshop(PS),这么多年一直用着感觉有些陌生,在每次使用PS时总感觉有些抵触,这状态说明还未入门。为了入门PS,笔者从头熟悉PS的菜单和工…

一文弄懂Jupyter的配置与使用(呕心沥血版)

Jupyter 是一个基于 Web 的交互式计算平台,使用户能够创建和共享文档,这些文档包含实时代码、方程式、可视化图表和解释文字。Jupyter 在数据分析领域被广泛应用,它提供了一个直观、交互式的操作界面,使得用户能够更容易地探索数据…

MybatisPlus入门和分页和条件查询里面的条件和null值的处理方式和查询投影和查询条件设置

MybatisPlus 简化了mybatis之前的在springboot整合MyBatis时需要自己写sql语句在接口中&#xff0c;现在只需要让接口继承BaseMapper<实体类>&#xff0c;然后在测试类中接口.增删改查方法&#xff08;&#xff09;即可 不用像springboot整合mybatis一样勾选spring web…

【Python】【进阶篇】9、Django路由系统精讲

目录 Django路由系统精讲1. Django 路由系统应用1&#xff09;配置第一个URL实现页面访问2&#xff09;正则与正则分组使用3&#xff09;正则捕获组使用 2. path()与re_path() Django路由系统精讲 在《URL是什么》一节中&#xff0c;我们对 URL 有了基本的认识&#xff0c;在本…

易基因:禾本科植物群落的病毒组丰度/组成与人为管理/植物多样性变化的相关性 | 宏病毒组

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 现代农业通过简化生态系统、引入新宿主物种和减少作物遗传多样性来影响植物病毒的出现。因此&#xff0c;更好理解农业生态中种植和未种植群落中的病毒分布&#xff0c;以及它们之间的病…

解析Mybaits核心配置文件属性

目录 1.environment 2.transactionManager 3.dataSource 4.peoperties 5.mapper 先来看看mybatis核心配置文件代码 <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN&qu…

02- stable diffusion的基本使用

stable diffusion的基本使用 对应视频 https://www.bilibili.com/video/BV1Q14y1f7XJ/https://www.bilibili.com/video/BV1av4y1E74C/ 一、下载 1.1 官方github&#xff1a; 官方github&#xff1a; GitHub - Stability-AI/stablediffusion: High-Resolution Image Synth…

Linux进程命令

目录 前言 基本命令 PS命令 语法 字段解释 栗子 top命令 语法 参数解释 栗子 kill命令 语法 参数解释 栗子 前言 进程是正在执行的一个程序或命令&#xff0c;每一个进程都是一个运行的实体&#xff0c;都有自己的地 址空间&#xff0c;并占用一定的系统资源。 基本命…

滑动奇异频谱分析:数据驱动的非平稳信号分解工具(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

线程池四种拒绝机制 实现 及执行日志

目录 目录 目录 创建线程池 测试代码 运行线程 全量代码 日志 AbortPolicy 报出异常模式 DiscardPolicy 放弃机制啥也不处理 DiscardOldestPolicy 放弃机制&#xff0c;放弃列队最早进入的 CallerRunsPolicy 交给主线程执行 创建线程池 public static ExecutorServi…

这篇文带你从入门级开始学习网络安全—认识网络安全

随着网络安全被列为国家安全战略的一部分&#xff0c;这个曾经细分的领域发展提速了不少&#xff0c;除了一些传统安全厂商以外&#xff0c;一些互联网大厂也都纷纷加码了在这一块的投入&#xff0c;随之而来的吸引了越来越多的新鲜血液不断涌入。不同于Java、C/C等后端开发岗位…

【Vue】Vue 前端设计模式梳理

文章目录 一、什么是设计模式&#xff1f;二、设计几个原则三、常见的设计模式及实际案例【1】单例模式1. 什么是单例模式&#xff1f;2.Vue中的单例模式 【2】工厂模式1. 什么是工厂模式&#xff1f;2.Vue中的工厂模式 【3】策略模式1. 什么是策略模式&#xff1f;2.策略模式的…