110 lines
5.7 KiB
Markdown
Executable File
110 lines
5.7 KiB
Markdown
Executable File
[简要](../../../../README.md)
|
||
|
||
# 微内核 k_kit
|
||
|
||
> k_kit 以下简称 kit。kit 可以理解成是一个实时内核中的软定时器模块的强化版。
|
||
基于此设计的程序就是由所有软定时器组成的集合,这些集合既可作为一个完整的工程,也可以作为一个线程模块,使用非常灵活。
|
||
|
||
## 特点
|
||
- 是一个极小的,由事件驱动的,管理任务的微内核;
|
||
- 介于裸机与实时内核之间,适用于资源受限的微型系统的同时,尽可能提供类似实时内核接口和管理方式;
|
||
- 极低的跨平台需求,只需要实现几个简单的接口,即可在任何平台上运行;
|
||
- 所有功能模块都有独立的对象,所有对象动通过态申请和销毁;
|
||
- 极短的、固定的关中断时间,有效保障硬实时性;
|
||
- 基于 kit 设计的工程可无缝扩充到 RTK 实时内核中 [点击查看 RTK](../../README.md);
|
||
|
||
## 文件结构
|
||
```bash
|
||
...
|
||
└── kit # 本目录
|
||
├── k_kit.c # kit 的所有实现代码。
|
||
├── k_kit.h # 完整的 kit 的功能接口
|
||
└── kk.h # 跨内核接口,与实时内核中 RTK 中的 `rtk_kk.h` 保持一致
|
||
```
|
||
|
||
## 模块简介
|
||
|
||
### `work`
|
||
- work 是任务管理的对象,数据结构由 k_work_t 封装,在创建对象时设置实现函数;
|
||
- 任务拥有: 运行、延时、挂起、堵塞 的能力;
|
||
- 所有任务都由队列函数 k_work_q_handler() 执行调用管管理;
|
||
- 所有任务可设置由通讯模块唤醒;
|
||
- 所有任务默认附带一个接收邮箱;
|
||
- 所有任务函数必须返回;
|
||
- 所有任务都允许设置优先级,但不可抢断;
|
||
|
||
#### *mbox*
|
||
- mbox 是 work 附带的一个功能的扩展功能,用法与 fifo 类似;
|
||
- 邮箱在使用前需要被创建,每个任务最多只能有一个邮箱;
|
||
- 邮件内存从堆中申请,传递的是指针,与 fifo 不可混用;
|
||
- 一个新邮件被提交时,对应的任务一定被唤醒;
|
||
- 提取后的邮件在任务函数退出后被自动删除;
|
||
|
||
### `timer`
|
||
- timer 是软定时器的管理对象,数据结构由 k_timer_t 封装,在创建对象时设置实现函数;
|
||
- 软定时器的本质是在 work 的基础上添加一些时间特性的任务;
|
||
- 软定时器拥有: 运行、延时、挂起 的能力;
|
||
- 所有软定时器都由队列函数 k_timer_q_handler() 执行调用管管理;
|
||
- 所有软定时器函数必须返回;
|
||
- 所有软定时器都允许设置优先级,但不可抢断;
|
||
|
||
### work 与 timer 比较
|
||
| | work | timer |
|
||
| :------: | :----------------: | :-----------------: |
|
||
| 入口 | k_work_q_handler() | k_timer_q_handler() |
|
||
| 运行 | 是 | 是 |
|
||
| 延时 | 是 | 是 |
|
||
| 挂起 | 是 | 是 |
|
||
| 堵塞 | 是 | 不支持 |
|
||
| 优先级 | 0 .. 7 | 0 .. 7 |
|
||
| mbox | 可用,默认唤醒 | 仅发送 |
|
||
| fifo | 可用,注册唤醒 | 可用,不支持唤醒 |
|
||
| queue | 可用,注册唤醒 | 可用,不支持唤醒 |
|
||
| pipe | 可用,注册唤醒 | 可用,不支持唤醒 |
|
||
| log | 可用 | 不可用 |
|
||
|
||
### *IPC*
|
||
|
||
- kit 目前包含了三种常用的独立对象的通讯模块 `fifo`, `queue`, `pipe` 和 work 专用的模块 `mbox`;
|
||
|
||
| | fifo | queue | pipe | mbox |
|
||
| :------------: | :-------: | :-------: | :------: | :------: |
|
||
| 对象 | k_fifo_t | k_queue_t | k_pipe_t | k_work_t |
|
||
| 数据缓存 | 堆 | 独立 | 独立 | 堆 |
|
||
| 数据吞吐 | 中 | 慢 | 快 | 中 |
|
||
| 数据交换 | 指针 | 副本 | 副本 | 指针 |
|
||
| 单位长度 | 不限 | 固定 | 字节 | 不限 |
|
||
| 总长度 | 不限 | 固定 | 固定 | 不限 |
|
||
| 在中断申请缓存 | 禁止 | 可用 | 不需要 | 禁止 |
|
||
| work | 完整可用 | 完整可用 | 完整可用 | 完整可用 |
|
||
| timer | 仅收发 | 仅收发 | 仅收发 | 仅发送 |
|
||
| isr | 仅收发 | 仅收发 | 仅收发 | 仅发送 |
|
||
|
||
## 调度机制
|
||
|
||
> 每个 work 对象都对应一个勾子函数为任务,由入口 k_work_q_handler() 管理(软定时器同理),通过三个关键链表的操作,调用对应的勾子函数。
|
||
> 主要由接口 k_work_submit(), k_work_resume(), k_work_suspend(), k_work_later() 等触发有关链表的操作。
|
||
|
||
- dlist_t event_list;
|
||
> dlist_t event_list 是一个双向链表,由上述的接口插入,在队列管理接口中取出;
|
||
|
||
- slist_t ready_list[8];
|
||
> dlist_t event_list 共8个成员的单向链表,每个成员表示一个优先级,由队列管理接口使用;
|
||
|
||
- slist_t delayed_list;
|
||
> slist_t delayed_list 是一个单向链表,由队列管理接口使用;
|
||
|
||
- 触发调试的过程:
|
||
1. 在接口 k_work_submit() 中把任务对象添加超时信息并插入到 event_list 中;
|
||
2. k_work_q_handler() 检测 delayed_list 如果有超时的任务,插入到 ready_list 中;
|
||
3. k_work_q_handler() 总是在 event_list 取出任务对象,如果:
|
||
- 任务已超时:插入到 ready_list;
|
||
- 任务未超时:按时间顺序,插入到 delayed_list;
|
||
4. 在 ready_list 中查找,如果:
|
||
- 存在任务:从链中删除并执行任务;
|
||
- 没有任务:无动作;
|
||
5. 返回下个超时的任务的剩余时间;
|
||
|
||
## END
|
||
|