内核节拍

xiaoxiao2021-02-28  50

内核的节拍是选用一个时钟源作为滴答源,但是选择这个时钟源有个条件,就是这个时钟必须有计时功能,定时功能,硬件中断功能,即可以触发中断,这样才可以去产生tick。 软件上的tick正是在这个中断函数中实现的,当这个中断来临后,回去调用系统的evt->event_handler(evt);

目前见到的有两种做法: 1:使用外置的定时器(一般在南桥) 2:使用cpu core内部的定时器 做法1:外置的定时器时钟来源是晶振,不易受干扰,但是需要重新写自己的driver注册这个定时器作为内核tick 做法2:core内置的定时器时钟来源是cpu的系统clk,如果这个clk在运行中变动的话,内置的core会受影响就不能用,但是这个有kernel标准的driver,配置好dts就可以直接用。 case:有的soc需要devfs(动态频率调整)cpu的clk,这样core内的定时器就用不了了,只能使用外置的独立不受干扰的定时器 如果cpu的频率是固定的不受干扰的,即可以使用core内的定时器,简单方便。

tick的1/HZ是如何和硬件定时器的时钟周期联系起来的? 这是个好问题,很多知识都是带着问题才得以发现和深入,开始的时候我就盯着代码看,看了右看,然并卵,收获很少,等我快要放弃的时候。我开始看起了书准确说是在看别人的理解结果, 无意间我一点一点看完了整个系统的大概框架,然后我居然有了迷糊灌顶的感觉。从此就觉的什么时候都不要放弃看有效的书,书和代码结合着看,看完书,再回购来看这个问题: 其实问题的本质是这样的,我们配置的HZ是如何和硬件系统定时器的周期联系起来的呢? 其实,无论tick以及HZ有多么神奇和千变万化,其宗旨就是,一旦确立了HZ的值,也就确定了tick的周期(tick= 1/HZ)那么定时器就要按照这个tick的周期去配置寄存器的触发中断周期,在中断中再触发一次tick的产生。即无论怎样,最终硬件层面,定时器的中断触发周期一定要配置为或者接近1/HZ,这样HZ就和硬件定时器联系起来了。 假设HZ= 100,那么tick = 1/HZs=0.01s = 10ms,即意味着,我们要将该定时器的中断触发周期设定为10ms触发一次,即中断发生的时候就会产生一次tick,一般定时器都是可以编程的,并且 该定时器的震荡周期远远小于10ms。所以当HZ = 1000时,tick = 1ms,定时器也是远远可以支持这么小颗粒的时钟周期的。

再看看代码:

#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) ticks_per_jiffy = DIV_ROUND_UP(timer_rate, HZ); //ticks_per_jiffy

为每(1/HZ)个时间触发一次中断所需要定时器震荡周期的次数,即= (timer_rate + HZ -1)/HZ 看公式不好理解,那这样理解,HZ确定后,tick = 1/HZ。即定时器产生中断的周期是tick = 1/HZ. timer_rate为该定时器的频率,即该定时器的震荡颗粒是 1/timer_rate s,那么我们需要计算需要多少次震荡才可以达到一次中断触发的时间,此时我们就可以计算``: (1/HZ)总时间/(1/timer_rate)单个时间 = 所需的次数。这个值会被用在配置这个定时器中,是它每隔(1/HZ)/(1/timer_rate)个震荡周期触发一次中断,在中断中再触发一次tick的产生 至于为何这样算:#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))`暂未深究,不过大体思路就是这样的。 下面是定时器的中断处理函数:

static irqreturn_t alitech_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = (struct clock_event_device *)dev_id; u8 val; /*clear INT flag*/ val = readl(timer_base + SB_TIMER_CTL_REG); writel(val | SB_TIMER_CTL_INT, timer_base + SB_TIMER_CTL_REG); if (periodic) alitech_timer_setup(ticks_per_jiffy);//这个函数就是配置定时器的中断触发周期的,里面填入的就是我们之前计算的需要多少次震荡次数才可以达到一次中断触发时间 ,具体的操作有具体的寄存器使用说明 evt->event_handler(evt);//这里触发tick。这里就可以看作是纯粹的一个软件起振源了 return IRQ_HANDLED; }
转载请注明原文地址: https://www.6miu.com/read-2630664.html

最新回复(0)