RISC-V (十一)软件定时器
主要的思想:硬件定时器是由硬件的定时器设备触发的。软件定时器在硬件定时器的基础上由软件控制实现多个定时器的效果。主要的思路是在trap_handler函数中加入软件代码,使其在设定的时间点 去执行想要执行的功能函数。
定时器的分类
硬件定时器:芯片本身提供的定时器,一般由外部晶振提供,提供寄存器设置超时时间,并采用外部中断的方式通知CPU。优点是精度高,但是定时器的个数受硬件设置限制。
软件定时器:操作系统中基于硬件定时器提供的功能,采用软件方式实现。扩展了硬件定时器的限制,可以提供数据更多(几乎不受限制)的定时器,缺点是精度较低,必须是tick的整数倍。
软件定时器的分类
按照定时器设定方式分:
单次触发定时器:创建后只会触发一次定时器通知事件,触发后该定时器自动停止(销毁)。
周期触发定时器:创建后按照设定的周期无限循环触发定时器通知事件,直到用户手动停止。
按照定时器超时后执行处理函数的上下文环境分:
超时函数运行在中断上下文环境中,要求执行函数的执行时间尽可能短,不可以执行等待其他事件等可能导致中断控制路径挂起的操作。优点是相应比较迅速,实时性较高。
超市函数运行在任务上下文环境中,即创建一个任务来执行这个函数,函数中可以等待或者挂起,但实时性较差。
软件定时器的设计和实现
构建timer结构体:里面记录了要执行的函数,函数的传参,以及timeout_tick 的值。
设置这个结构体的数量,这里程序设置的是10。
timer_init初始化函数,就是遍历这些结构体,初始化里面的值。
timer_create函数和timer_delete函数,就是给结构体传值,和删除结构体的值。
定时器软件中断的核心程序是timer_check,实现在中断程序的上下文中。此例子是单次触发定时器。
虽然硬件上只有一个定时器,但是可以通过软件的方式来实现多个定时器。
软件定时器的优化
软件定时器优化(1):采用链表的方式代替数组,动态地去分配内存,而不是一开始就分配好一个大数组;定时器按照时间排序。
软件定时器优化(2):对搜索命中的方式做改变:跳表算法,有点像二分法。就是原先是按照链表的方式从前到后去搜索,事件复杂度为O(n),在原先的链表的基础上加一个二级、三级、四级链表,也就是跳表算法,时间复杂度为Olog(n)。