I.MX6U嵌入式Linux驱动开发(10)内核定时器

1、概念

1.1、节拍

打开Linux内核源码,图形化配置页面:

cd /linux/IMX6ULL/linux
cd linux-imx-rel_imx_4.1.15.2.1.0_ga_alientek/
make menuconfig

HZ表示系统节拍率。

采用 100Hz 的节拍率,时间精度就是 10ms,采用1000Hz 的话时间精度就是 1ms,精度提高了 10 倍。

高节拍率会导致中断的产生更加频繁,频繁的中断会加剧系统的负担,1000Hz 和 100Hz的系统节拍率相比,系统要花费 10 倍的“精力”去处理中断。

Linux 内核使用全局变量 jiffies 来记录系统从启动以来的系统节拍数。

1.2、内核定时器

(1)、只需要提供超时时间(相当于定时值)和定时处理函数即可,当超时时间到了以后,设置的定时处理函数就会执行;
(2)内核定时器并不是周期性运行的,超时以后就会自动关闭,因此如果想要实现周期性定时,那么就需要在定时处理函数中重新开启定时器。

2、编写驱动

mkdir 12_timer
cd 12_timer

2.1、编写驱动框架

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>

#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define TIMER_CNT			1		  	/* 设备号个数 */
#define TIMER_NAME		"timer"	/* 名字 */


/* key设备结构体 */
struct timer_dev{
   
	dev_t devid;			/* 设备号 	 */
	int major;				/* 主设备号	  */
	int minor;				/* 次设备号   */
	struct cdev cdev;		/* cdev 	*/
	struct class *class;	/* 类 		*/
	struct device *device;	/* 设备 	 */	
	struct device_node	*nd; /* 设备节点 */
};

struct timer_dev timerdev;	/* timer设备 */

/*
 * @description		: 打开设备
 * @param - inode 	: 传递给驱动的inode
 * @param - filp 	: 设备文件,file结构体有个叫做private_data的成员变量
 * 					  一般在open的时候将private_data指向设备结构体。
 * @return 			: 0 成功;其他 失败
 */
static int timer_open(struct inode *inode, struct file *filp)
{
   
	filp->private_data = &timerdev; /* 设置私有数据 */
	return 0;
}

/*
 * @description		: 向设备写数据 
 * @param - filp 	: 设备文件,表示打开的文件描述符
 * @param - buf 	: 要写给设备写入的数据
 * @param - cnt 	: 要写入的数据长度
 * @param - offt 	: 相对于文件首地址的偏移
 * @return 			: 写入的字节数,如果为负值,表示写入失败
 */
static ssize_t timer_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
   
	int ret = 0;
	
	return ret;
}

/*
 * @description		: 关闭/释放设备
 * @param - filp 	: 要关闭的设备文件(文件描述符)
 * @return 			: 0 成功;其他 失败
 */
static int timer_release(struct inode *inode, struct file *filp)
{
   
	return 0;
}

/* 设备操作函数 */
static struct file_operations timerdev_fops = {
   
	.owner   =  THIS_MODULE,
	.open    =  timer_open,
	.write   =  timer_write,
	.release = 	timer_release,
};

/*
 * @description	: 驱动出口函数
 * @param 		: 无
 * @return 		: 无
 */
static int __init timer_init(void)
{
   
	int ret = 0;

	/* 注册字符设备驱动 */
	/* 1、创建设备号 */
	timerdev.major = 0;
	if (timerdev.major) {
   		/*  定义了设备号 */
		timerdev.devid = MKDEV(timerdev.major
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值