IMX6ULL嵌入式Linux驱动开发学习
以下内容是我在学习正点原子IMX6ULL
开发板alpha
中记录的笔记,部分摘录自正点原子IMX6ULL开发手册
。
Linux内核定时器和ioctl函数
内核时间管理
1.1 对于
Cortex-M
内核来说,一般使用systick
硬件定时器作为系统定时器,使用过FreeRTOS
等操作系统的也知道,FreeRTOS
一般就是使用systick
来提供系统时钟,同样Linux
也需要系统时钟。1.2
Linux
内核频率可以配置,在图形化界面可以配置。在include/aasm-generic/param.h
文件中可以看到内核配置的节拍率HZ
(系统频率)。1.3
HZ
表示每秒的节拍数。节拍率高低的缺陷
系统使用硬件定时中断来计时,中断周期性产生的频率就是系统频率,也叫作节拍率
tick rate
。节拍率越高,时间精度越高,同样也会加剧系统的负担。
jiffies
Linux
内核使用全局变量jiffies
来记录系统从启动以来的系统节拍数,系统启动的时候会将其初始化为0,jiffies
定义在文件include/linux/jiffies.h
中。jiffies
/HZ
就是系统运行时间,单位为秒。
1 | /************** 判断是否超时的api函数 ***************/ |
内核定时器
4.1 软件定时器不像硬件定时器一样是直接设置周期值的。软件定时器是设置期限满以后的时间点。
4.2 需要编写定时器处理函数。
4.3 内核定时器不是周期性的,一次定时时间到了以后就会关闭,除非重新打开。
定时器
API
函数
1 | /******** timer_list 结构体 **********/ |
- 内核短延时函数
1 | void ndelay(unsigned long nsecs); // 纳秒延时 |
定时器使用练手
1 |
|
使用ioctl
函数控制
用户APP
中使用ioctl
函数
1 | unlocked_ioctl(); |
对应驱动里的函数
1 | /* |
ioctl
的命令是自己定义的,但是要符合Linux
的规则。具体的说明可以查看博主coolwriter的博客。
cmd
拆分如下
幻数(type) | 序数(number) | 数据传输方向(direction) | 数据大小(size) |
---|---|---|---|
8bit | 8bit | 2bit | 14bit |
- 幻数:是一个
0~0xFF
的数,是用来区分不同的书驱动的。 - 序数:用这个数来给自己的命令编号。
- 数据传输方向:如果涉及到要传参,内核要求描述一下传输的方向。
_IOC_NONE
:值为0,无数据传输。_IOC_READ
:值为1,从设备驱动读取数据。_IOC_WRITE
:值为2,向设备驱动写入数据。_IOC_READ|_IOC_WRITE
:双向数据传输。
- 数据大小:==与体系结构相关==,
ARM
下占14bit(_IOC_SIZEBITS)
,如果数据是int
,内核给这个赋的值就是sizeof(int)
。
构建命令
1 | /* type是幻数,nr是序数,size是大小 */ |
驱动程序
1 |
|
测试APP程序
1 |
|
- 本文作者: 路痴的兔子
- 本文链接: https:/proudrabbit.gitee.io/IMX6ULL嵌入式Linux驱动学习笔记(八).html
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!