驱动开发 linux内核GPIO子系统、及其新版API的概念和使用,linux内核定时器

1、GPIO子系统

概述:每一个芯片厂商生产出芯片后会给linux提供一个当前芯片中gpio外设的驱动,我们只需要调用对应的厂商驱动就可以完成硬件的控制。而linux内核源码中的gpio厂商驱动有很多,linux内核个会对厂商驱动做一些封装,会提供一系列的API,我们在自己编写设备驱动中只需要调用这些API即可访问对应厂商驱动,进而完成GPIO的控制。

2、框图

在用户层编写控制硬件的控制裸机,然后设备驱动层调用内核提供的API去管理厂商驱动,完成GPIO的控制,获取GPIO编号并申请,然后到核心层会有厂商驱动的相关细节,有上层接口提供给我们使用,最后会在厂商驱动层,完成对硬件层的控制。

3、GPIO子系统相关API

1、解析GPIO相关的设备数节点

cs 复制代码
struct device_node *of_find_node_by_path(const char *path)
//path 设备树节点路径
//返回值
//成功返回目标节点首地址,失败返回NULL

2、根据解析的相关GPIO节点信息获取GPIO编号

cs 复制代码
#include<linux/of_gpio.h>
int of_get_named_gpio(struct device_node *np,const char *propname,int index)
//功能:获取GPIO编号
参数:
    np:设备树节点指针
    proname:gpio编号信息对应到的键名
    index:管教在这个属性键值对中的索引号
返回值:成功返回GPIO编号,失败返回错误码

3、向内核申请要使用的GPIO编号

cs 复制代码
int gpio_request(unsigned gpio,const char *label)
功能:申请GPIO编号
参数:
    gpio:申请的GPIO编号
    label:标签,填NULL
返回值:成功返回0,失败返回错误码

4、将gpio编号对应的gpio管脚设置为输入

cs 复制代码
int gpio_direction_input(unsigned) gpio
功能:将gpio编号对应的gpio管脚设置为输入
参数:
    gpio:gpio编号
返回值:成功返回0,失败返回错误码

5、将gpio编号对应的gpio管脚设置为输出

cs 复制代码
int gpio_direction_output(unsigned gpio,int value)
功能:将gpio编号对应的gpio管脚设置为输出
参数: gpio:gpio编号
        value:默认的输出值 (1)高电平 (0)低电平
返回值:成功返回0,失败返回错误码

6、设置gpio编号对应的gpio管脚,输出高低电平

cs 复制代码
void gpio_set_value(unsigned gpio,int value)
功能:设置gpio编号对应的gpio引脚,输出高低电平
参数: gpio编号
        value:默认的输出值
返回值:无

7、获取gpio编号对应的GPIO引脚状态值

cs 复制代码
int gpio_get_value(unsigned gpio)

gpio:gpio编号
返回值:1(高电平) 0(低电平)

8、释放GPIO编号

cs 复制代码
void gpio_free(unsigned gpio)

4、linux内核定时器

linux内核定时器是设置一个定时事件,当时间达到之后会执行和定时器处理函数,可以执行一些周期性任务。

4.1步骤

分配一个定时器对象

初始化定时器对象

注册定时器

启用定时器

注销定时器

4.2jiffies

是内核中用来保存内核节拍数的一个变量,她的值从内核启动就不断从0开始增加

4.3内核频率

内核节拍数一秒钟增加的数量被称作为内核的频率,内核的频率在内核顶层目录下的.config文件中被设置

4.4内核定时器对象分析

cs 复制代码
struct timer_list {
    struct hlist_node  entry;//用于构成一个对象链表
    unsigned long       expires;//设置的时间阈值  定时一秒:jiffies+CONFIG_HZ
    void            (*function)(struct timer_list *);//定时器处理函数指针
    u32         flags;//标志,新版才有,填0即可
    };

4.5API

cs 复制代码
1.分配定时器对象
struct timer_list mytimer;
2.初始化定时器对象
void timer_setup(struct timer_list *timer,
            void (*func)(struct timer_list *), unsigned int flags);
 功能:初始化定时器对象,定时器对象中的expires需要手动初始化
 参数:
 timer:定时器对象指针
 func:定时器处理函数的函数指针
 flags:0
 返回值:无
3.void add_timer(struct timer_list *timer)
功能:注册定时器对象并启用定时器
参数:
    timer:定时器对象指针
返回值:无
4.再次启用定时器
int mod_timer(struct timer_list *timer, unsigned long expires)
功能:再次启用定时器
参数:
timer:定时器对象指针
expires:重新设置的定时器阈值
返回值:启用之前没启用的定时器返回0,启用之前启用的定时器返回1

5.注销定时器对象
int del_timer(struct timer_list *timer)
相关推荐
计算机安禾4 分钟前
【Linux从入门到精通】第12篇:进程的前后台切换与信号控制
linux·运维·算法
Cyan_RA911 分钟前
如何利用 Paddle-OCR 丝滑进行复杂版面 PDF 的批量化OCR处理?
java·linux·python·ocr·conda·paddle·surya
AC赳赳老秦13 分钟前
OpenClaw与Notion联动:自动同步工作任务、整理笔记,实现高效管理
运维·人工智能·python·数学建模·自动化·deepseek·openclaw
上海云盾安全满满14 分钟前
服务器带宽一直跑高,是什么情况
运维·服务器
.柒宇.14 分钟前
信创实战:银河麒麟 V10 服务器安装、网络配置与 Docker 环境搭建
linux·运维·docker·国产信创·麒麟操作系统
云动课堂17 分钟前
【运维实战】企业级SFTP 文件服务 · 一键自动化部署方案 (适配AnolisOS /openEuler /CentOS)
运维·centos·自动化
杨浦老苏18 分钟前
Docker容器管理面板Dockhand
运维·docker·群晖
diygwcom23 分钟前
jeecg验证码在centos报错
linux·运维·centos
努力的搬砖人.25 分钟前
配置 Docker 镜像加速器
运维·docker·容器
坚持就完事了34 分钟前
Linux中的tar命令
linux·运维·服务器