Files
ESPC3-wireless/components/system/source/k_kit/k_kit.h

318 lines
14 KiB
C
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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_default(k_work_t *work_handle,
const char *name,
k_work_fn work_route,
void *arg,
uint8_t priority,
k_tick_t delay_ticks);
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