时钟节拍

2020-06-04

CPU时钟频率是处理器的心跳,有了它处理器才能进行运算!那么,系统的心跳呢?

答案就是:时钟节拍!也叫做系统时钟!

任何操作系统都需要提供一个时钟节拍,以供系统处理所有和时间有关的事件,如线程的延时、线程的时间片轮转调度以及定时器超时等。时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳,中断之间的时间间隔取决于不同的应用,一般是 1ms–100ms,时钟节拍率越快,系统的额外开销就越大,从系统启动开始计数的时钟节拍数称为系统时间。

RT-Thread 中, 时 钟 节 拍 的 长 度 可 以 根 据 RT_TICK_PER_SECOND 的 定 义 来 调 整, 等 于 1/RT_TICK_PER_SECOND 秒。

时钟节拍的实现方式

时 钟 节 拍 由 配 置 为 中 断 触 发 模 式 的 硬 件 定 时 器 产 生, 当 中 断 到 来 时, 将 调 用 一 次:void rt_tick_increase(void),通知操作系统已经过去一个系统时钟;不同硬件定时器中断实现都不同,下面的中断函数以 STM32 定时器作为示例。

void SysTick_Handler(void)
{
/* 进 入 中 断 */
	rt_interrupt_enter();
	……
	rt_tick_increase();
	/* 退 出 中 断 */
	rt_interrupt_leave();
}

在中断函数中调用 rt_tick_increase() 对全局变量 rt_tick 进行自加,代码如下所示:

void rt_tick_increase(void)
{
	struct rt_thread *thread;
	/* 全 局 变 量 rt_tick 自 加 */
	++ rt_tick;
	/* 检 查 时 间 片 */
	thread = rt_thread_self();
	-- thread->remaining_tick;
	if (thread->remaining_tick == 0)
	{
		/* 重 新 赋 初 值 */
		thread->remaining_tick = thread->init_tick;
		/* 线 程 挂 起 */
		rt_thread_yield();
	}
	/* 检 查 定 时 器 */
	rt_timer_check();
}

可以看到全局变量 rt_tick 在每经过一个时钟节拍时,值就会加 1,rt_tick 的值表示了系统从启动开始总共经过的时钟节拍数,即系统时间。敲黑板,系统时间的定义哦!

此外,每经过一个时钟节拍时,都会检查当前线程的时间片是否用完,以及是否有定时器超时。

由此可见什么?

时钟节拍是中 断 触 发 模 式 的 硬 件 定 时 器产生,也就是说供系统处理所有和时间有关的事件的时钟节拍其实就是一个硬件定时器

定时器,是指从指定的时刻开始,经过一定的指定时间后触发一个事件,例如定个时间提醒第二天能够按时起床。

而这里的定时器就是告诉系统一定时间后,去判断线程的延时、线程的时间片轮转调度以及定时器超时等。而这个一定的时间是可配的,也就是上文说的:1/RT_TICK_PER_SECOND 秒