当前位置: 首页 > news >正文

Linux驱动入门实验班——基础驱动模板(附百问网视频链接)

目录

一、GPIO子系统

1.确定引脚编号

2.写程序

二、中断函数

使用中断的流程

三、定时器

1.定时器两要素

2.使用定时器

四、交互流程解读

1、非阻塞访问和阻塞访问

2、POLL

3、异步通知

课程链接


一、GPIO子系统

如何驱动GPIO

1.确定引脚编号

可以在开发板上,执行以下命令查看

cat /sys/kernel/debug/gpio

2.写程序

①获得GPIO(gpio_request)

        函数原型

int gpio_request(unsigned int gpio, const char *label);
  1. unsigned int gpio:要请求的GPIO引脚号。
  2. const char *label:用于标识GPIO引脚的字符串。
  3. unsigned long flags:标志位,用于设置GPIO引脚的属性。

      返回值为整型,返回0表示请求成功,返回负数表示请求失败。

②设置方向(gpio_direction_input、gpio_direction_output)

        函数原型:

int gpio_direction_input(unsigned int gpio);

参数:

  • unsigned gpio:指定的GPIO引脚编号

返回值:

  • int:成功返回0,失败返回负数错误码
int gpio_direction_output(unsigned int pin, int value);

参数:

  • unsigned int pin: 指定的GPIO引脚编号
  • int value: 初始化输出的值,0代表低电平,1代表高电平

返回值:

  • 成功返回0,失败返回负数错误码

③读值、写值(gpio_get_value\gpio_set_value)

int gpio_get_value(unsigned int gpio);

参数:GPIO的引脚号

返回值:int类型,返回GPIO引脚的值,0表示引脚低电平,1表示引脚高电平

int gpio_set_value(unsigned int gpio, unsigned int value);

参数:GPIO的编号和要设置的值,

返回值:为0表示成功,其他值表示失败。

④释放GPIO(gpio_free)

二、中断函数

使用中断的流程

        ● 确定中断号 

        ● 注册中断处理函数

                ○ request_irq函数

函数原型:int request_irq(unsigned int irq,irqreturn_t (*handler)(int, void *, struct pt_regs *),unsigned long flags, const char *dev_name,void *dev_id);void free_irq(unsigned int irq, void *dev_id);
返回值:成功为0,失败负值,-EBUSY表示一个驱动正在使用这个中断线(不常见);
参数说明:unsigned int irq:请求的中断号,这个是系统预先设定好的,可以在irq.h中找到对应值;irqreturn_t (*handler) (int ,void *, struct pt_regs *):中断处理函数指针;unsigned long flags:中断标志位,可以是一个或者多个,它跟中断处理相关;const char *dev_name:中断名称,这个可以在系统运行后查看/proc/interrupts找到对应名称void *dev_id:主要用在共享型中断线中,它一般指向对应驱动的私有数据,以便中断释放的时候,只释放        指定驱动中的中断,它具有唯一性;当它不是共享型的时候,可以设定为NULL,但是建议将它指向设备结构体;

                ○ 参数细节 

request_irq函数的第一个参数是中断号,可以根据GPIO函数获得中断号:

        

int gpio_to_irq(unsigned gpio);
int gpiod_to_irq(const struct gpio_desc *desc);

第三个参数:

IRQF_DISABLED:如果被指定它,那么它会禁用其他所有中断,如果不设定,程序可以和其他中断程序同时运行;

IRQF_TIMER:为系统的定时器中断而准备的。

IRQF_SHARED:表示多个中断处理程序可以共享中断号,即如果没有设定只有一个中断程序使用这个中断号,如果设定了,多个中断程序可以共享这个中断号。

        ● 中断处理函数

                ○ 分辨中断

                ○ 处理中断

                ○ 清楚中断

三、定时器

1.定时器两要素

        ● 超时时间

        ● 处理函数

2.使用定时器

init_timer(timer)

函数功能:

        初始化timer。

void setup_timer(timer, fn, data)

函数功能:

        与init_timer()类似,fn为定时器回调函数,data为回调函数的参数。

参数:

  1. timer_id:定时器的ID,用于区分不同的定时器。
  2. interval:定时器的间隔时间,单位为毫秒。
  3. callback:定时器触发时调用的回调函数。

