- 开发板:stm32mp157aaa(Cortex-A7*2 + Cortex-M4*1)
- 开发环境:vscode、串口工具、ubuntu 18.04
vscode编译过程:

1 引入ioctl函数的意义
linux操作系统中有意将数据的读写和读写功能的选择分别交给不同的函数去完成。就让read/write函数只进行数据的读写即可,让一些其他功能的设置和选择交给ioctl函数来实现。比如,串口通信时,需要设置波特率,需要设置数据格式,也需要最终选择数据收发,让这些都由ioctl函数来完成。让read()write()只进行串口数据收发即可。
2 ioctl函数分析
*********系统调用函数的分析**********
#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);
功能:进行io功能的设置
参数:
fd:文件描述符
request:io控制的功能码
...:可以加,也可以不加。如果第三个参数传递数值,只能传递整型数据和指针
返回值:成功返回0,失败返回错误码
*********驱动中操作方法的分析********
long (*unlocked_ioctl) (struct file *file, unsigned int cmd, unsigned long arg)
{
参数分析:
file:文件指针
cmd:应用程序中的ioctl第二个参数传递过来
arg:应用程序中的ioctl第三个参数传递过来
}
3 ioctl功能码的构建
为了让实现不同功能的功能码尽量不一样,我们对功能码进行了编码
查询内核的说明手册:~/linux-5.10.61/Documentation/userspace-api/ioctl
vi ioctl-decoding.rst //功能码的编码说明文档
====== ==================================
bits meaning
====== ==================================
31-30 00 - no parameters: uses _IO macro
10 - read: _IOR
01 - write: _IOW
11 - read/write: _IOWR
29-16 size of arguments
15-8 ascii character supposedly
unique to each driver
7-0 function #
====== ==================================
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)
#define _IOC(dir,type,nr,size) \
((unsigned int) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT)))
ex:构建LED开关的功能码:ioctl函数无第三个参数
开灯 #define LED_ON _IO('l',1)
关灯 #define LED_OFF _IO('l',0)
ex:构建LED开关的功能码:ioctl函数有第三个参数
开灯 #define LED_ON _IOW('l',1,int)
关灯 #define LED_OFF _IOW('l',0,int)
4 ioctl实例①——不传递第三个参数
应用程序
#
Linux ioctl函数驱动开发详解

本文围绕Linux操作系统中的ioctl函数展开驱动开发讲解。介绍了引入ioctl函数的意义,即让其负责读写功能的设置与选择,而read/write函数专注数据读写。还分析了ioctl函数,阐述功能码构建,并给出三个不同参数情况的实例,包括应用程序、头文件和驱动程序。开发板为stm32mp157aaa,环境有vscode等。

最低0.47元/天 解锁文章
241

被折叠的 条评论
为什么被折叠?



