基于Linux的旋转编码器的驱动程序和应用的开发

2021-07-09 13:49高永相
电子乐园·中旬刊 2021年8期

高永相

摘要:在产品设计和开发中,需要在arm平台下进行驱动开发,根据旋转编码器的基本工作原理,利用Linux 设备驱动的输入子系统进行了驱动和应用程序的设计。实验结果表明,方案切实可行。

关键词: Linux; 旋转编码器; Input子系统

中图分类号: TP273 文献标志码: A

选择EC11旋转编码器作为输入按钮,向右旋转,按步长增加参数,向左旋转,按步长递减参数。为实现设计目标,研究旋转编码器的输出特性以及linux平台的输入子系统特性,并成功移植到当前设备并设计应用程序[1]。

1硬件结构及基本原理

硬件平台以NXP的I.MX6ULL 为核心的。EC11是AB 相旋转编码器。在正向旋转时A相超前B相 90°; 在编码器反转时,B相超前A相 90°。通过判断A、B两相边沿处的电平高低就可判断方向。

2 输入子系统的组成

输入设备有共同的特点,输入子系统自下而上分为驱动层、核心层和事件处理层。驱动层是与硬件相关的实现。核心层承上启下,为驱动层提供输入设备注册和操作接口。事件处理层主要和用户空间进行交互,负责创建设备文件并将报告的事件传递给用户空间[2]。最底层就是具体设备,比如按键,旋转编码器等。

3 驱动的设计与实现

设备驱动程序是 Linux 内核的一部分,它提供内核接口,运行在内核态。驱动程序主要完成如下功能:

1) 完成rotary encoder设备初始化、资源申请和释放等操作;

2) 完成数据在内核和硬件设备间的读取和写入;

3) 接收应用程序传给硬件设备的数据并返回应用程序请求的数据;

input 核心层会向 Linux 内核注册一个字符设备,input.c 就是 input 输入子系统的核心层。class_registe注册一个input 类,系统启动以后就会在/sys/class 目录下生成 input 子 目录。register_chrdev_region注册一个字符设备[3]。设备驱动流程图见图1的左边。

3.1引脚的配置和初始化

EC_A连接到IMX6ULL 的GPIO5_1引脚,EC_B连接到IMX6ULL的GPIO1_1引脚。

引脚的配置和初始化,是外界硬件设备和内核沟通的桥梁。使用设备树来描述板级设备信息。

compatible = "rotary-encoder";用来和设备驱动匹配

gpios = <&gpio5 1 GPIO_ACTIVE_LOW>,<&gpio1 1 GPIO_ACTIVE_LOW>;配置rotary encoder 驱动的两个输入引脚,低电平有效。

3.2 驱动加载函数

输入对象的初始化是在驱动加载入口函数内完成的。输入对象描述了一个输入设备,包括它可能报告的事件,使用input 子系统的时候需注册一个input设备,input_dev结构体表示input设备。调用devm_input_allocate_device(struct input_dev*)实现input 设备的内存分配。使用input_set_capability(input, EV_REL, encoder->axis)注册此驱动,事件为EV_REL,使旋转编码器支持相对坐标。之后调用input_register_device(struct input_dev*)函数实现将输入设备注册到输入子系统中,并配置中断函数。使用devm_request_threaded_irq注册中断,handler = &rotary_encoder_irq设定中断函数。

3.3中断函数的实现

中断函数根据引脚当前的状态和之前状态,判断方向并上报方向数据。用state变量来保存两个输入引脚的电平状态。state=2之后state=1,判断为顺时针。state=2之后state=3,判断为逆时针,input_report_rel(encoder->input, encoder->axis, encoder->dir)报告事件。调用函数input_sync(encoder->input)来通知输入子系统同步到用户层。

4用户层应用实现

根据 Linux 下内核调用机制,实现应用程序读取旋转编码器的值,有两个值,1表示顺时针旋转,-1表示逆时针旋转,由上层应用程序对数据进一步处理后输出。流程如图1的右图。将应用程序交叉编译后在ARM平台上执行。此时转动旋转编码器运行结果正向旋转value=1 反向旋转value=-1。

5结束语

本文设计并实现了Linux 下的旋转编码器驱动程序,实现了旋转编码器相对值旋转方向检测功能,在实際应用中运行良好,达到了预期目的。

参考文献

[1] 屈克文,石奋苏基于 ARM- Linux 的旋转编码器接口与驱动程序的设计[J] 计算机应用,2011,12:31

[2] 宋宝华.Linux设备驱动开发详解[M].机械工业出版社,2015.7