参考代码
This commit is contained in:
109
components/system/source/k_kit/README.md
Executable file
109
components/system/source/k_kit/README.md
Executable file
@@ -0,0 +1,109 @@
|
||||
[简要](../../../../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
|
||||
|
||||
4437
components/system/source/k_kit/k_kit.c
Executable file
4437
components/system/source/k_kit/k_kit.c
Executable file
File diff suppressed because it is too large
Load Diff
311
components/system/source/k_kit/k_kit.h
Executable file
311
components/system/source/k_kit/k_kit.h
Executable file
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* @file k_kit.h
|
||||
* @author LokLiang (lokliang@163.com)
|
||||
* @brief 裸机版微内核
|
||||
* @version 1.1.0
|
||||
*
|
||||
* @copyright Copyright (c) 2022
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __K_KIT_H__
|
||||
#define __K_KIT_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef int k_err_t;
|
||||
typedef int k_tick_t;
|
||||
|
||||
typedef void* k_hdl_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_work_q_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *(*malloc)(size_t); // 执行申请内存(内部已通过 scheduler_disable()/scheduler_enable() 进行临界保护)
|
||||
void (*free)(void *); // 执行释放内存(内部已通过 scheduler_disable()/scheduler_enable() 进行临界保护)
|
||||
unsigned (*get_sys_ticks)(void); // 获取当前系统时间
|
||||
unsigned (*interrupt_save)(void); // 禁止中断
|
||||
void (*interrupt_restore)(unsigned); // 恢复中断
|
||||
|
||||
void (*scheduler_disable)(void); // 禁止线程的调度(实时内核使用,非实时内核使用可设置为NULL)
|
||||
void (*scheduler_enable)(void); // 恢复线程的调度(实时内核使用,非实时内核使用可设置为NULL)
|
||||
k_work_q_t *(*get_work_q_hdl)(void); // 获取当前执行 k_work_q_handler() 的线程的 k_work_q_t 对象(实时内核使用,非实时内核使用可设置为NULL)
|
||||
void (*thread_sleep)(k_tick_t sleep_ticks); // 使线程休眠(实时内核使用,非实时内核使用可设置为NULL)
|
||||
} k_init_t;
|
||||
|
||||
void k_entry(const k_init_t *init_struct); // 初始化并进入微内核模式
|
||||
|
||||
void k_init(const k_init_t *init_struct); // 初始化微内核
|
||||
void k_deinit(void); // 取消初始化微内核
|
||||
|
||||
/** @defgroup work queue
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef void (*k_work_q_fn)(void *arg);
|
||||
|
||||
extern k_work_q_t *default_work_q_hdl; // 预留的一个工默认的作队列对象内存,初始值为内部默认的对象
|
||||
|
||||
k_tick_t k_work_q_handler(k_work_q_t *work_q_handle); // 工作队列执行入口
|
||||
|
||||
k_err_t k_work_q_create(k_work_q_t *work_q_handle); // 创建一个工作队列的对象
|
||||
void k_work_q_delete(k_work_q_t *work_q_handle); // 删除一个工作队列的对象
|
||||
|
||||
void k_work_q_resume_regist(k_work_q_t *work_q_handle, k_work_q_fn work_q_resume, void *arg); // 注册一个函数:当有任务被提交时,此回调函数将被自动执行
|
||||
|
||||
bool k_work_q_is_valid(k_work_q_t *work_q_handle); // 获取工作队列是否有效
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup work
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_work_t;
|
||||
|
||||
typedef void (*k_work_fn)(void *arg);
|
||||
|
||||
void k_work_hook(k_work_q_t *work_q_handle, k_work_fn hook); // 设置切换任务时,进入和退出任务时回调函数
|
||||
|
||||
bool k_work_q_delayed_state(k_work_q_t *work_q_handle); // 获取是否有正在延时状态的任务
|
||||
bool k_work_q_ready_state(k_work_q_t *work_q_handle); // 获取工作队列中是否有就绪的任务
|
||||
|
||||
k_err_t k_work_create(k_work_t *work_handle,
|
||||
const char *name,
|
||||
k_work_fn work_route,
|
||||
void *arg,
|
||||
uint8_t priority);
|
||||
|
||||
void k_work_delete(k_work_t *work_handle); // 删除由工作队列管理的任务
|
||||
|
||||
bool k_work_is_valid(k_work_t *work_handle); // 获取任务对象是否有效
|
||||
bool k_work_is_pending(k_work_t *work_handle); // 获取任务是否在就绪或延时的状态
|
||||
k_tick_t k_work_time_remain(k_work_t *work_handle); // 获取任务距离下个执行的剩余时间
|
||||
|
||||
void k_work_submit(k_work_q_t *work_q_handle, k_work_t *work_handle, k_tick_t delay_ticks); // 使任务在指定工作队列中在指定时间后就绪
|
||||
void k_work_resume(k_work_t *work_handle, k_tick_t delay_ticks); // 唤醒任务。注意需要先使用 k_work_submit 绑定一个 work_q_handle
|
||||
void k_work_suspend(k_work_t *work_handle); // 挂起任务,任务不会被删除
|
||||
|
||||
void k_work_later(k_tick_t delay_ticks); // 延时多少个系统节拍后再执行本任务
|
||||
void k_work_later_until(k_tick_t delay_ticks); // 从最后一次唤醒的时间算起,延时多少个系统节拍后再执行本任务(固定周期的延时)
|
||||
void k_work_yield(k_tick_t delay_ticks); // 释放一次CPU的使用权,不调度低于当前任务优先级的任务
|
||||
void k_work_sleep(k_tick_t delay_ticks); // 释放一次CPU的使用权,可调度低于当前任务优先级的任务
|
||||
|
||||
k_work_t *k_get_curr_work_handle(k_work_q_t *work_q_handle); // 查询最近一次执行的任务
|
||||
|
||||
k_err_t k_work_mbox_create(k_work_t *work_handle); // 创建任务的邮箱
|
||||
void k_work_mbox_delete(k_work_t *work_handle); // 删除任务的邮箱
|
||||
|
||||
void *k_work_mbox_alloc(k_work_t *work_handle, size_t size); // 申请一个邮件
|
||||
k_err_t k_work_mbox_cancel(void *mbox); // 取消已申请的邮件
|
||||
k_err_t k_work_mbox_submit(void *mbox); // 发送邮件
|
||||
void *k_work_mbox_take(void); // 提取邮件
|
||||
void *k_work_mbox_peek(void); // 查询邮件
|
||||
void k_work_mbox_clr(void); // 清空任务的所有邮件
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup timer queue
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_timer_q_t;
|
||||
|
||||
typedef void (*k_timer_q_fn)(void *arg);
|
||||
|
||||
extern k_timer_q_t *default_timer_q_hdl; // 预留的一个工默认的软定时器队列对象内存,初始值为内部默认的对象
|
||||
|
||||
k_tick_t k_timer_q_handler(k_timer_q_t *timer_q_handle); // 软定时器队列执行入口
|
||||
|
||||
k_err_t k_timer_q_create(k_timer_q_t *timer_q_handle); // 创建一个软定时器队列的对象
|
||||
void k_timer_q_delete(k_timer_q_t *timer_q_handle); // 删除一个软定时器队列的对象
|
||||
|
||||
void k_timer_q_resume_regist(k_timer_q_t *timer_q_handle, k_timer_q_fn timer_q_resume, void *arg); // 注册一个函数:当有任务被提交时,此回调函数将被自动执行
|
||||
|
||||
bool k_timer_q_is_valid(k_timer_q_t *timer_q_handle); // 获取软定时器队列是否有效
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup timer
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_timer_t;
|
||||
|
||||
typedef void (*k_timer_fn)(void *arg);
|
||||
|
||||
bool k_timer_q_delayed_state(k_timer_q_t *timer_q_handle); // 获取是否有正在延时状态的定时器
|
||||
bool k_timer_q_ready_state(k_timer_q_t *timer_q_handle); // 获取软定时器队列中是否有就绪的定时器
|
||||
|
||||
k_err_t k_timer_create(k_timer_t *timer_handle,
|
||||
k_timer_q_t *timer_q_handle,
|
||||
k_timer_fn timer_route,
|
||||
void *arg,
|
||||
uint8_t priority);
|
||||
|
||||
void k_timer_delete(k_timer_t *timer_handle);
|
||||
|
||||
void k_timer_set_period(k_timer_t *timer_handle, bool periodic, k_tick_t period); // 设置定时器的自动重装值
|
||||
void k_timer_start(k_timer_t *timer_handle, k_tick_t delay_ticks); // 使定时器在指定软定时器队列中在指定时间后就绪
|
||||
void k_timer_stop(k_timer_t *timer_handle); // 挂起定时器,定时器不会被删除
|
||||
|
||||
k_err_t k_timer_newsubmit(k_timer_q_t *timer_q_handle, k_timer_fn timer_route, void *arg, k_tick_t delay_ticks); // 生成一个临时定时器,执行完自动删除
|
||||
k_err_t k_timer_resubmit(k_timer_q_t *timer_q_handle, k_timer_fn timer_route, void *arg, k_tick_t delay_ticks); // 删除并重新生成一个新的临时定时器,执行完自动删除
|
||||
void k_timer_cancel(k_timer_q_t *timer_q_handle, k_timer_fn timer_route); // 立即删除临时定时器
|
||||
|
||||
bool k_timer_is_valid(k_timer_t *timer_handle); // 获取定时器对象是否有效
|
||||
bool k_timer_is_pending(k_timer_t *timer_handle); // 获取定时器是否在就绪或延时的状态
|
||||
bool k_timer_is_periodic(k_timer_t *timer_handle); // 查询当前是否自动重装
|
||||
k_tick_t k_timer_get_period(k_timer_t *timer_handle); // 查询当前的自动重装值
|
||||
k_tick_t k_timer_time_remain(k_timer_t *timer_handle); // 获取定时器距离下个执行的剩余时间
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup fifo
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_fifo_t;
|
||||
|
||||
k_err_t k_fifo_q_create(k_fifo_t *fifo_handle); // 创建一个 FIFO 对象
|
||||
void k_fifo_q_delete(k_fifo_t *fifo_handle); // 删除一个 FIFO 的对象
|
||||
void k_fifo_q_clr(k_fifo_t *fifo_handle); // 清除 FIFO 内的所有数据
|
||||
|
||||
bool k_fifo_q_is_valid(k_fifo_t *fifo_handle); // 获取 FIFO 对象是否有效
|
||||
|
||||
void k_fifo_q_regist(k_fifo_t *fifo_handle, k_work_t *work_handle, k_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
|
||||
void k_fifo_q_unregist(k_fifo_t *fifo_handle); // 取消注册任务
|
||||
|
||||
void *k_fifo_alloc(size_t size); // 申请可用于 FIFO 的数据结构
|
||||
k_err_t k_fifo_free(void *data); // 释放由 k_fifo_alloc() 申请的数据结构
|
||||
|
||||
k_err_t k_fifo_put(k_fifo_t *fifo_handle, void *data); // 把数据结构压入到 FIFO 中
|
||||
void *k_fifo_take(k_fifo_t *fifo_handle); // 从 FIFO 中弹出最先压入的数据
|
||||
void *k_fifo_peek_head(k_fifo_t *fifo_handle); // 查询 FIFO 中头部的数据地址
|
||||
void *k_fifo_peek_tail(k_fifo_t *fifo_handle); // 查询 FIFO 中尾部的数据地址
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup queue
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_queue_t;
|
||||
|
||||
k_err_t k_queue_create(k_queue_t *queue_handle, size_t queue_length, size_t item_size); // 创建一个 QUEUE 对象
|
||||
void k_queue_delete(k_queue_t *queue_handle); // 删除一个 QUEUE 的对象
|
||||
void k_queue_clr(k_queue_t *queue_handle); // 清除 QUEUE 内的所有数据
|
||||
|
||||
bool k_queue_is_valid(k_queue_t *queue_handle); // 获取 QUEUE 对象是否有效
|
||||
|
||||
void k_queue_regist(k_queue_t *queue_handle, k_work_t *work_handle, k_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
|
||||
void k_queue_unregist(k_queue_t *queue_handle); // 取消注册任务
|
||||
|
||||
k_err_t k_queue_recv(k_queue_t *queue_handle, void *dst); // 接收并复制数据
|
||||
k_err_t k_queue_send(k_queue_t *queue_handle, const void *src); // 复制数据并发送
|
||||
|
||||
void *k_queue_alloc(k_queue_t *queue_handle); // 申请可用于 QUEUE 的数据结构
|
||||
k_err_t k_queue_free(void *data); // 释放由 k_queue_alloc() 申请的数据结构
|
||||
k_err_t k_queue_put(void *data); // 把数据压入到 QUEUE 中
|
||||
void *k_queue_take(k_queue_t *queue_handle); // 从 QUEUE 中弹出最先压入的数据
|
||||
|
||||
void *k_queue_peek_head(k_queue_t *queue_handle); // 查询 QUEUE 中头部的数据地址
|
||||
void *k_queue_peek_tail(k_queue_t *queue_handle); // 查询 QUEUE 中尾部的数据地址
|
||||
|
||||
size_t k_queue_get_item_size(k_queue_t *queue_handle); // 读回 k_queue_create() 中设置的 item_size 的值
|
||||
|
||||
k_queue_t *k_queue_read_handle(void *data); // 查询已申请数据的所属队列句柄
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup pipe
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
k_hdl_t hdl;
|
||||
} k_pipe_t;
|
||||
|
||||
k_err_t k_pipe_create(k_pipe_t *pipe_handle, size_t pipe_size); // 创一个管道对象
|
||||
void k_pipe_delete(k_pipe_t *pipe_handle); // 删除一个管道对象
|
||||
void k_pipe_clr(k_pipe_t *pipe_handle); // 清空管道的数据
|
||||
|
||||
bool k_pipe_is_valid(k_pipe_t *pipe_handle); // 获取 PIPE 对象是否有效
|
||||
|
||||
void k_pipe_regist(k_pipe_t *pipe_handle, k_work_t *work_handle, k_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
|
||||
void k_pipe_unregist(k_pipe_t *pipe_handle); // 取消注册任务
|
||||
|
||||
size_t k_pipe_poll_write(k_pipe_t *pipe_handle, uint8_t data); // 写一个字节到缓存中(写入缓存),返回实际复制成功的字节数
|
||||
size_t k_pipe_fifo_fill(k_pipe_t *pipe_handle, const void *data, size_t size); // 把内存数据复制到缓存中(写入缓存),返回实际复制成功的字节数
|
||||
size_t k_pipe_poll_read(k_pipe_t *pipe_handle, uint8_t *data); // 从缓存复制一个字节到指定地址中,返回 0 表示缓存空
|
||||
size_t k_pipe_fifo_read(k_pipe_t *pipe_handle, void *data, size_t size); // 从管道中复制数据到内存(从缓存读取),返回实际复制成功的字节数。注:参数 data 值可以为 NULL,此时不复制数据,只释放相应的数据量
|
||||
|
||||
bool k_pipe_is_ne(k_pipe_t *pipe_handle); // 获取管道非空, true 有数据
|
||||
size_t k_pipe_get_valid_size(k_pipe_t *pipe_handle); // 获取管道的数据大小(字节数)
|
||||
size_t k_pipe_get_empty_size(k_pipe_t *pipe_handle); // 获取管道的剩余空间(字节数)
|
||||
|
||||
void k_pipe_peek_valid(k_pipe_t *pipe_handle, void **dst_base, size_t *dst_size); // 获取当前已写入的连续的内存信息
|
||||
void k_pipe_peek_empty(k_pipe_t *pipe_handle, void **dst_base, size_t *dst_size); // 获取当前空闲的连续的内存信息
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup miscellaneous
|
||||
* @{
|
||||
*/
|
||||
|
||||
k_tick_t k_get_sys_ticks(void); // 获取当前系统时间
|
||||
void k_disable_interrupt(void); // 禁止中断(屏蔽中断并自动记录嵌套数)
|
||||
void k_enable_interrupt(void); // 恢复中断(根据嵌套数自动恢复中断)
|
||||
|
||||
void k_log_sched(void); // 打印当前调度日志
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
153
components/system/source/k_kit/kk.h
Executable file
153
components/system/source/k_kit/kk.h
Executable file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @file kk.h
|
||||
* @author lokliang
|
||||
* @brief k_kit.h 衍生的易用接口,简化部分接口中的参数,去除不常用的接口
|
||||
* @version 1.0
|
||||
* @date 2022-12-09
|
||||
* @date 2021-01-13
|
||||
*
|
||||
* @copyright Copyright (c) 2021
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __KK_H__
|
||||
#define __KK_H__
|
||||
|
||||
#include "k_kit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef k_err_t kk_err_t;
|
||||
typedef k_tick_t kk_time_t;
|
||||
typedef k_work_q_t kk_work_q_t;
|
||||
typedef k_work_t kk_work_t;
|
||||
typedef k_timer_t kk_timer_t;
|
||||
typedef k_fifo_t kk_fifo_t;
|
||||
typedef k_queue_t kk_queue_t;
|
||||
typedef k_pipe_t kk_pipe_t;
|
||||
|
||||
#define WORK_Q_HDL default_work_q_hdl
|
||||
#define TIMER_Q_HDL default_timer_q_hdl
|
||||
|
||||
#define kk_handler() k_work_q_handler(WORK_Q_HDL) // 工作队列执行入口
|
||||
#define kk_timer_handler() k_timer_q_handler(TIMER_Q_HDL) // 软定时器队列执行入口
|
||||
|
||||
#define kk_work_q_delayed_state() k_work_q_delayed_state(WORK_Q_HDL) // 获取是否有正在延时状态的任务
|
||||
#define kk_work_q_ready_state() k_work_q_ready_state(WORK_Q_HDL) // 获取工作队列中是否有就绪的任务
|
||||
#define kk_work_q_delete() k_work_q_delete(WORK_Q_HDL) // 删除一个工作队列的对象
|
||||
#define kk_work_q_is_valid() k_work_q_is_valid(WORK_Q_HDL) // 获取工作队列是否有效
|
||||
|
||||
#define kk_work_create(work_handle, work_route, arg, priority) k_work_create(work_handle, #work_route, work_route, arg, priority) // 创建由工作队列管理的任务
|
||||
#define kk_work_delete(work_handle) k_work_delete(work_handle) // 删除由工作队列管理的任务
|
||||
#define kk_work_submit(work_q_handle, work_handle, delay) k_work_submit(work_q_handle, work_handle, delay) // 多少时间后唤醒任务
|
||||
|
||||
#define kk_work_is_valid(work_handle) k_work_is_valid(work_handle) // 获取任务对象是否有效
|
||||
#define kk_work_is_pending(work_handle) k_work_is_pending(work_handle) // 获取任务是否在就绪或延时的状态
|
||||
#define kk_work_time_remain(work_handle) k_work_time_remain(work_handle) // 获取任务距离下个执行的剩余时间
|
||||
|
||||
#define kk_timer_create(timer_handle, timer_route, arg) k_timer_create(timer_handle, TIMER_Q_HDL, timer_route, arg, 0) // 创建由软定时器队列管理的定时器任务
|
||||
#define kk_timer_delete(timer_handle) k_timer_delete(timer_handle) // 删除由软定时器队列管理的定时器任务
|
||||
|
||||
#define kk_timer_start(timer_handle, periodic, period) do { k_timer_set_period(timer_handle, periodic, period); k_timer_start(timer_handle, period); } while (0) // 启动定时器
|
||||
#define kk_timer_stop(timer_handle) k_timer_stop(timer_handle) // 挂起定时器,定时器不会被删除
|
||||
|
||||
#define kk_timer_is_valid(timer_handle) k_timer_is_valid(timer_handle) // 获取定时器对象是否有效
|
||||
#define kk_timer_is_pending(timer_handle) k_timer_is_pending(timer_handle) // 获取定时器是否在就绪或延时的状态
|
||||
#define kk_timer_time_remain(timer_handle) k_timer_time_remain(timer_handle) // 获取定时器距离下个执行的剩余时间
|
||||
|
||||
#define kk_work_mbox_create(work_handle) k_work_mbox_create(work_handle) // 创建任务的邮箱
|
||||
#define kk_work_mbox_delete(work_handle) k_work_mbox_delete(work_handle) // 删除任务的邮箱
|
||||
|
||||
#define kk_fifo_q_create(fifo_handle) k_fifo_q_create(fifo_handle) // 创建一个FIFO对象
|
||||
#define kk_fifo_q_delete(fifo_handle) k_fifo_q_delete(fifo_handle) // 删除一个FIFO的对象
|
||||
#define kk_fifo_q_clr(fifo_handle) k_fifo_q_clr(fifo_handle) // 清除FIFO内的所有数据
|
||||
#define kk_fifo_q_is_valid(fifo_handle) k_fifo_q_is_valid(fifo_handle) // 获取 FIFO 对象是否有效
|
||||
#define kk_fifo_q_regist(fifo_handle, work_handle, ticks) k_fifo_q_regist(fifo_handle, work_handle, ticks) // 注册当队列非空时被唤醒的任务
|
||||
|
||||
#define kk_queue_create(queue_handle, queue_length, item_size) k_queue_create(queue_handle, queue_length, item_size) // 创建一个QUEUE对象
|
||||
#define kk_queue_delete(queue_handle) k_queue_delete(queue_handle) // 删除一个QUEUE的对象
|
||||
#define kk_queue_clr(queue_handle) k_queue_clr(queue_handle) // 清除QUEUE内的所有数据
|
||||
#define kk_queue_is_valid(queue_handle) k_queue_is_valid(queue_handle) // 获取 QUEUE 对象是否有效
|
||||
#define kk_queue_regist(queue_handle, work_handle, ticks) k_queue_regist(queue_handle, work_handle, ticks) // 注册当队列非空时被唤醒的任务
|
||||
|
||||
#define kk_pipe_create(pipe_handle, pipe_size) k_pipe_create(pipe_handle, pipe_size) // 创一个管道对象
|
||||
#define kk_pipe_delete(pipe_handle) k_pipe_delete(pipe_handle) // 删除一个管道对象
|
||||
#define kk_pipe_clr(pipe_handle) k_pipe_clr(pipe_handle) // 清空管道的数据
|
||||
#define kk_pipe_is_valid(pipe_handle) k_pipe_is_valid(pipe_handle) // 获取 PIPE 对象是否有效
|
||||
#define kk_pipe_regist(pipe_handle, work_handle, ticks) k_pipe_regist(pipe_handle, work_handle, ticks) // 注册当队列非空时被唤醒的任务
|
||||
|
||||
#define kk_work_resume(work_handle, delay) k_work_resume(work_handle, delay) // 唤醒任务。注意需要先使用 k_work_submit 绑定一个 work_q_handle
|
||||
#define kk_work_suspend(work_handle) k_work_suspend(work_handle) // 挂起任务,任务不会被删除
|
||||
#define kk_work_later(delay) k_work_later(delay) // 设置下个执行延时
|
||||
#define kk_work_later_until(delay) k_work_later_until(delay) // 从最后一次唤醒的时间算起,延时多少个系统节拍后再执行本任务(固定周期的延时)
|
||||
#define kk_work_yield(delay) k_work_yield(delay) // 释放一次CPU的使用权,不调度低于当前任务优先级的任务
|
||||
#define kk_work_sleep(delay) k_work_sleep(delay) // 释放一次CPU的使用权,可调度低于当前任务优先级的任务
|
||||
|
||||
#define kk_work_mbox_alloc(work_handle, size) k_work_mbox_alloc(work_handle, size) // 申请一个邮件
|
||||
#define kk_work_mbox_cancel(mbox) k_work_mbox_cancel(mbox) // 取消已申请的邮件
|
||||
#define kk_work_mbox_submit(mbox) k_work_mbox_submit(mbox) // 发送邮件
|
||||
#define kk_work_mbox_take() k_work_mbox_take() // 提取邮件
|
||||
#define kk_work_mbox_peek() k_work_mbox_peek() // 查询邮件
|
||||
#define kk_work_mbox_clr() k_work_mbox_clr() // 清空任务的所有邮件
|
||||
|
||||
#define kk_fifo_alloc(size) k_fifo_alloc(size) // 申请可用于FIFO的数据结构
|
||||
#define kk_fifo_free(data) k_fifo_free(data) // 释放由 kk_fifo_alloc() 申请的数据结构
|
||||
#define kk_fifo_put(fifo_handle, data) k_fifo_put(fifo_handle, data) // 把数据结构压入到FIFO中
|
||||
#define kk_fifo_take(fifo_handle) k_fifo_take(fifo_handle) // 从FIFO中弹出最先压入的数据
|
||||
#define kk_fifo_peek_head(fifo_handle) k_fifo_peek_head(fifo_handle) // 查询FIFO中头部的数据地址
|
||||
#define kk_fifo_peek_tail(fifo_handle) k_fifo_peek_tail(fifo_handle) // 查询FIFO中尾部的数据地址
|
||||
|
||||
#define kk_queue_recv(queue_handle, dst) k_queue_recv(queue_handle, dst) // 接收并复制数据
|
||||
#define kk_queue_send(queue_handle, src) k_queue_send(queue_handle, src) // 复制数据并发送
|
||||
#define kk_queue_alloc(queue_handle) k_queue_alloc(queue_handle) // 申请可用于QUEUE的数据结构
|
||||
#define kk_queue_free(data) k_queue_free(data) // 释放由 kk_queue_alloc() 申请的数据结构
|
||||
#define kk_queue_put(data) k_queue_put(data) // 把数据压入到QUEUE中
|
||||
#define kk_queue_take(queue_handle) k_queue_take(queue_handle) // 从QUEUE中弹出最先压入的数据
|
||||
#define kk_queue_peek_head(queue_handle) k_queue_peek_head(queue_handle) // 查询QUEUE中头部的数据地址
|
||||
#define kk_queue_peek_tail(queue_handle) k_queue_peek_tail(queue_handle) // 查询QUEUE中尾部的数据地址
|
||||
#define kk_queue_get_item_size(queue_handle) k_queue_get_item_size(queue_handle); // 读回 k_queue_create() 中设置的 item_size 的值
|
||||
|
||||
#define kk_pipe_fifo_fill(pipe_handle, data, size) k_pipe_fifo_fill(pipe_handle, data, size) // 把内存数据复制到缓存中(写入缓存),返回实际复制成功的字节数
|
||||
#define kk_pipe_poll_write(pipe_handle, data) k_pipe_poll_write(pipe_handle, data) // 写一个字节到缓存中(写入缓存),返回实际复制成功的字节数
|
||||
#define kk_pipe_fifo_read(pipe_handle, data, size) k_pipe_fifo_read(pipe_handle, data, size) // 从管道中复制数据到内存(从缓存读取),返回实际复制成功的字节数。注:参数 data 值可以为 NULL,此时不复制数据,只释放相应的数据量
|
||||
#define kk_pipe_poll_read(pipe_handle, data) k_pipe_poll_read(pipe_handle, data) // 从缓存复制一个字节到指定地址中,返回 0 表示缓存空
|
||||
|
||||
#define kk_pipe_is_ne(pipe_handle) k_pipe_is_ne(pipe_handle) // 获取管道非空, true 有数据
|
||||
#define kk_pipe_get_valid_size(pipe_handle) k_pipe_get_valid_size(pipe_handle) // 获取管道的数据大小(字节数)
|
||||
#define kk_pipe_get_empty_size(pipe_handle) k_pipe_get_empty_size(pipe_handle) // 获取管道的剩余空间(字节数)
|
||||
|
||||
#define kk_pipe_peek_valid(pipe_handle, dst_data, dst_size) k_pipe_peek_valid(pipe_handle, dst_data, dst_size) // 获取当前已写入的连续的内存信息
|
||||
#define kk_pipe_peek_empty(pipe_handle, dst_data, dst_size) k_pipe_peek_empty(pipe_handle, dst_data, dst_size) // 获取当前空闲的连续的内存信息
|
||||
|
||||
#define kk_get_sys_ticks() k_get_sys_ticks() // 获取当前系统时间
|
||||
#define kk_get_heap_mem() k_get_heap_mem() // 获取初始化时指定的堆内存
|
||||
|
||||
#define kk_disable_interrupt() k_disable_interrupt() // 禁止中断
|
||||
#define kk_enable_interrupt() k_enable_interrupt() // 恢复中断
|
||||
|
||||
#define kk_log_sched() k_log_sched() // 打印当前调度日志
|
||||
|
||||
#if defined(MIX_COMMON)
|
||||
#include "heap.h"
|
||||
#endif
|
||||
|
||||
#define kk_malloc(size) heap_malloc(NULL, size) // 申请内存
|
||||
#define kk_calloc(size) heap_calloc(NULL, size) // 申请内存并置0
|
||||
#define kk_realloc(ptr, size) heap_realloc(NULL, ptr, size) // 重定义已申请的内存大小
|
||||
#define kk_free(ptr) heap_free(NULL, ptr) // 释放内存
|
||||
|
||||
#define kk_heap_is_valid(ptr) heap_is_valid(NULL, ptr) // 获取内存指针是否有效
|
||||
#define kk_heap_block_size(ptr) heap_block_size(ptr) // 已申请内存块的实际占用空间大小(不含所有控制信息)(字节)
|
||||
#define kk_heap_space_size(ptr) heap_space_size(ptr) // 已申请内存块的实际占用空间大小(含所有控制信息)(字节)
|
||||
#define kk_heap_used_size() heap_used_size(NULL) // 获取总已使用空间
|
||||
#define kk_heap_free_size() heap_free_size(NULL) // 获取总空闲空间(包含所有碎片)
|
||||
#define kk_heap_block_max() heap_block_max(NULL) // 获取当前最大的连续空间
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user