【学习笔记:GPIO驱动开发】

这篇具有很好参考价值的文章主要介绍了【学习笔记:GPIO驱动开发】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

gpio_request

快门驱动芯片ms8837 输入信号是两个GPIO,最开始是在camera 驱动中调用 gpio_request() 申请GPIO,当 open/close camera 的时候就可以调用 gpio_direction_output() 来控制快门的开、关。
在dts 中加入引脚配置:

kd_camera_hw1:kd_camera_hw1@1a040000 {
		compatible = "mediatek,imgsensor";
		cam2_vcama_d_ext = <&pio 162 0x0>; 
		cam_shutter_in1 = <&pio 163 0x0>;
		cam_shutter_in2 = <&pio 164 0x0>;
	};

在camera 驱动中调用gpio_request() 去控制GPIO:

UINT32 XXX_SensorInit(PSENSOR_FUNCTION_STRUCT *pfFunc)
{
	/* To Do : Check Sensor status here */
	int ret;
	struct device_node * node;
	SENSORDB("%s",__func__);
	if (pfFunc!=NULL)
		*pfFunc=&SensorFuncXXX;
	node = of_find_compatible_node(NULL, NULL, "mediatek,imgsensor");
	if (!node) {
		printk(" Get cust camera node failed!\n");
		return -ENODEV;
	}
	cam_shutter_in1  = of_get_named_gpio(node, "cam_shutter_in1", 0);
	ret = gpio_request(cam_shutter_in1,"cam_shutter_in1");
	if (ret) {
		printk("error: cam_shutter_in1 gpio_request\n");
		return -1;
	}
			
	ret = gpio_direction_output(cam_shutter_in1, 1);
	if (ret) {
		printk("error %s : cam_shutter_in1  gpio_direction_output failed\n",__func__);
		ret = -1;
	}
	cam_shutter_in2  = of_get_named_gpio(node, "cam_shutter_in2", 0);
	ret = gpio_request(cam_shutter_in2,"cam_shutter_in2");
	if (ret) {
		printk("error: cam_shutter_in2 gpio_request\n");
		return -1;
	}
		
	ret = gpio_direction_output(cam_shutter_in2, 0);
	if (ret) {
		printk("error %s : cam_shutter_in2  gpio_direction_output failed\n",__func__);
		ret = -1;
	}
	printk("cam_shutter_in1:%d, cam_shutter_in2:%d\n", cam_shutter_in1, cam_shutter_in2);
	return ERROR_NONE;
} /* SensorInit() */

这样在open/close camera 的时间是可以正常调用的,但后续的开发遇到了问题,原来是想通过camera 的 feature control 来发送快门开、关指令,但是发现非常复杂,快门指令是要结合3A处理的,就先放弃了,转而用 ioctl 的方法去实现。

SYSFS

看其它帖子,控制GPIO最简单的方法是通过SYSFS:
export_store: invalid gpio 5,学习,笔记,驱动开发

make menuconfig