返回值:

        无返回值。

void add_timer(struct timer_list *timer)

函数功能:
        用于向 Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,定时器就会开始运行。

int mod_timer(struct timer_list *timer, unsigned long expires)

  ● 函数功能:
        用于修改定时值,如果定时器还没有激活的话, mod_timer 函数会激活定时器。

  ● 参数:
        timer:要修改超时时间的定时器。
        expires:修改后的超时时间。


返回值:

        0,调用 mod_timer 函数前定时器未被激活;

         1,调用 mod_timer 函数前定时器已被激活。

del_timer(struct timer_list * timer)

函数功能:
        用于删除一个定时器,不管定时器有没有被激活,都可以使用此函数删除。

四、交互流程解读

1、非阻塞访问和阻塞访问

当应用程序传入O_NONBLOCK标志位后,驱动程序会判断这个标志位,当然驱动程序可以选择判不判断这个标志位。

        ○ 如果APP传入该标志位当数组为空时,驱动程序就会立即返回。

        ○ 如果APP没有传入该标志位当数组为空时,驱动程序就会往下执行

wait_event_interruptible(gpio_wait, !is_key_buf_empty());

一直等待到当 !is_key_buf_empty()条件成立后,才继续往下执行。

2、POLL

poll 函数原型:#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);参数说明:1. fds:传入传出参数,指向struct pollfd类型数组的首元素,每个数组元素指定一个描述符以及对其关心的状态,关于这个结构体的说明在本小节后面阐述。2. nfds:指明fds指向的数组元素个数。3. timeout:该参数指定poll阻塞等待文件描述符就绪的毫秒数。会被四舍五入到系统时钟粒度。这个参数有三种可能:○ timeout设置为负数:一直阻塞等待,直到有描述符准备就绪;○ timeout设置为 0:不等待,检查描述符后直接返回。○ timeout设置为正数:阻塞等待timeout设置的毫秒数,期间有描述符准备就绪就返回,没有就等到时间结束返回。返回值:成功返回已准备就绪的描述符个数;超时返回0;失败返回-1。

3、异步通知

        APP

        驱动

课程链接

21_GPIO子系统简述_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1XK411D7wK?p=22&vd_source=3a9afee9fda50350a1c881b4325e007d

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MongoDB | MongoDB 终端查询
  • 详细分析Python链接Oracle的多种方式(附Demo)
  • “从头开始训练模型,几乎没有意义”
  • 【亲测有效!】ubuntu20.04和Centos7离线安装docker及nvidia-container-toolkit
  • 从零搭建React全家桶框架教程:快速搭建react+react-router+redux项目
  • 新专利:温室土壤温湿度预测模型构建方法和程序产品
  • day09——集合ArrayList
  • vue使用富文本编辑器+自由伸缩图片
  • 在Linux下编译安装Python3.10.0及以上环境(解决了openssl依赖问题)
  • javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级
  • git update-git-for-windows 升级失败
  • django项目中通用的分页组件
  • 【深度学习实践】基于深度学习的图像去雾算法-ChaIR-实践
  • Unity游戏开发
  • unity 本地使用Json(全套)
  • centos安装java运行环境jdk+tomcat
  • const let
  • git 常用命令
  • php面试题 汇集2
  • Python 基础起步 (十) 什么叫函数?
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • vue脚手架vue-cli
  • vue--为什么data属性必须是一个函数
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 官方解决所有 npm 全局安装权限问题
  • 两列自适应布局方案整理
  • 前端路由实现-history
  • 如何借助 NoSQL 提高 JPA 应用性能
  • 深入浏览器事件循环的本质
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 无服务器化是企业 IT 架构的未来吗?
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 最简单的无缝轮播
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • # 日期待t_最值得等的SUV奥迪Q9:空间比MPV还大,或搭4.0T,香
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (day 12)JavaScript学习笔记(数组3)
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (分享)自己整理的一些简单awk实用语句
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (三)c52学习之旅-点亮LED灯
  • (十三)Maven插件解析运行机制
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四)js前端开发中设计模式之工厂方法模式
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)JAVA中的堆栈
  • (转载)Google Chrome调试JS
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .gitignore文件---让git自动忽略指定文件
  • .java 9 找不到符号_java找不到符号