156 lines
5.2 KiB
Markdown
156 lines
5.2 KiB
Markdown
# 节拍机制
|
||
|
||
* [简介](#intro)
|
||
* [函数接口](#func_api)
|
||
* [定时器机制](#tmr_mechanism)
|
||
* [结构定义](#structure)
|
||
* [软件定时器接口](#timer_api)
|
||
|
||
|
||
<span id="intro"></span>
|
||
|
||
## 简介
|
||
每一个操作系统都需要一个时钟计数,提供“心跳”计数,该时钟可以提供系统处理所有和时钟相关的事件。
|
||
XiUOS的“心跳”通过芯片提供的硬件定时器产生的周期性中断进行计数,XiUOS可以在menuconfig界面进行配置,配置单位为毫秒。
|
||
配置界面如下:
|
||
|
||
<img src="./imagesrc/tmr_config.png" width="100%"/>
|
||
|
||
界面中的数值将配置给变量 TICK_PER_SECOND,该变量解释为每秒钟支持的节拍数(tick)。当 TICK_PER_SECOND
|
||
配置为100,则tick节拍表示10毫秒,即一个时间片(timeslice)为10毫秒。
|
||
在节拍配置成功后,系统支持的调度算法、软件定时器等依赖于该时钟周期服务的事件就可以正常工作了。例如,在XiUOS支持的时间片轮转算法当中,每进行的一次线程切换为10个tick。
|
||
|
||
节拍计数执行流程如下图所示:
|
||
|
||
<img src="./imagesrc/tmr_process.png" width="100%"/>
|
||
|
||
在每一个定时器中断到来时,系统进行常规的中断执行流,定时器按照每一个tick单位进行触发中断,在中断服务程序当中进行自增,并对当前运行线程的时间片进行计算,同步可处理定时器的计数时间。
|
||
|
||
<span id="func_api"></span>
|
||
|
||
## 函数接口
|
||
|
||
```c
|
||
x_ticks_t CalculteTickFromTimeMs(uint32 ms);
|
||
```
|
||
该函数用于获取毫秒时间转化成节拍数。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| ms | 毫秒时间 |
|
||
```c
|
||
uint32 CalculteTimeMsFromTick(x_ticks_t ticks);
|
||
```
|
||
该函数用于获取节拍数转换成毫秒时间。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| ticks | 节拍数 |
|
||
```c
|
||
x_ticks_t CurrentTicksGain(void);
|
||
```
|
||
该函数用于获取当前的时钟节拍数。
|
||
|
||
<span id="tmr_mechanism"></span>
|
||
|
||
## 内核定时器机制
|
||
内核软件定时器模块根据系统的节拍心跳(tick)提供软件定时服务,用户可以设定固定的超时时间,
|
||
当系统运行的节拍数到达用户设定的超时时间时,便执行用户定义的超时回调函数进行业务处理。
|
||
软件定时器的存在可以解决硬件定时器数量不足的问题。
|
||
|
||
<span id="structure"></span>
|
||
|
||
### 内核软件定时器结构定义
|
||
```c
|
||
struct Timer
|
||
{
|
||
struct IdNode id_node;
|
||
char name[NAME_NUM_MAX];
|
||
uint8 active_status;
|
||
uint8 trigger_mode;
|
||
void (*func_callback)(void *param);
|
||
void *param;
|
||
x_ticks_t origin_timeslice;
|
||
x_ticks_t deadline_timeslice;
|
||
DoubleLinklistType link;
|
||
DoubleLinklistType sortlist;
|
||
uint8 prio;
|
||
struct Work *t_work;
|
||
struct TimerDone *done;
|
||
};
|
||
```
|
||
| 成员 | 描述 |
|
||
| --- | --- |
|
||
| id_node | 软件定时器ID,用于唯一标识一个软件定时器 |
|
||
| name | 软件定时器名称 |
|
||
| active_status | 定时器的激活状态 |
|
||
| trigger_mode | 定时器的触发模式,包含单次触发和周期触发两种方式 |
|
||
| func_callback | 定时器超时回调函数 |
|
||
| param | 定时器超时回调函数的参数 |
|
||
| origin_timeslice | 初始化的超时时间 |
|
||
| deadline_timeslice | 截止时间 |
|
||
| link | 系统中所有定时器构成的链表 |
|
||
| sortlist | 处于激活态的定时器链表,并按时间排序 |
|
||
| prio | 记录使用定时器处理回调的线程优先级 |
|
||
| t_work | 定时器所用到的工作队列 |
|
||
| done | 定时器的函数操作集 |
|
||
|
||
<span id="timer_api"></span>
|
||
|
||
### 内核软件定时器接口
|
||
定时器用户操作结构体定义如下:
|
||
|
||
```c
|
||
#define TIMER_TRIGGER_ONCE (1 << 0)
|
||
#define TIMER_TRIGGER_PERIODIC (1 << 1)
|
||
|
||
int32 KCreateTimer(const char *name, void (*timeout)(void *parameter), void *parameter, x_ticks_t time, uint8 trigger_mode);
|
||
```
|
||
该函数用于创建一个内核软件定时器,并返回创建成功的软件定时器的ID,ID默认范围0-255,可配置。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| name | 定时器名称 |
|
||
| timeout | 软件定时器回调函数 |
|
||
| parameter | 软件定时器回调函数参数 |
|
||
| time | 配置需要等待的超时时间,单位tick |
|
||
| trigger_mode | 触发方式,可以配置为宏TRIGGE_WAY_ONCE和TRIGGE_WAY_PERIODIC |
|
||
|
||
```c
|
||
void KTimerDelete(int32 timer_id);
|
||
```
|
||
该函数用于删除一个软件定时器。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| timer_id | 待删除的软件定时器ID |
|
||
|
||
```c
|
||
x_err_t KTimerStartRun(int32 timer_id);
|
||
```
|
||
该函数用于启动一个软件定时器。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| timer_id | 已创建且待运行的软件定时器ID |
|
||
|
||
```c
|
||
x_err_t KTimerQuitRun(int32 timer_id);
|
||
```
|
||
该函数用于停止一个软件定时器。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| timer_id | 待停止运行的软件定时器ID |
|
||
|
||
```c
|
||
x_err_t KTimerModify(int32 timer_id, x_tick_t ticks);
|
||
```
|
||
该函数用于修改一个软件定时器的超时时间。
|
||
|
||
| 参数 | 描述 |
|
||
| --- | --- |
|
||
| timer_id | 待修改超时时间的软件定时器ID |
|
||
| ticks | 超时时间 |
|
||
|