因为没有 /sys/class/gpio 路径,需要通过make menuconfig,将GPIO 映射到sysfs 文件系统中。
在kernel-4.4/ 下 make menuconfig 失败及解决方法:
export_store: invalid gpio 5,学习,笔记,驱动开发
配置后 out/.config 文件中CONFIG_GPIO_SYSFS is not set,可见并未生效;直接在kernel-4.4/arch/arm64/configs/*_defconfig 中加入:

CONFIG_GPIO_SYSFS=y

这下有 /dev/class/gpio 路径了。

export

执行第二步:echo 163 > export 时未生成gpio163 路径,同时kernel log 报错:
export_store: invalid GPIO 163
有可能是因为GPIO 被占用了的原因,因为这个方法也不方便app去调用,所以暂时放弃。

GPIO驱动

编译

在kernel-4.4/drivers/gpio/ 下添加GPIO 驱动文件 gpio-ms8837.c,同时修改kernel-4.4/drivers/gpio/ 下的Kconfig 和 Makefile:

+config GPIO_MS8837
+       tristate "MS8837 GPIOs"
+       help
+         This option enables support for on-chip GPIO found
+         on MS8837.
+obj-$(CONFIG_GPIO_MS8837)      += gpio-ms8837.o

注:Kconfig 也要改,只改Makefile 不会编译gpio-ms8837.o

驱动分析

static int __init gpio_shutter_init(void)
{
    int devno;
    dev_t num_dev;

    printk("%s is called. \n", __func__);

    alloc_chrdev_region(&num_dev, gpio_minor, 1, MYGPIO_NAME);

    gpio_major = MAJOR(num_dev);
    printk("gpio_major = %d. \n", gpio_major);

    gpio_class = class_create(THIS_MODULE, MYGPIO_NAME);

    devno = MKDEV(gpio_major, gpio_minor);

    cdev_init(&gpio_cdev, &gpio_ops);

    cdev_add(&gpio_cdev, devno, 1);

    device_create(gpio_class, NULL, devno, NULL, MYGPIO_NAME);//1

#ifdef MYGPIO_HW_ENABLE
    gpio_shutter_hw_init();
#endif

    return 0;
}

标记1 处的device_create 负责在 /dev/ 下生成设备文件,屏蔽掉,设备文件就没有创建。
那么设备文件是如何创建的呢?
class_create() 源码:
kernel-4.4\drivers\base\class.c
device_create() 源码:
kernel-4.4\drivers\base\core.c

class_create()
This is used to create a struct class pointer that can then be used in calls to device_create().(用于创建一个class 结构体指针,用于device_create() 的调用。)class_create()调用后,会在/sys/class 下创建设备目录。本文是创建了 /sys/class/shutter 。
device_create()
This function can be used by char device classes. A struct device will be created in sysfs, registered to the specified class.(该函数可用于字符型设备类。用于在sysfs 中创建device 结构体,并注册到特定的class 中。)device_create()调用后会在 /dev/下建立设备节点,本文是/dev/shutter。这样用户层就可以 去访问设备了。class 与 device 通过 /sys/devices/virtual/shutter/shutter 关联。

export_store: invalid gpio 5,学习,笔记,驱动开发
剩下的就是 file_operations 了,read/write/ioctl 等,根据需求去实现。

static const struct file_operations gpio_ops={
    .owner = THIS_MODULE,
    .open  = gpio_ms8837_open,
    .unlocked_ioctl = gpio_ms8837_ioctl
};

补充:也可以通过mknod 指令去创建设备节点
mknod
[OPTION]… NAME TYPE [MAJOR MINOR]
export_store: invalid gpio 5,学习,笔记,驱动开发
export_store: invalid gpio 5,学习,笔记,驱动开发
export_store: invalid gpio 5,学习,笔记,驱动开发

参考文档:
https://cloud.tencent.com/developer/article/1599571
https://zhuanlan.zhihu.com/p/442079581
http://blog.chinaunix.net/uid-22666248-id-3052861.html文章来源地址https://www.toymoban.com/news/detail-769175.html

到了这里,关于【学习笔记:GPIO驱动开发】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux驱动开发:gpio子系统

    目录 1、GPIO配置流程 2、GPIO子系统API 2.1 of_find_node_by_path 2.2 of_get_named_gpio 2.3 gpio_request 与 gpiod_get 与 gpiod_get_index 2.4 gpio_direction_input 与 gpiod_direction_input 2.5 gpio_direction_output 与 gpiod_direction_output 2.6 gpio_get_value 与 gpiod_get_value 2.7 gpio_set_value 与 gpiod_set_value 2.8  gpiod_get_from

    2024年02月12日
    浏览(50)
  • 驱动开发作业3——GPIO子系统

    作业1:在内核模块中启用定时器,定时1s,让LED1以1s为周期实现流水灯  myled.c(驱动文件)    作业2:基于GPIO子系统完成LED灯驱动的注册,并利用应用程序测试  chrdevled.c(驱动文件) test.c(测试文件)

    2024年02月16日
    浏览(38)
  • <Linux开发>驱动开发 -之-基于pinctrl/gpio子系统的beep驱动

    <Linux开发>驱动开发 -之-基于pinctrl/gpio子系统的beep驱动 交叉编译环境搭建: <Linux开发> linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下: <Linux开发> -之-系统移植 uboot移植过程详细记录(第一部分) <Linux开发> -之-系统移植 uboot移植过程详细记录(第二部分

    2024年02月13日
    浏览(42)
  • 【Linux驱动开发】011 gpio子系统

    前面我们编写了基于设备树的 LED 驱动,但是驱动的本质还是没变,都是配置 LED 灯所使用的 GPIO 寄存器,驱动开发方式和裸机基本没啥区别。本章我们就来学习一下如何借助 pinctrl 和 gpio 子系统来简化 GPIO 驱动开发。   Linux 内核针对 PIN 的配置推出了 pinctrl 子系统,对于

    2024年02月03日
    浏览(49)
  • Linux驱动开发学习笔记

    (Trusted Firmware - Arm) tsv语法 p220 ‘P’:向分区或者设备烧写固件。 ‘E’:空分区或设备,表示对应的分区或设备不更新,相关的 Id项会被跳过。 ‘D’:删除分区或设备。 TF_A的bl33部分是uboot,uboot的功能是引导、启动linux。 U-boot命令 一般环境变量存放在外部flash中,uboo

    2024年02月14日
    浏览(49)
  • OpenHarmony轻量系统开发【5】驱动之GPIO点灯

    摘要 :本文简单介绍如何操作GPIO去点灯 适合群体 :适用于Hi3861开发板,L0轻量系统驱动开发 5.1点灯例程源码 先看最简单得LED灯闪烁操作 源码结构如下: 第一个BUILD.gn文件内容: 第二个BUILD.gn内容: led_demo.c内容: 编译后烧录进去,应该可以看到复位按键旁边的LED灯一直在

    2024年02月07日
    浏览(40)
  • [驱动开发]gpio子系统及中断实现led亮灭

    编写LED灯的驱动,使用GPIO子系统,里面添加按键的中断处理 1.应用程序发送指令控制发光二极管亮灭 2.按键1按下,led1电位反转;按键2按下,led2电位反转;按键3按下,led3电位反转   

    2024年02月14日
    浏览(78)
  • Linux驱动开发之【pinctrl和gpio子系统】

    目录 一、 pinctrl和gpio子系统 1.pinctrl子系统 1.1 pinctrl子系统简介 1.2 pinctrl子系统驱动 1.3 设备树中添加pinctrl节点模版 2. gpio子系统 2.1 gpio子系统简介 2.2 gpio子系统驱动 2.3 gpio子系统API函数 2.4 设备树中添加gpio节点模板 2.5 与gpio相关的OF函数 3. 驱动程序编写 3.1 驱动入口函数 3

    2024年02月06日
    浏览(46)
  • 【Linux驱动开发】012 gpio子系统API函数

    设置好设备树以后, 在驱动程序中就可以使用 gpio 子系统提供的 API 函数来操作指定的 GPIO, gpio 子系统向驱动开发人员屏蔽了具体的读写寄存器过程。这就是驱动分层与分离的好处,大家各司其职,做好自己的本职工作即可。 gpio 子系统提供的常用的 API 函数有下面几个:

    2023年04月18日
    浏览(43)
  • 全志H3-nanopi-duo2开发板GPIO驱动开发

    编译和更新Linux内核: [ 注意: 这里我只需要编译驱动模块,不需要编译内核,上一篇文章有编译驱动模块的步骤] 编译完成后会在arch/arm/boot/目录下生成zImage,并且在arch/arm/boot/dts/目录下生成dtb文件,dtb文件是设备树二进制文件。 假设SD卡的boot分区挂载在/media/SD/boot/,更新SD卡上的

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包