《Linux 内核定时器》之iPhone13真香

iPhone13真香系列

iphone 的发布会在9月17号,我的一位小伙伴,在发布会结束之后就下单,晒在了朋友圈。作为一个,作为一个爱国主义着,当然要支持国产品牌。最主要的原因:一些品牌吃着中国的饭,砸着中国的碗。像前段时间的H&W的一些知名品牌,做出"停用中国棉花"的决定,所以本人也是内心很抵制一些非国产品牌。
在这里插入图片描述
但是,第二天我俩聊天 , 12期免息,一个月500,还是值得入手的,啊,真香 !在真香的同时,希望苹果不要做“吃着中国的饭,还砸着中国的锅”!!!H&W就是个例子,天下哪有这样的美事。
在这里插入图片描述

linux 内核定时器

一:简介
我们在开发单片机和裸机时,会经常用到定时器,是由一个硬件的定时器提供系统时钟,在rtos系统中一般使用Systick作为系统时钟。同样的在linux中,也是需要一个系统时钟。
在内核中有大量的需要函数需要时间管理,比如周期性的程序调度,延时程序。对于驱动开发人员来说,最常用的就是定时器。硬件定时器提供时钟源,时钟源的频率可以设置。设置好之后,就会产生周期性性的中断,系统使用使用中断来计时。中断周期性产生的频率就是系统频率,也叫节拍率,比如100HZ 、500HZ等都是系统节拍率。

二:系统节拍率
1. 系统节拍率时可以设置的,单位时HZ,可以通过如下方法来进行设置:
文件kernel/include/asm-generic/param.h

#ifndef __ASM_GENERIC_PARAM_H
#define __ASM_GENERIC_PARAM_H
#include <uapi/asm-generic/param.h>
# undef HZ
# define HZ             CONFIG_HZ       /* Internal kernel timer frequency */
# define USER_HZ        100             /* some user interfaces are */
# define CLOCKS_PER_SEC (USER_HZ)       /* in "ticks" like times() */
#endif /* __ASM_GENERIC_PARAM_H */
//定义一个HZ宏,宏HZ=CONFIG_HZ=100,在驱动编写会经常使用到HZ,因为HZ表示的就是一秒的节拍数,也就是频率。
//这里存在一个问题,系统节拍HZ为100Hz,时间精度就是10ms,采用高节拍HZ,比如1000hz,时间精度就是1ms,引出了一个高节拍率和低节拍率优缺点问题:1)高精度时钟的好处有很多,对于时间要求严格的函数来说,能够以更高精度运行,时间测量也更加精准。毕竟时间精度从10ms---1ms,精度提高了10倍。
	(2)高精度提高时间精度的同时,产生的中断也是10倍,这样中断产生的更加频繁,加剧系统的负担。中断服务处理函数占用处理器时间增加,增加系统负载的压力

2.系统使用全局变量jiffes来记录系统节拍数,在我们日常使用的手机 Android系统中,会看到系统以及开机多长时间或者运行了多长时间。就是jiffes来记录的,在系统启动时,初始化为0,然后记录。
jiffies定义在kernel/include/linux/jiffies.h

extern u64 __cacheline_aligned_in_smp jiffies_64;
extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies;
//可以看到定义了u64 64bit的jiffies_64,undigned long 32bit 的jiffies。64bit和32bit定义的jiffies其实是相同的。64bit用于64为系统,32bit运用与32bit系统。内核这样做的目的,是为了兼容不同硬件,jiffies_64的低32bit就是jiffies。

3.HZ代表每秒的节拍数,jiffies表示系统的节拍数,所以jiffies/HZ就是系统运行的时间,单位为s。不管32bit、64bit都有溢出的风险,溢出之后会从0从新计数,这个现象叫做绕回,64bit系统需要5.8亿年才能绕回,32bit50天左右会绕回。所以处理32bit的绕回对我们来说很重要。
api:

(1) //a通常为jiffies,b为要对比的value.
time_after(a,b) //a>b,return=true
time_before(a,b)//a<b,return=true
time_after_eq(a,b)//类似
time_before_eq(a,b)//

(2) //时间转换函数
extern unsigned int jiffies_to_msecs(const unsigned long j);//jiffies-->ms
extern unsigned int jiffies_to_usecs(const unsigned long j);//jiffies-->us
static inline u64 jiffies_to_nsecs(const unsigned long j)//jiffies-->nu

static inline unsigned long _msecs_to_jiffies(const unsigned int m)//ms-->jiffies
extern unsigned long __usecs_to_jiffies(const unsigned int u);//us-->jiffies

二:定时器
作为一个常用的功能,在使用上也是很简单的,只需要设置超时时间和定时处理函数即可。当时间到了,定时处理函数就会执行。但是要注意一点:内核定时器并不是周期运行,超市自动关闭。因此要实现周期性定时,需要在定时处理函数中重新开启定时器。
1. 内核定时器结构体,timer_list:

struct timer_list {
 struct list_head entry;
 unsigned long expires; /* 定时器超时时间,单位是节拍数 */
 struct tvec_base *base;
 void (*function)(unsigned long); /* 定时处理函数 */
 unsigned long data; /* 要传递给 function 函数的参数 */
 int slack;
};

使用之前要先定义一个time_list变量,表示定时器。expies表示超时时间,单位为节拍数。fuction就是定时器超时之后处理函数,data是函数参数。

2.定时器相关api函数

void init_timer(struct timer_list *timer)//初始化定时器结构体
void add_timer(struct timer_list *timer)//向内核注册定时器
int del_timer(struct timer_list * timer)//删除定时器,多核,需等待其他核定时器退出在删除。
int del_timer_sync(struct timer_list *timer)//等待其他处理器使用完定时器在删除,不能用于中断上下文。

int mod_timer(struct timer_list *timer, unsigned long expires)//用于修改定时器的值,如果定时器还没激活,mod_timer会定时激活。

3.内核定时器使用流程

//1.定义定时器
struct timer_list timer;

void function(unsigned long arg)
{
	//定时器处理函数

	//5.重置超时值,启动定时器;并且需要周期性运行使用mod_timer
	mod_timer(&dev->timertest, jiffies + msecs_to_jiffies(2000));
}

void init(void{
	//2.初始化
	init_timer(&timer); //初始化定时器
	
	//3.设置函数和超时时间
	timer.function = functuion;//设置定时器处理函数
	timer.expires = jiffies + mesce_to_jiffies(2000);//超时时间为2s
	timer.data = (unsigned long)*dev;//将设备结构体作为参数
	
	//4.向内核注册定时器
	add_timer(&timer);
}

void exit(vid)
{	
	//6.删除
	del_timer(&timer); //删除定时器
	//or
	del_timer_sync(&timer);
}

4.相关延时函数:

void ndelay(unsigned long nsecs) //ns
void udelay(unsigned long usecs) //us
void mdelay(unsigned long meseces) //ms

总结:
1.节拍率HZ ,节拍数jiffies,系统启动时间jiffie/HZ;
2. 定时器使用流程1、2、3、4、5、6;
3. ms、us、ns延时函数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值