[简要](../../../../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