1、前言 tick一般作为任务延时的调度的内部机制,其接口主要为系统内部使用。对于使用操作系统的应用软件,也需要定时触发相关功能的接口,包括单次定时器和周期定时器。从用户层面讲,可以不关注底层cpu的定时机制以及tick的调度,定时器的接口是可以创建和使能一个软件定时器,时间到了之后,用户的钩子函数能被执行。 Rhino提供基本的软件定时器功能,包括定时器的创建、删除、运行,以及单次和周期定时器。 2、定时器的实现原理操作系统需要完成定时器的两个功能:一个是定时器的管理;另一个是定时器的运行。 ①定时器的管理定时器的管理主要包括定时器的创建、删除、启动、停止以及参数变更。 定时器管理接口(如创建或者删除定时器)被调用后,向命令buffer写入命令,设置需要配置的定时器、参数相关信息。timer任务循环从命令buffer中读取处理信息。 ②定时器的运行timer任务除了处理管理命令外,还需要进行当前所有已运行定时器的实时调度。所有正在运行的timer都会被挂载g_timer_head队列,timer任务循环从g_timer_head中取出时间最近一次的定时器,通过当前tick计数和该定时器的超时tick数来判断是否到定时时间。如果该定时器触发时间已到,则立即执行其处理函数。 3、定时器模块初始化使用timer模块,首先需要确保k_config.h中宏RHINO_CONFIG_TIMER已打开,其模块初始化函数只有一个接口:void ktimer_init(void),此接口主要完成以下三个工作: ①、初始化timer队列g_timer_head; ②、初始化timer定时器管理buffer队列g_timer_queue; ③、创建定时器基本处理任务g_timer_task; 4、定时器基本接口①定时器创建静态创建函数原型: kstat_t krhino_timer_create (ktimer_t *timer ,const name_t *name ,timer_cb_t cb ,sys_timer_t first ,sys_timer_t round ,void *arg ,uint8_t auto_run) 其中主要参数的意义分别为: timer:用户传入定时器管理句柄; cb:定时器处理钩子; first:第一次延时时间; round:后续周期定时时间; auto_run:是否立即运行,不需要另外调用start。 动态创建函数原型: kstat_t krhino_timer_dyn_create (ktimer_t * *timer ,const name_t *name ,timer_cb_t cb ,sys_timer_t first ,sys_timer_t round ,void *arg ,uint8_t auto_run) 其与静态创建函数的主要区别在于timer是出参,内存不需要用户指定,由内部申请返回。 ②定时器删除静态删除函数原型: kstat_t krhino_timer_del(ktimer_t *timer) 动态删除函数原型: kstat_t krhino_timer_dyn_del(ktimer_t *timer) krhino_timer_del只能释放krhino_timer_create创建的定时器;krhino_timer_dyn_del只能释放krhino_timer_dyn_del创建的定时器。动态删除接口会释放timer内存。 ③定时器启动和停止 启动接口 : kstat_t krhino_timer_start(ktimer_t *timer) 停止接口 : kstat_t krhino_timer_stop(ktimer_t *timer) 除了在start阶段设置timer为自动启动外,其他定时器都需要调用krhino_timer_start来运行timer,并将该定时器加入g_time_head队列;同理,krhino_timer_stop会将其从g_time_head中删除。 ④参数变更接口 定时时长变更接口 : kstat_t krhino_timer_change(ktimer_t *timer ,sys_timer_t first ,sys_timer_t round ) 此接口允许修改初次和周期定时时长。需要在定时器处于未启动状态时才能修改。 参数变更接口 : kstat_t krhino_timer_arg_change(ktimer_t *timer ,void *arg) 此函数修改定时器触发时,传入钩子函数的接口。需要在定时器处于未启动状态时才能修改。 自动参数变更接口 : kstat_t krhino_timer_arg_change_auto(ktimer_t *timer ,void *arg) 此接口会完成定时器停止,参数修改,重新启动等一连串动作。 5、总结一般来说,tick负责内部任务的调度,因此是内核模块的必选项;timer是基于tick单元虚拟的软件定时器模块,如果用户不使用此模块,可以修改对应k_config.h的宏RHINO_CONFIG_TIMER。
|