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


    1、GPIO子系统

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

    2、框图

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

    3、GPIO子系统相关API

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

    1. struct device_node *of_find_node_by_path(const char *path)
    2. //path 设备树节点路径
    3. //返回值
    4. //成功返回目标节点首地址,失败返回NULL

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

    1. #include
    2. int of_get_named_gpio(struct device_node *np,const char *propname,int index)
    3. //功能:获取GPIO编号
    4. 参数:
    5. np:设备树节点指针
    6. proname:gpio编号信息对应到的键名
    7. index:管教在这个属性键值对中的索引号
    8. 返回值:成功返回GPIO编号,失败返回错误码

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

    1. int gpio_request(unsigned gpio,const char *label)
    2. 功能:申请GPIO编号
    3. 参数:
    4. gpio:申请的GPIO编号
    5. label:标签,填NULL
    6. 返回值:成功返回0,失败返回错误码

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

    1. int gpio_direction_input(unsigned) gpio
    2. 功能:将gpio编号对应的gpio管脚设置为输入
    3. 参数:
    4. gpio:gpio编号
    5. 返回值:成功返回0,失败返回错误码

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

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

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

    1. void gpio_set_value(unsigned gpio,int value)
    2. 功能:设置gpio编号对应的gpio引脚,输出高低电平
    3. 参数: gpio编号
    4. value:默认的输出值
    5. 返回值:无

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

    1. int gpio_get_value(unsigned gpio)
    2. gpio:gpio编号
    3. 返回值:1(高电平) 0(低电平)

    8、释放GPIO编号

    1. void gpio_free(unsigned gpio)

    4、linux内核定时器

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

    4.1步骤

           分配一个定时器对象

            初始化定时器对象

            注册定时器

            启用定时器

            注销定时器

    4.2jiffies

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

    4.3内核频率

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

    4.4内核定时器对象分析

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

    4.5API

    1. 1.分配定时器对象
    2. struct timer_list mytimer;
    3. 2.初始化定时器对象
    4. void timer_setup(struct timer_list *timer,
    5. void (*func)(struct timer_list *), unsigned int flags);
    6. 功能:初始化定时器对象,定时器对象中的expires需要手动初始化
    7. 参数:
    8. timer:定时器对象指针
    9. func:定时器处理函数的函数指针
    10. flags:0
    11. 返回值:无
    12. 3.void add_timer(struct timer_list *timer)
    13. 功能:注册定时器对象并启用定时器
    14. 参数:
    15. timer:定时器对象指针
    16. 返回值:无
    17. 4.再次启用定时器
    18. int mod_timer(struct timer_list *timer, unsigned long expires)
    19. 功能:再次启用定时器
    20. 参数:
    21. timer:定时器对象指针
    22. expires:重新设置的定时器阈值
    23. 返回值:启用之前没启用的定时器返回0,启用之前启用的定时器返回1
    24. 5.注销定时器对象
    25. int del_timer(struct timer_list *timer)

  • 相关阅读:
    Linux - dsta 命令详解
    技能学习链接
    【滤波器】基于matlab实现微波带低通高通带通滤波器设计
    99%的亚马逊运营都不知道爆单小技巧——社媒促销代码
    【自动化脚本】常用自动化脚本一览【持续更新】
    html jquery vue php 混合使用
    关于自定义 HttpServletRequestWrapper 后续读不到参数的问题
    SpringBoot整合Swagger3,赶紧整起来!
    将来进行时习题
    【Go语言】Go语言中的流程控制
  • 原文地址:https://blog.csdn.net/weixin_60039521/article/details/132984151