Files
ESPC3-wireless/components/system/source/k_kit
LokLiang 176b2c49f6 20250529 同步自原始工程:
优化 CMakeLists.txt,增加 lib-out 目录的包含;修改 app_config.c 中的 LED 灯带开关变量名;更新 app_config.h,增加新的灯效模式和方向控制;更新 SBDEMO.h 中的默认设备名称;在 msc_host.c 中添加 USB 设备连接类型的处理;在 usbport.c 中增加 USB 连接类型的状态管理;更新 Kconfig,增加 LED 灯带的最大图层数和竞速模式选项;新增 spbelib_interface.h 文件,定义无线调参功能接口;删除不再使用的 components/CMakeLists.txt 文件;更新 misc.h,添加读取 MCU 身份信息的 MD5 值的函数声明;修改 tim.h 中的 drv_pwm_init 函数参数;更新 kk.h,增加默认工作队列的创建宏;优化 sh.c 中的命令行插入字符串逻辑;更新 sdkconfig 默认配置文件,升级 ESP-IDF 版本和调整蓝牙默认发射功率。
2025-05-29 18:05:20 +08:00
..
2025-05-29 18:05:20 +08:00
2024-03-28 12:19:52 +08:00

简要

微内核 k_kit

k_kit 以下简称 kit。kit 可以理解成是一个实时内核中的软定时器模块的强化版。 基于此设计的程序就是由所有软定时器组成的集合,这些集合既可作为一个完整的工程,也可以作为一个线程模块,使用非常灵活。

特点

  • 是一个极小的,由事件驱动的,管理任务的微内核;
  • 介于裸机与实时内核之间,适用于资源受限的微型系统的同时,尽可能提供类似实时内核接口和管理方式;
  • 极低的跨平台需求,只需要实现几个简单的接口,即可在任何平台上运行;
  • 所有功能模块都有独立的对象,所有对象动通过态申请和销毁;
  • 极短的、固定的关中断时间,有效保障硬实时性;
  • 基于 kit 设计的工程可无缝扩充到 RTK 实时内核中 点击查看 RTK

文件结构

...
└── 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