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

《嵌入式驱动(六):pinctrl子系统和gpio子系统驱动》

一、Linux驱动分层思想    

1.设备与驱动分离思想

        和设备相关的信息放到设备树里,驱动里面只写对于设备的操作方法

2.驱动分层思想

        把相同的操作提出来,构建子系统,子系统可以完成这些通用的操作(GPIO,引脚)

二、pinctrl子系统(linux内核中自带该系统)

        我们通过设备树来使用pinctrl子系统。pinctrl子系统中有2个概念:
pin controller(一种引脚的定义和实现):它对应IOMUX来复用引脚
client device(使用某种引脚定义方向):pinctrl子系统的客户,即使用pinctrl系统的设备。

        在imx6ull-alientek-emmc.dts文件中iomuxc节点中定义controller引脚配置

pinctrl_putekey: putekey {
fsl,pins = <MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0xf0b0>;
};


在对应的putekey节点中引用该方案

putekey {
#address-cells = <1>;
#size-cells = <1>;
compatible = "pute-key";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_putekey>;
reg = <0x209C004 0x4
0x209C000 0x4>;
status = "okay";
};

三、gpio子系统

在设备中指定节点使用的GPIO引脚编号

1. 在设备中指定节点使用的GPIO引脚编号,格式如下:

putekey {
#address-cells = <1>;
#size-cells = <1>;
compatible = "pute-key";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_putekey>;
gpio-key = <&gpio1 18 GPIO_ACTIVE_LOW>;
status = "okay";
};

在putekey节点里面修改

2. 在驱动中编写代码

        2.1.通过of_get_named_gpio从设备树节点中解析并获取指定GPIO硬件编号

        2.2.通过gpio_request申请GPIO资源

        2.3.通过gpio_direction_input/output设置GPIO的方向

        2.4.通过gpio_get_value 读取输入引脚电平
gpio_set_value设置输出引脚电平

        2.5.释放GPIO,gpio_free()

四、代码

以key为例

        pinctrl子系统

 pinctrl_putekey: putekey {fsl,pins = <MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0XF0B0>;};  

        gpio子系统

putekey {#address-cells = <1>;#size-cells = <1>;compatible = "pute-key";pinctrl-names = "default";pinctrl-0 = <&pinctrl_putekey>;gpio-key = <&gpio1 18 GPIO_ACTIVE_LOW>;status = "okay";};

        key_app.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>int main(void)
{int fd = 0;int stat = 0;fd = open("/dev/misc_key", O_RDWR);if (-1 == fd){perror("fail to open");return -1;}while (1){read(fd, &stat, sizeof(stat));printf("stat = %d\n", stat);}close(fd);return 0;
}

        Makefile

#模块名
modulename := key_app#编译工具链
CC := arm-linux-gnueabihf-gcc all:$(CC) $(modulename).c -o $(modulename)cp $(modulename) ~/nfs/rootfs .PHONY:
clean:rm $(modulename)
distclean:rm $(modulename)rm ~/nfs/rootfs/$(modulename)

        key_drv.c

#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/of_address.h>
#include <linux/of.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>static struct device_node *pkeynode = NULL;
static int gpiokey = 0;static ssize_t key_read(struct file *fp, char __user *puser, size_t n, loff_t *off)
{int status = 0;unsigned long nret = 0;if (gpio_get_value(gpiokey)) {status = 0;} else {status = 1;}nret = copy_to_user(puser, &status, sizeof(status));if (nret) {pr_info("copy_to_user failed\n");return -1;}return nret;
}static struct file_operations fops = {.owner = THIS_MODULE,.read = key_read,
};static struct miscdevice misc_key = {.minor = MISC_DYNAMIC_MINOR,.name = "misc_key",.fops = &fops,
};static __init int key_drv_init(void)
{int ret = 0;ret = misc_register(&misc_key);if (ret) {pr_info("misc_register failed\n");return -1;}pkeynode = of_find_node_by_path("/putekey");if (NULL == pkeynode) {pr_info("of_find_node_by_path failed\n");return -1;}gpiokey = of_get_named_gpio(pkeynode, "gpio-key", 0);if (gpiokey < 0) {pr_info("of_get_named_gpio failed\n");return -1;}ret = gpio_request(gpiokey, "pute-key-gpio");if (ret) {pr_info("gpio_request failed\n");return -1;}ret = gpio_direction_input(gpiokey);if (ret) {pr_info("gpio_direction_input failed\n");return -1;}pr_info("key_drv_init success\n");return 0;
}static __exit void key_drv_exit(void)
{int ret = 0;gpio_free(gpiokey);ret = misc_deregister(&misc_key);if (ret) {pr_info("misc_deregister failed\n");return;}pr_info("key_drv_exit success\n");return;
}module_init(key_drv_init);
module_exit(key_drv_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("pute");

        Makefile

#模块名
modulename := key_drv#内核路径
kerdir := /home/linux/imx6ull/kernel/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek#加入内核编译中
obj-m += $(modulename).o#当前路径
pwd := $(shell pwd)all:make -C $(kerdir) modules M=$(pwd)cp $(modulename).ko ~/nfs/rootfs .PHONY:
clean:make -C $(kerdir) modules M=$(pwd) clean
distclean:make -C $(kerdir) modules M=$(pwd) cleanrm ~/nfs/rootfs/$(modulename).ko

        Makefile

#模块名
modulename := keyall:make -C $(modulename)_drvmake -C $(modulename)_app.PHONY:
distclean:make -C $(modulename)_drv distcleanmake -C $(modulename)_app distclean 
clean:make -C $(modulename)_drv cleanmake -C $(modulename)_app clean
http://www.dtcms.com/a/446880.html

相关文章:

  • 怎么建立一个网站让百度搜到北京病例最新消息今天
  • 六安网站建设培训成品网站能用吗
  • 简道云系统开发(八)国内主流的CRM系统优劣势分析
  • 杭州英文网站建设优秀作文网站推荐
  • 福州网站建设哪个好怎么做网站的搜索功能
  • 【算法】树上启发式合并 (CCPC2020长春 F. Strange Memory)
  • C#程序代码
  • 电商网站如何做引流广点通广告投放平台登录
  • 《API网关在企业研发协作平台中的深度定制与流程化效能重构》
  • 宁波网站排名优化seo小型网站建设价格低
  • 加强协会网站建设意义新乡百度网站优化排名
  • 企业网站优化做什么杭州网站建设前三
  • 蓝星旋钮旋转跳动大异常解决办法
  • 经营网站需要什么资质下载app软件到手机
  • 松江建设网站公司oss cdn wordpress
  • 做视频网站代码精品应用下载安装
  • 门户网站建设公司市场如何编写网站开发文档
  • Android 配置多个 cmake
  • 阿里云企业建站教程wordpress 明月浩空
  • AI智能体赋能文化传承与创新领域:社群身份认同的数字空间重构与文化融合策略
  • c 网站开发实例教学游戏网站建设系统介绍
  • 唐山建设信息网站国内网站
  • 解决leetcode第3704题统计和为N的无零数对
  • 全网通官方网站wordpress会员积分邀请
  • 吉林省高等级公路建设局死人网站网站qq登录原理
  • 网站专题页设计it运维平台
  • 核辐射探测器典型脉冲波形
  • 12306网站为什么做不好黄页88网官网
  • 网站建设讯美品牌购买平台
  • Python 集合速查:去重、并交差运算一文掌握