diff --git a/System/os_var.c b/System/os_var.c new file mode 100644 index 00000000..667b570d --- /dev/null +++ b/System/os_var.c @@ -0,0 +1,81 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file os_var.c + * @brief 系统全局变量定义 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_redef.h" + +/* The Soft-RTC */ +#if SYSCFG_SOFTRTC == __ENABLED__ +const s_u8_t _CONST_MEM_ s_month0day[13] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /*!< 每月各有几天?*/ + s_u8_t _RTC_MEM_ s_month2day = 28; /*!< 二月有几天?*/ +volatile s_every_ts _SYS_MEM_ s_sign_every = {0}; /*!< 每信号 */ + s_rtc_ts _RTC_MEM_ s_rtc = {SYSCFG_MANUFACTUREDATE}; /*!< RTC正本 */ +#if SYSCFG_GETRTC_INT == __ENABLED__ + s_rtc_ts _RTC_MEM_ s_rtc_copy = {SYSCFG_MANUFACTUREDATE}; /*!< RTC副本 */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_rtc = false; /*!< 更新RTC副本信号 */ +#endif +#endif +/* The Task */ + m_bit_t /*_SYS_MEM_*/ s_sign_return = true; /*!< 返回信号 */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule = false; /*!< 调度信号 */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule_all = false; /*!< 完整调度信号 */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule_forbid = false; /*!< 禁止调度信号 */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_switch_prigroup = false; /*!< 优先级组切换信号 */ + s_u8_t _SYS_MEM_ s_forbid_counter = 0; /*!< 禁止调度嵌套计数器 */ + s_u8_t _SYS_MEM_ s_taskcri_counter = 0; /*!< 任务临界区嵌套计数器 */ + s_sharing_t _SYS_MEM_ s_tick_counter = 0; /*!< 系统滴答计数器 */ + s_ecode_t _SYS_MEM_ s_startup_code = OS_ECODE_NOERROR; /*!< 启动任务时,用来异地缓存错误码 */ + s_u8_t _SYS_MEM_ s_task_status0 = OS_STATUS_DELETED; /*!< 被启动任务 -> 初始状态 */ + s_taskhand_tsp _SYS_MEM_ s_task_starter = OS_NULL; /*!< 被启动任务 -> 装载块句柄 */ + s_tasknode_tsp _SYS_MEM_ s_task_current = OS_NULL; /*!< 当前任务句柄 */ + s_tasknode_tsp _SYS_MEM_ s_task_switch = OS_NULL; /*!< 立即切换至某任务 -> 任务句柄 */ + s_tasknode_tsp _SYS_MEM_ s_taskpri_tail = OS_NULL; /*!< 设置任务优先级时 -> 临时链表的尾节点 */ +#if SYSCFG_SAFERUNTIME == __ENABLED__ + s_bool_t s_sign_timeout[OS_TASKTOTAL + 1]; /*!< 超时信号,安全运行时专用 */ +#endif +#if SYSCFG_TIMESHARINGMODE == 2 +const s_sharing_t _CONST_MEM_ s_time_sharing[SYSCFG_TASKPRIORITY] = {SYSCFG_CUSTOMTIMESHARING}; /*!< 自定义时间片 -> 时间片数组 */ +#endif +/* The Timing Interrupt */ +#if OS_TIMINTTOTAL + s_timinthand_tsp s_timint_handle[OS_TIMINTTOTAL]; /*!< 定时中断句柄 */ +#endif +/* The Timing Query */ +#if OS_TIMQRYTOTAL + s_timqryhand_tsp s_timqry_handle[OS_TIMQRYTOTAL]; /*!< 定时查询句柄 */ +#endif +/* The Global Variable Accessor */ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_updatecopy = false; /*!< 更新副本信号 */ +/* The Task Message */ +#if SYSCFG_TASKMSG == __ENABLED__ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_send_taskmsg = false; /*!< 发送私信信号 */ +#endif +/* The Debug Interface */ +#if SYSCFG_DEBUGGING == __ENABLED__ +volatile m_bit_t /*_SYS_MEM_*/ s_sign_taskmgr = SYSCFG_TASKMGRAUTOSTART; +volatile m_bit_t /*_SYS_MEM_*/ s_sign_debug_send = false; +volatile m_bit_t /*_SYS_MEM_*/ s_sign_debug_recv = false; +volatile s_u8_t _SYS_MEM_ s_debug_sendtype = 0; + char _XDATA_MEM_ s_debug_recvbuff[OS_DEBUGRECVBUFFSIZE];/* + char _XDATA_MEM_ s_cmdline_sendbuff[OS_CMDLINESENDBUFFSIZE];*/ + char _XDATA_MEM_ s_taskmgr_sendbuff[OS_TASKMGRSENDBUFFSIZE]; + char _XDATA_MEM_ * _SYS_MEM_ s_debug_recvptr = s_debug_recvbuff; + char _XDATA_MEM_ * _SYS_MEM_ s_debug_sendptr; + s_alarm_ts _DEBUG_MEM_ s_alarm = {0}; + s_fault_ts _DEBUG_MEM_ s_fault = {0}; +#if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ + s_u32_t _DEBUG_MEM_ s_tick_counter1 = 0; + s_u32_t _DEBUG_MEM_ s_tick_counter2 = 0; +#endif +#if SYSCFG_TASKPC_MONITOR == __ENABLED__ + m_pc_t _SYS_MEM_ s_pc = 0; +#endif +#if SYSCFG_RUNTIME_COUNT == __ENABLED__ + s_runtime_ts _DEBUG_MEM_ s_runtime = {0}; +#endif +#endif diff --git a/System/os_var.h b/System/os_var.h new file mode 100644 index 00000000..2dd22ba3 --- /dev/null +++ b/System/os_var.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file os_var.h + * @brief 系统全局变量声明 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __OS_VAR_H +#define __OS_VAR_H +#include "os_redef.h" + +/* The Soft-RTC */ +#if SYSCFG_SOFTRTC == __ENABLED__ +extern const s_u8_t _CONST_MEM_ s_month0day[13]; +extern s_u8_t _RTC_MEM_ s_month2day; +extern volatile s_every_ts _SYS_MEM_ s_sign_every; +extern s_rtc_ts _RTC_MEM_ s_rtc; +#if SYSCFG_GETRTC_INT == __ENABLED__ +extern s_rtc_ts _RTC_MEM_ s_rtc_copy; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_rtc; +#endif +#endif +/* The Task */ +extern m_bit_t /*_SYS_MEM_*/ s_sign_return; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule_all; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_schedule_forbid; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_switch_prigroup; +extern s_u8_t _SYS_MEM_ s_forbid_counter; +extern s_u8_t _SYS_MEM_ s_taskcri_counter; +extern s_sharing_t _SYS_MEM_ s_tick_counter; +extern s_ecode_t _SYS_MEM_ s_startup_code; +extern s_u8_t _SYS_MEM_ s_task_status0; +extern s_taskhand_tsp _SYS_MEM_ s_task_starter; +extern s_tasknode_tsp _SYS_MEM_ s_task_current; +extern s_tasknode_tsp _SYS_MEM_ s_task_switch; +extern s_tasknode_tsp _SYS_MEM_ s_taskpri_tail; +#if SYSCFG_SAFERUNTIME == __ENABLED__ +extern s_bool_t s_sign_timeout[OS_TASKTOTAL + 1]; +#endif +#if SYSCFG_TIMESHARINGMODE == 2 +extern const s_sharing_t _CONST_MEM_ s_time_sharing[SYSCFG_TASKPRIORITY]; +#endif +/* The Timing Interrupt */ +#if OS_TIMINTTOTAL +extern s_timinthand_tsp s_timint_handle[OS_TIMINTTOTAL]; +#endif +/* The Timing Query */ +#if OS_TIMQRYTOTAL +extern s_timqryhand_tsp s_timqry_handle[OS_TIMQRYTOTAL]; +#endif +/* The Global Variable Accessor */ +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_updatecopy; +/* The Task Message */ +#if SYSCFG_TASKMSG == __ENABLED__ +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_send_taskmsg; +#endif +/* The Debug Interface */ +#if SYSCFG_DEBUGGING == __ENABLED__ +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_taskmgr; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_debug_send; +extern volatile m_bit_t /*_SYS_MEM_*/ s_sign_debug_recv; +extern volatile s_u8_t _SYS_MEM_ s_debug_sendtype; +extern char _XDATA_MEM_ s_debug_recvbuff[OS_DEBUGRECVBUFFSIZE];/* +extern char _XDATA_MEM_ s_cmdline_sendbuff[OS_CMDLINESENDBUFFSIZE];*/ +extern char _XDATA_MEM_ s_taskmgr_sendbuff[OS_TASKMGRSENDBUFFSIZE]; +extern char _XDATA_MEM_ * _SYS_MEM_ s_debug_recvptr; +extern char _XDATA_MEM_ * _SYS_MEM_ s_debug_sendptr; +extern s_alarm_ts _DEBUG_MEM_ s_alarm; +extern s_fault_ts _DEBUG_MEM_ s_fault; +#if SYSCFG_SYSTICKTIME_COUNT == __ENABLED__ +extern s_u32_t _DEBUG_MEM_ s_tick_counter1; +extern s_u32_t _DEBUG_MEM_ s_tick_counter2; +#endif +#if SYSCFG_TASKPC_MONITOR == __ENABLED__ +extern m_pc_t _SYS_MEM_ s_pc; +#endif +#if SYSCFG_RUNTIME_COUNT == __ENABLED__ +extern s_runtime_ts _DEBUG_MEM_ s_runtime; +#endif +#endif + +extern void (_CODE_MEM_ * const _CONST_MEM_ sPendSV_FIFOHandler[OS_SVID_END])(void _STATIC_MEM_ *sv); + +#endif diff --git a/System/sv_create.h b/System/sv_create.h new file mode 100644 index 00000000..9dae0b28 --- /dev/null +++ b/System/sv_create.h @@ -0,0 +1,298 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_create.h + * @brief 创建服务 + * @details 用于创建 CosyOS 内核对象。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_CREATE_H +#define __SV_CREATE_H + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 创建服务 + \brief 用于创建 CosyOS 内核对象。 + @{ + */ + +/* + * 声明任务 + */ + +/** 声明静态任务:无私信 */ +#define sCSV_ExternTask(name) \ + extern s_tasknode_tsp u_taskhandle_##name; \ + extern s_tasknode_ts u_taskhand_##name; \ + void name(void) + +/** 声明动态任务:无私信 */ +#define dCSV_ExternTask(name) \ + extern s_tasknode_tsp u_taskhandle_##name; \ + extern s_taskhand_ts u_taskhand_##name; \ + void name(void) + +/** 声明静态任务:有私信 */ +#define sCSV_ExternTask_Msg(name) \ + extern s_tasknode_tsp u_taskhandle_##name; \ + extern s_tasknode_ts u_taskhand_##name; \ + void name(MCUCFG_TASKMSG_VAR, + +/** 声明动态任务:有私信 */ +#define dCSV_ExternTask_Msg(name) \ + extern s_tasknode_tsp u_taskhandle_##name; \ + extern s_taskhand_ts u_taskhand_##name; \ + void name(MCUCFG_TASKMSG_VAR, + + + +/* + * 创建任务 + */ + +#if SYSCFG_DEBUGGING == __ENABLED__ + #if SYSCFG_SAFERUNTIME == __ENABLED__ + /** 静态创建任务:启用 DEBUGGING,启用 安全运行时 */ + #define sCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_ts u_taskhand_##name; \ + s_tasknode_tsp u_taskhandle_##name = &u_taskhand_##name; \ + MCUCFG_STACK_ALIGN static s_u8_t u_taskstack_##name[tss]; \ + s_tasknode_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, #name, srt, u_taskstack_##name, 0}; \ + void name \ + sCreateTaskMsg_##ntm + #else /** 静态创建任务:启用 DEBUGGING,禁用 安全运行时 */ + #define sCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_ts u_taskhand_##name; \ + s_tasknode_tsp u_taskhandle_##name = &u_taskhand_##name; \ + MCUCFG_STACK_ALIGN static s_u8_t u_taskstack_##name[tss]; \ + s_tasknode_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, #name, /**/ u_taskstack_##name, 0}; \ + void name \ + sCreateTaskMsg_##ntm + #endif +#else + #if SYSCFG_SAFERUNTIME == __ENABLED__ + /** 静态创建任务:禁用 DEBUGGING,启用 安全运行时 */ + #define sCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_ts u_taskhand_##name; \ + s_tasknode_tsp u_taskhandle_##name = &u_taskhand_##name; \ + MCUCFG_STACK_ALIGN static s_u8_t u_taskstack_##name[tss]; \ + s_tasknode_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, /****/ srt, u_taskstack_##name, 0}; \ + void name \ + sCreateTaskMsg_##ntm + #else /** 静态创建任务:禁用 DEBUGGING,禁用 安全运行时 */ + #define sCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_ts u_taskhand_##name; \ + s_tasknode_tsp u_taskhandle_##name = &u_taskhand_##name; \ + MCUCFG_STACK_ALIGN static s_u8_t u_taskstack_##name[tss]; \ + s_tasknode_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, /****/ /**/ u_taskstack_##name, 0}; \ + void name \ + sCreateTaskMsg_##ntm + #endif +#endif + +#if SYSCFG_DEBUGGING == __ENABLED__ + #if SYSCFG_SAFERUNTIME == __ENABLED__ + /** 动态创建任务:启用 DEBUGGING,启用 安全运行时 */ + #define dCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_tsp u_taskhandle_##name = OS_NULL; \ + s_taskhand_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, #name, srt}; \ + void name \ + sCreateTaskMsg_##ntm + #else /** 动态创建任务:启用 DEBUGGING,禁用 安全运行时 */ + #define dCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_tsp u_taskhandle_##name = OS_NULL; \ + s_taskhand_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, #name}; \ + void name \ + sCreateTaskMsg_##ntm + #endif +#else + #if SYSCFG_SAFERUNTIME == __ENABLED__ + /** 动态创建任务:禁用 DEBUGGING,启用 安全运行时 */ + #define dCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_tsp u_taskhandle_##name = OS_NULL; \ + s_taskhand_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent, srt}; \ + void name \ + sCreateTaskMsg_##ntm + #else /** 动态创建任务:禁用 DEBUGGING,禁用 安全运行时 */ + #define dCSV_CreateTask(name, pri, tss, srt, ntm, ent) \ + s_tasknode_tsp u_taskhandle_##name = OS_NULL; \ + s_taskhand_ts u_taskhand_##name = {0, 0, pri, tss, &u_taskhandle_##name, ent}; \ + void name \ + sCreateTaskMsg_##ntm + #endif +#endif +/** 静态创建定时中断任务 */ +#define sCSV_CreateTask_TimInt(tmid, arl, name, pri, tss, srt, ntm) \ + void name(void); \ + s_tasknode_ts u_taskhand_##name; \ + s_timinthand_ts _STATIC_MEM_ u_timinthand_##tmid = {0, 0, arl, 1, &u_taskhand_##name}; \ + sCSV_CreateTask(name, pri, tss, srt, ntm, name) + +/** 动态创建定时中断任务 */ +#define dCSV_CreateTask_TimInt(tmid, arl, name, pri, tss, srt, ntm) \ + void name(void); \ + s_taskhand_ts u_taskhand_##name; \ + s_timinthand_ts _STATIC_MEM_ u_timinthand_##tmid = {0, 0, arl, 1, &u_taskhand_##name}; \ + dCSV_CreateTask(name, pri, tss, srt, ntm, name) + +/** 静态创建定时查询任务 */ +#define sCSV_CreateTask_TimQry(tmid, event, arl, name, pri, tss, srt, ntm) \ + void name(void); \ + s_bool_t u_timqryevent_##tmid(void) MCUCFG_C51USING {return (event ? true : false);} \ + s_tasknode_ts u_taskhand_##name; \ + s_timqryhand_ts _STATIC_MEM_ u_timqryhand_##tmid = {(s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), (s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), arl, 1, &u_taskhand_##name, u_timqryevent_##tmid}; \ + sCSV_CreateTask(name, pri, tss, srt, ntm, name) + +/** 动态创建定时查询任务 */ +#define dCSV_CreateTask_TimQry(tmid, event, arl, name, pri, tss, srt, ntm) \ + void name(void); \ + s_bool_t u_timqryevent_##tmid(void) MCUCFG_C51USING {return (event ? true : false);} \ + s_taskhand_ts u_taskhand_##name; \ + s_timqryhand_ts _STATIC_MEM_ u_timqryhand_##tmid = {(s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), (s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), arl, 1, &u_taskhand_##name, u_timqryevent_##tmid}; \ + dCSV_CreateTask(name, pri, tss, srt, ntm, name) + + + +/* + * 创建钩子 + */ + +/** 创建定时中断钩子 */ +#define sCSV_CreateHook_TimInt(tmid, arl, name) \ + void name(void); \ + s_timinthand_ts _STATIC_MEM_ u_timinthand_##tmid = {0, 0, arl, 0, name}; \ + void name(void) MCUCFG_C51USING + +/** 创建定时查询钩子 */ +#define sCSV_CreateHook_TimQry(tmid, event, arl, name) \ + s_bool_t u_timqryevent_##tmid(void) MCUCFG_C51USING {return (event ? true : false);} \ + void name(void); \ + s_timqryhand_ts _STATIC_MEM_ u_timqryhand_##tmid = {(s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), (s_timqry_t)(SYSCFG_USERTIMQRYINIT - 1), arl, 0, name, u_timqryevent_##tmid}; \ + void name(void) MCUCFG_C51USING + + + +/* + * 互斥信号量 + */ + +/** 声明互斥信号量 */ +#define sCSV_ExternMut(name) \ + extern s_mutex_ts name + +/** 创建互斥信号量 */ +#define sCSV_CreateMut(name) \ + s_mutex_ts name = {false, OS_NULL, 0} + + + +/* + * 二值信号量 + */ + +/** 声明二值信号量 */ +#define sCSV_ExternBin(name) \ + extern s_binary_ts name + +/** 创建二值信号量 */ +#define sCSV_CreateBin(name, init) \ + s_binary_ts name = {init, OS_NULL} + + + +/* + * 计数信号量 + */ + +/** 声明计数信号量 */ +#define sCSV_ExternSem(name) \ + extern s_semaph_ts name + +/** 创建计数信号量 */ +#define sCSV_CreateSem(name, init, max) \ + s_semaph_ts name = {init, max, OS_NULL} + + + +/* + * 飞信 + */ + +/** 声明信箱 */ +#define sCSV_ExternTionbox(name) \ + extern s_tionbox_ts name + +/** 创建信箱 */ +#define sCSV_CreateTionbox(name) \ + s_tionbox_ts name = {false, OS_NULL} + + + +/* + * 邮箱 + */ + +/** 声明邮箱 */ +#define sCSV_ExternMailbox(name) \ + extern s_mailbox_ts name + +/** 创建邮箱 */ +#define sCSV_CreateMailbox(name) \ + s_mailbox_ts name = {false, OS_NULL, OS_NULL} + + + +/* + * 消息队列 + */ + +/** 声明静态队列 */ +#define sCSV_ExternQueue_Static(name) \ + extern ss_queue_ts name + +/** 声明动态队列 */ +#define sCSV_ExternQueue_Dynamic(name) \ + extern sd_queue_ts name + +/** 创建静态队列 */ +#define sCSV_CreateQueue_Static(name, mode, len) \ + void *u_queue_##name[len]; \ + ss_queue_ts name = {0, __STATIC__, mode, len, OS_NULL, true, u_queue_##name, u_queue_##name + len - 1, u_queue_##name} + +/** 创建动态队列 */ +#define sCSV_CreateQueue_Dynamic(name, mode, len) \ + sd_queue_ts name = {0, __DYNAMIC__, mode, len, OS_NULL, true, OS_NULL, OS_NULL} + + + +/* + * 事件标志组(必须声明) + */ + +/** 声明标志组 */ +#define sCSV_ExternFlagGroup(name, bits) \ + typedef struct{bits}u_##name##_ts; \ + extern volatile u_##name##_ts name + +/** 创建标志组 */ +#define sCSV_CreateFlagGroup(name) \ + volatile u_##name##_ts name + + + +/* + * 线程内存 + */ + +/** 创建线程内存池 */ +#define sCSV_CreateMempool \ + static s_thrmem_ts u_thrmem = {OS_NULL, OS_NULL, 0} + +/** @} */ +/** @} */ + +#endif diff --git a/System/sv_int_loc.c b/System/sv_int_loc.c new file mode 100644 index 00000000..fb921cfd --- /dev/null +++ b/System/sv_int_loc.c @@ -0,0 +1,149 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_loc.c + * @brief 中断本地服务 + * @details 仅在用户中断中调用,并在本地执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_var.h" +#include "os_api.h" + +#if SYSCFG_MCUCORE == 8051 +#pragma NOAREGS /* 相对寄存器访问 for C51 */ +#endif + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 中断本地服务 + \brief 仅在用户中断中调用,并在本地执行。 + @{ + */ + +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 获取二值信号量 + \param[in] hbin 二值信号量句柄 + \return 结果 [true:成功,false:失败] + */ +s_bool_t si_take_binary(s_binary_tsp hbin) +{ + if(hbin->binary){ + hbin->binary = false; + return true; + } + return false; +} +#endif + +#if SYSCFG_FETION == __ENABLED__ +/** + \brief 接收飞信 + \param[in] htbox 信箱句柄 + \return 飞信数据 [false:失败] + */ +m_fetion_t si_recv_fetion(s_tionbox_tsp htbox) +{ + m_fetion_t fetion = htbox->fetion; + htbox->fetion = false; + return fetion; +} +#endif + +#if SYSCFG_MAILBOX == __ENABLED__ +/** + \brief 接收邮件 + \param[in] hmbox 邮箱句柄 + \return 邮件指针 [NULL:失败] + */ +void *si_recv_mail(s_mailbox_tsp hmbox) +{ + if(hmbox->flag){ + hmbox->flag = false; + return hmbox->mail; + } + return OS_NULL; +} +#endif + +#if SYSCFG_MSGQUEUE == __ENABLED__ +#if SYSCFG_MCUCORE == 8051 +/** + \brief 获取队列互斥量 + \details 获取队列访问权限 for C51 接收消息。 + \param[in] hque 队列句柄 + \return 结果 [true:成功,false:失败] + */ +s_bool_t si_take_quemut(s_queue_tsp hque) +{ + if(!hque->mutex) return false; + hque->mutex = false; + + if(hque->type == __DYNAMIC__){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.error_recvmsg_int = true; + #endif + } + else if(!hque->counter); + else return true; + + hque->mutex = true; + return false; +} + +/** + \brief 归还并返回 + \details 归还队列互斥量并返回消息指针 for C51 接收消息。 + \param[out] mut 队列互斥量指针 + \param[in] msg 消息指针 + \return 消息指针 [NULL:失败] + */ +static void *_back_ret_(s_bool_t _STATIC_MEM_ *mut, void *msg) +{ + *mut = true; + return msg; +} + +/** + \brief C51 接收消息 + \param[in] hque 队列句柄 + \return 消息指针 [NULL:失败] + */ +void *si_recv_msg_c51(s_queue_tsp hque) +{ + void *msg; + sRecvMsg_Static(msg); + return _back_ret_((s_bool_t *)&hque->mutex, msg); +} +#else +/** + \brief 非51 接收消息 + \param[in] hque 队列句柄 + \return 消息指针 [NULL:失败] + */ +void *si_recv_msg_n51(s_queue_tsp hque) +{ + void *msg = OS_NULL; + if(!hque->mutex) return OS_NULL; + hque->mutex = false; + + if(hque->type == __DYNAMIC__){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.error_recvmsg_int = true; + #endif + } + else if(!hque->counter); + else sRecvMsg_Static(msg); + + hque->mutex = true; + return msg; +} +#endif +#endif + +/** @} */ +/** @} */ diff --git a/System/sv_int_loc.h b/System/sv_int_loc.h new file mode 100644 index 00000000..f1ee877b --- /dev/null +++ b/System/sv_int_loc.h @@ -0,0 +1,48 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_loc.h + * @brief 中断本地服务 + * @details 仅在用户中断中调用,并在本地执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_INT_LOC_H +#define __SV_INT_LOC_H + +s_bool_t si_take_binary (s_binary_tsp hbin); +m_fetion_t si_recv_fetion (s_tionbox_tsp htbox); +void *si_recv_mail (s_mailbox_tsp hmbox); +s_bool_t si_take_quemut (s_queue_tsp hque); +void *si_recv_msg_c51 (s_queue_tsp hque); +void *si_recv_msg_n51 (s_queue_tsp hque); + +/** + @addtogroup 中断本地服务 + @{ + */ + +#define sISV_TakeBin(bin) si_take_binary(&bin) /*!< 获取二值信号量 */ +#define sISV_RecvFetion(tbox) si_recv_fetion(&tbox) /*!< 接收飞信 */ +#define sISV_RecvMail(mbox) si_recv_mail(&mbox) /*!< 接收邮件 */ +#define sISV_GetTime(t) s_memcpy(t, iWhichGVar_Read ? &s_rtc : &s_rtc_copy, sizeof(s_rtc_ts)) /*!< 获取时间 */ + +#if SYSCFG_MCUCORE == 8051 +#define sISV_RecvMsg(que) (si_take_quemut((s_queue_tsp)&que) ? si_recv_msg_c51((s_queue_tsp)&que) : OS_NULL) /*!< C51 接收消息 */ +#else +#define sISV_RecvMsg(que) si_recv_msg_n51((s_queue_tsp)&que) /*!< 非51 接收消息 */ +#endif + +/** 查询标志组 */ +#define sISV_QueryFlagGroup(group) \ +( \ + sizeof(group) == 1 ? *(s_u8_t *)&group ? true : false \ + : sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \ + : sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \ + : false \ +) + +/** @} */ + +#endif diff --git a/System/sv_int_pend_fifo.c b/System/sv_int_pend_fifo.c new file mode 100644 index 00000000..98472809 --- /dev/null +++ b/System/sv_int_pend_fifo.c @@ -0,0 +1,466 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_pend_fifo.c + * @brief 中断挂起服务_FIFO - 执行函数 + * @details 仅在 PendSV 中由系统调用并执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_link.h" +#if MCUCFG_PENDSVFIFO_DEPTH > 0 + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 中断挂起服务_FIFO + \brief 在中断中调用的服务,不在本地执行,而是把服务的内容写入局部的结构体中, + 再把结构体指针入 PendSV_FIFO,再触发 PendSV,而后在 PendSV 中执行。 + @{ + */ + +/** + \page 手动裁剪说明: + + \li 本页中的各个执行函数,任何编译器都无法自动移除未使用,原因是
+ 它们是通过函数指针间接调用的。 + + \li 如果您希望做到极致的裁剪,可逐一查看这些函数,确定不使用的,
+ 可通过 手动开关 进行手动移除。 + */ + +/** + \brief 清除就绪延时 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iClearDelay。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _clear_delay_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + if(sv == OS_NULL) return; /* 该句无实际用途,只为屏蔽可能的编译器警告 */ + if(s_sign_schedule_forbid){ + s_task_current->timer = 0; + } +} +#else +#define _clear_delay_ OS_NULL +#endif + +/** + \brief 切换任务 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSwitchTask(task)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _switch_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_STOPPED){ + s_switch_taskpri(htask); + } +} +#else +#define _switch_task_ OS_NULL +#endif + +/** + \brief 恢复任务 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iResumeTask(task)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _resume_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status & OS_STATUS_SUSPENDED){ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + s_switch_ready(htask); + } +} +#else +#define _resume_task_ OS_NULL +#endif + +/** + \brief 挂起任务 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSuspendTask(task)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _suspend_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_SUSPENDED){ + htask->status |= OS_STATUS_SUSPENDED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + } +} +#else +#define _suspend_task_ OS_NULL +#endif + +/** + \brief 删除任务 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iDeleteTask(task)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _delete_task_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_DELETED){ + htask->status = OS_STATUS_DELETED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + } +} +#else +#define _delete_task_ OS_NULL +#endif + +/** + \brief 设置任务优先级 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSetTaskPri(task, pri)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _set_taskpri_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_taskpri_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_STOPPED){ + s_u8_t pri = ((sp_taskpri_tsp)sv)->pri; + if(htask->pri != pri){ + htask->pri = pri; + s_set_taskpri(htask); + s_sign_schedule = true; + } + } +} +#else +#define _set_taskpri_ OS_NULL +#endif + +/** + \brief 设置阻塞(时间) + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSetBlock_tc(task, tc)、iSetBlock_ms(task, ms)、 + iSetBlock_s(task, s)、iSetBlock_m(task, m)、iSetBlock_h(task, h)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _set_block_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_blocktime_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + if(!((sp_blocktime_tsp)sv)->tick){ + htask->status = OS_STATUS_READY; + s_switch_taskpri(htask); + } + htask->timer = ((sp_blocktime_tsp)sv)->tick; + } +} +#else +#define _set_block_ OS_NULL +#endif + +/** + \brief 清除阻塞(状态) + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iClearBlock(task)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _clear_block_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tasknode_tsp htask = ((sp_task_tsp)sv)->htask; + if(htask == OS_NULL) return; + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + htask->status = OS_STATUS_READY; + htask->timer = 0; + s_switch_taskpri(htask); + } +} +#else +#define _clear_block_ OS_NULL +#endif + +/** + \brief 定时中断 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iTimInt_tc(tmid, tc)、iTimInt_ms(tmid, ms)、iTimInt_s(tmid, s)、 + iTimInt_m(tmid, m)、iTimInt_h(tmid, h)、iTimInt_Cancel(tmid)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && OS_TIMINTTOTAL +static void _timint_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_timint_handle[((sp_timint_tsp)sv)->tmid]->timer + = s_timint_handle[((sp_timint_tsp)sv)->tmid]->reload + = ((sp_timint_tsp)sv)->tick; +} +#else +#define _timint_ OS_NULL +#endif + +/** + \brief 定时查询 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iTimQry_tc(tmid, tc)、iTimQry_ms(tmid, ms)、iTimQry_s(tmid, s)、 + iTimQry_m(tmid, m)、iTimQry_h(tmid, h)、iTimQry_Cancel(tmid)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && OS_TIMQRYTOTAL +static void _timqry_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_timqry_handle[((sp_timqry_tsp)sv)->tmid]->timer + = s_timqry_handle[((sp_timqry_tsp)sv)->tmid]->reload + = ((sp_timqry_tsp)sv)->tick; +} +#else +#define _timqry_ OS_NULL +#endif + +/** + \brief 上锁or给予二值信号量 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iLockBin(bin)、iGiveBin(bin)、iBackBin(bin)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_BINARY == __ENABLED__ +static void _binary_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_binary_tsp hbin = ((sp_binary_tsp)sv)->hbin; + hbin->binary = ((sp_binary_tsp)sv)->value; + if(!hbin->binary) return; + s_switch_notnull(hbin->htask); +} +#else +#define _binary_ OS_NULL +#endif + +/** + \brief 给予计数信号量 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iGiveSem(sem)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_SEMAPHORE == __ENABLED__ +static void _give_sem_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_semaph_tsp hsem = ((sp_semaph_tsp)sv)->hsem; + if(hsem->counter < hsem->maximum){ + hsem->counter++; + } + s_switch_notnull(hsem->htask); +} +#else +#define _give_sem_ OS_NULL +#endif + +/** + \brief 发送飞信 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSendFetion(tbox, tion)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_FETION == __ENABLED__ +static void _send_fetion_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_tionbox_tsp htbox = ((sp_tionbox_tsp)sv)->htbox; + htbox->fetion = ((sp_tionbox_tsp)sv)->fetion; + s_switch_notnull(htbox->htask); +} +#else +#define _send_fetion_ OS_NULL +#endif + +/** + \brief 发送邮件 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSendMail(mbox, mail)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_MAILBOX == __ENABLED__ +static void _send_mail_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_mailbox_tsp hmbox = ((sp_mailbox_tsp)sv)->hmbox; + hmbox->flag = false; + hmbox->mail = ((sp_mailbox_tsp)sv)->mail; + hmbox->flag = true; + s_switch_notnull(hmbox->htask); +} +#else +#define _send_mail_ OS_NULL +#endif + +/** + \brief 发送消息 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSendMsg(que, msg)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_MSGQUEUE == __ENABLED__ +static void _send_msg_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + s_queue_tsp hque = ((sp_msg_tsp)sv)->hque; + hque->mutex = false; + + if(hque->counter == hque->len){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_alarm.overflow_msgqueue = true; + #endif + hque->mutex = true; + return; + } + if(hque->type == __DYNAMIC__){ + s_msgnode_tsp hmsg = OS_NULL; + hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts)); + if(hmsg == OS_NULL){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.mallocfailed_msgnode = true; + #endif + hque->mutex = true; + return; + } + sSendMsg_Dynamic(((sp_msg_tsp)sv)->msg); + } + else + sSendMsg_Static(((sp_msg_tsp)sv)->msg); + + s_switch_notnull(hque->htask); + hque->mutex = true; +} +#else +#define _send_msg_ OS_NULL +#endif + +/** + \brief 写标志组 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iClearFlagGroup(group)、 + iSetFlagBit(group, bit)、iSetFlagBits(group, nbit) ...)、 + iClearFlagBit(group, bit)、iClearFlagBits(group, nbit) ...)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ \ + && SYSCFG_FLAGGROUP == __ENABLED__ +static void _group_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + switch(((sp_group_tsp)sv)->size){ + case +1: *(s_u8_t *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break; + case +2: *(s_u16_t *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break; + case +4: *(s_u32_t *)((sp_group_tsp)sv)->hgrp |= ((sp_group_tsp)sv)->value; break; + case -1: *(s_u8_t *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break; + case -2: *(s_u16_t *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break; + case -4: *(s_u32_t *)((sp_group_tsp)sv)->hgrp &=~((sp_group_tsp)sv)->value; break; + } +} +#else +#define _group_ OS_NULL +#endif + +/** + \brief 全局变量写访问 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iWriteGVar(gv, lv)、iWriteGAry(gp, lp, size)、iWriteGStr(gs, ls)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _gvar_write_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + ((sp_gvar_tsp)sv)->size + ? s_memcpy(((sp_gvar_tsp)sv)->gp, ((sp_gvar_tsp)sv)->lp, ((sp_gvar_tsp)sv)->size) + : s_strcpy((char *)((sp_gvar_tsp)sv)->gp, (char *)((sp_gvar_tsp)sv)->lp); +} +#else +#define _gvar_write_ OS_NULL +#endif + +/** + \brief 挂起服务调用 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iPendSVC(fp)。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _pendsvc_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + (*((sp_pendsvc_tsp)sv)->fp)(); +} +#else +#define _pendsvc_ OS_NULL +#endif + +/** + \brief 发送信号 + \param[in] sv 服务的结构体指针 + \return 无 + \note 关联服务:iSendSign(sign); + iSetTime(t) [系统配置中,当 中断中获取RTC 选项为启用, + 即 SYSCFG_GETRTC_INT == 1 时,调用该服务]。 + */ +#if 1 /* 手动开关 *//* 如果用户不会调用关联服务,可手动移除该函数(1 改为 0)*/ +static void _send_sign_(void _STATIC_MEM_ *sv) MCUCFG_C51USING +{ + *((sp_sign_tsp)sv)->sign = true; +} +#else +#define _send_sign_ OS_NULL +#endif + +/** + \brief 中断挂起服务_FIFO - 执行总函数(函数指针数组) + \param[in] [SVID] 服务ID + \param[in] sv 服务的结构体指针 + \return 无 + */ +void (_CODE_MEM_ * const _CONST_MEM_ sPendSV_FIFOHandler[OS_SVID_END])(void _STATIC_MEM_ *sv) = +{ + _clear_delay_, + _switch_task_, + _resume_task_, + _suspend_task_, + _delete_task_, + _set_taskpri_, + _set_block_, + _clear_block_, + _timint_, + _timqry_, + _binary_, + _give_sem_, + _send_fetion_, + _send_mail_, + _send_msg_, + _group_, + _gvar_write_, + _pendsvc_, + _send_sign_ +}; + +/** @} */ +/** @} */ +#endif diff --git a/System/sv_int_pend_fifo.h b/System/sv_int_pend_fifo.h new file mode 100644 index 00000000..128802d7 --- /dev/null +++ b/System/sv_int_pend_fifo.h @@ -0,0 +1,192 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_pend_fifo.h + * @brief 中断挂起服务_FIFO - 调用宏 + * @details 仅在用户中断中调用,而后挂起到 PendSV 中执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_INT_PEND_FIFO_H +#define __SV_INT_PEND_FIFO_H + +/** + @addtogroup 中断挂起服务_FIFO + @{ + */ + +/** 清除就绪延时 */ +#define sPSV_ClearDelay \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_CLEARDELAY, OS_NULL}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 切换任务 */ +#define sPSV_SwitchTask(_htask) \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_SWITCHTASK, OS_NULL}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 恢复任务 */ +#define sPSV_ResumeTask(_htask) \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_RESUMETASK, OS_NULL}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 挂起任务 */ +#define sPSV_SuspendTask(_htask) \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_SUSPENDTASK, OS_NULL}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 删除任务 */ +#define sPSV_DeleteTask(_htask) \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_DELETETASK, OS_NULL}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 设置任务优先级 */ +#define sPSV_SetTaskPri(_htask, _pri) \ +do{ \ + static sp_taskpri_ts u_psv = {OS_SVID_SETTASKPRI, OS_NULL, _pri}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 设置阻塞(时间)*/ +#define sPSV_SetBlock(_htask, _tick) \ +do{ \ + static sp_blocktime_ts u_psv = {OS_SVID_SETBLOCK, OS_NULL, _tick}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 清除阻塞(状态)*/ +#define sPSV_ClearBlock(_htask) \ +do{ \ + static sp_task_ts u_psv = {OS_SVID_CLEARBLOCK, OS_NULL}; \ + u_psv.htask = _htask; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 定时中断 */ +#define sPSV_TimInt(_tmid, _tick) \ +do{ \ + static sp_timint_ts u_psv = {OS_SVID_TIMINT, _tmid, 0}; \ + u_psv.tick = _tick; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 定时查询 */ +#define sPSV_TimQry(_tmid, _tick) \ +do{ \ + static sp_timqry_ts u_psv = {OS_SVID_TIMQRY, _tmid, 0}; \ + u_psv.tick = _tick; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 上锁or给予二值信号量 */ +#define sPSV_WriteBin(_bin, _val) \ +do{ \ + static sp_binary_ts u_psv = {OS_SVID_BINARY, &_bin, _val}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 给予计数信号量 */ +#define sPSV_GiveSem(_sem) \ +do{ \ + static sp_semaph_ts u_psv = {OS_SVID_GIVESEM, &_sem}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 发送飞信 */ +#define sPSV_SendFetion(_tbox, _tion) \ +do{ \ + static sp_tionbox_ts u_psv = {OS_SVID_SENDFETION, &_tbox, 0}; \ + u_psv.fetion = _tion; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 发送邮件 */ +#define sPSV_SendMail(_mbox, _mail) \ +do{ \ + static sp_mailbox_ts u_psv = {OS_SVID_SENDMAIL, &_mbox, OS_NULL}; \ + u_psv.mail = _mail; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 发送消息 */ +#define sPSV_SendMsg(_que, _msg) \ +do{ \ + static sp_msg_ts u_psv = {OS_SVID_SENDMSG, (s_queue_tsp)&_que, OS_NULL}; \ + u_psv.msg = _msg; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 清除标志组 */ +#define sPSV_ClearFlagGroup(_group) \ +do{ \ + static sp_group_ts u_psv = {OS_SVID_GROUP, (void *)&_group, -sizeof(_group), ~0}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 写多标志位 */ +#define sPSV_WriteFlagBits(_group, _sign, _nbit) \ +do{ \ + static sp_group_ts u_psv = {OS_SVID_GROUP, (void *)&_group, _sign##sizeof(_group), 0}; \ + u_##_group##_ts lv; \ + miWriteFlagBits; \ + sizeof(lv) == 1 ? *(s_u8_t *)&lv = false : MCUCFG_TERNARYMASK \ + sizeof(lv) == 2 ? *(s_u16_t *)&lv = false : MCUCFG_TERNARYMASK \ + sizeof(lv) == 4 ? *(s_u32_t *)&lv = false : false; \ + siWriteFlagBits_##_nbit( + +/** 全局变量写访问 */ +#define sPSV_WriteGVar(_gp, _lp, _size) \ +do{ \ + static sp_gvar_ts u_psv = {OS_SVID_GVARWRITE, _gp, _lp, _size}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 挂起服务调用 */ +#define sPSV_PendSVC(_fp) \ +do{ \ + static sp_pendsvc_ts u_psv = {OS_SVID_PENDSVC, _fp}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 发送信号 */ +#define sPSV_SendSign(_sign) \ +do{ \ + static sp_sign_ts u_psv = {OS_SVID_SENDSIGN, (s_bool_t *)&_sign}; \ + mPendSV_FIFOLoad; \ +}while(false) + +/** 设置时间 */ +#if SYSCFG_GETRTC_INT == __ENABLED__ +#define sPSV_SetTime(_t) \ +do{ \ + iWriteGAry(&s_rtc, _t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ + iSendSign(s_sign_rtc); \ +}while(false) +#else +#define sPSV_SetTime(_t) \ +do{ \ + iWriteGAry(&s_rtc, _t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ +}while(false) +#endif +/** @} */ + +#endif diff --git a/System/sv_int_pend_flag.c b/System/sv_int_pend_flag.c new file mode 100644 index 00000000..1de25eae --- /dev/null +++ b/System/sv_int_pend_flag.c @@ -0,0 +1,163 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_pend_flag.c + * @brief 中断挂起服务_FLAG + * @details 仅在 pendsv_hook 中调用并执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_link.h" +#if SYSCFG_PENDSVHOOK == __ENABLED__ + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 中断挂起服务_FLAG + \brief 当需要在中断中完成特定的服务功能时,可先设置一个标志位,再触发 PendSV; + 而后在 pendsv_hook 中查询该标志位,为真就清除标志位,而后调用服务。 + @{ + */ + +/** + \brief 清除就绪延时 + \param 无 + \return 无 + */ +void sp_clear_delay(void) MCUCFG_C51USING +{ + if(s_sign_schedule_forbid){ + s_task_current->timer = 0; + } +} + +/** + \brief 切换任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sp_switch_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_STOPPED){ + s_switch_taskpri(htask); + } +} + +/** + \brief 恢复任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sp_resume_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status & OS_STATUS_SUSPENDED){ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + s_switch_ready(htask); + } +} + +/** + \brief 挂起任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sp_suspend_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_SUSPENDED){ + htask->status |= OS_STATUS_SUSPENDED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + } +} + +/** + \brief 删除任务 + \param[in] htask 任务句柄 + \return 无 + */ +void sp_delete_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_DELETED){ + htask->status = OS_STATUS_DELETED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + } +} + +/** + \brief 设置任务优先级 + \param[in] htask 任务句柄 + \param[in] pri 任务优先级 + \return 无 + */ +void sp_set_taskpri(s_tasknode_tsp htask, s_u8_t pri) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status < OS_STATUS_STOPPED){ + if(htask->pri != pri){ + htask->pri = pri; + s_set_taskpri(htask); + s_sign_schedule = true; + } + } +} + +/** + \brief 设置阻塞(时间) + \param[in] htask 任务句柄 + \param[in] tick 阻塞时间 [单位:滴答周期,0:等效于清除阻塞,~0:无限阻塞] + \return 无 + */ +void sp_set_block(s_tasknode_tsp htask, s_delay_t tick) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + if(!tick){ + htask->status = OS_STATUS_READY; + s_switch_taskpri(htask); + } + htask->timer = tick; + } +} + +/** + \brief 清除阻塞(状态) + \param[in] htask 任务句柄 + \return 无 + */ +void sp_clear_block(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL) return; + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + htask->status = OS_STATUS_READY; + htask->timer = 0; + s_switch_taskpri(htask); + } +} + +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 上锁or给予二值信号量 + \param[in] hbin 二值信号量句柄 + \param[in] val 0:上锁,1:给予 + \return 无 + */ +void sp_write_binary(s_binary_tsp hbin, s_bool_t val) MCUCFG_C51USING +{ + hbin->binary = val; + if(!val) return; + s_switch_notnull(hbin->htask); +} +#endif + +/** @} */ +/** @} */ +#endif diff --git a/System/sv_int_pend_flag.h b/System/sv_int_pend_flag.h new file mode 100644 index 00000000..17a46f28 --- /dev/null +++ b/System/sv_int_pend_flag.h @@ -0,0 +1,41 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_int_pend_flag.h + * @brief 中断挂起服务_FLAG + * @details 仅在 pendsv_hook 中调用并执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_INT_PEND_FLAG_H +#define __SV_INT_PEND_FLAG_H + +void sp_clear_delay (void); +void sp_switch_task (s_tasknode_tsp htask); +void sp_resume_task (s_tasknode_tsp htask); +void sp_suspend_task(s_tasknode_tsp htask); +void sp_delete_task (s_tasknode_tsp htask); +void sp_set_taskpri (s_tasknode_tsp htask, s_u8_t pri); +void sp_set_block (s_tasknode_tsp htask, s_delay_t tick); +void sp_clear_block (s_tasknode_tsp htask); +void sp_write_binary(s_binary_tsp hbin, s_bool_t val); + +/** + @addtogroup 中断挂起服务_FLAG + @{ + */ + +#define sPS2_ClearDelay sp_clear_delay() /*!< 清除就绪延时 */ +#define sPS2_SwitchTask(htask) sp_switch_task(htask) /*!< 切换任务 */ +#define sPS2_ResumeTask(htask) sp_resume_task(htask) /*!< 恢复任务 */ +#define sPS2_SuspendTask(htask) sp_suspend_task(htask) /*!< 挂起任务 */ +#define sPS2_DeleteTask(htask) sp_delete_task(htask) /*!< 删除任务 */ +#define sPS2_SetTaskPri(htask, pri) sp_set_taskpri(htask, pri) /*!< 设置任务优先级 */ +#define sPS2_SetBlock(htask, tick) sp_set_block(htask, tick) /*!< 设置阻塞(时间)*/ +#define sPS2_ClearBlock(htask) sp_clear_block(htask) /*!< 清除阻塞(状态)*/ +#define sPS2_WriteBin(bin, val) sp_write_binary(&bin, val) /*!< 上锁or给予二值信号量 */ + +/** @} */ + +#endif diff --git a/System/sv_task.c b/System/sv_task.c new file mode 100644 index 00000000..b70abe24 --- /dev/null +++ b/System/sv_task.c @@ -0,0 +1,1004 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_task.c + * @brief 任务服务 + * @details 仅在任务中调用并执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_var.h" +#include "os_api.h" +#include "ur_api.h" + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 任务服务 + \brief 仅在任务中调用并执行。 + @{ + */ + +/** 禁止调度(支持嵌套)*/ +void su_forbid_schedule(void) +{ + s_sign_schedule_forbid = true; + s_forbid_counter++; +} + +/** 恢复调度(支持嵌套)*/ +void su_resume_schedule(void) +{ + s_forbid_counter--; + if(!s_forbid_counter){ + s_sign_schedule_forbid = false; + if(s_sign_schedule && !s_taskcri_counter){ + mPendSV_Set; + } + } +} + +/** 进入嵌套任务临界区 */ +void su_enter_critical(void) +{ + mSysIRQ_Disable; + s_taskcri_counter++; +} + +/** 退出嵌套任务临界区 */ +void su_exit_critical(void) +{ + s_taskcri_counter--; + if(!s_taskcri_counter){ + if(s_sign_schedule && !s_sign_schedule_forbid){ + mPendSV_Set; + mSysIRQ_Enable; + #if MCUCFG_ISA == __ARM__ + OS_NOPx1; + #endif + while(s_sign_schedule); + } + else{ + mSysIRQ_Enable; + } + } +} + +/** 退出嵌套任务临界区并返回(void *) */ +void *su_return_voidptr(void *p) +{ + uExitCritical; + return p; +} + +/** 进入非嵌套任务临界区 */ +void su_enter_critical_one(void) +{ + mSysIRQ_Disable; +} + +/** 退出非嵌套任务临界区 */ +void su_exit_critical_one(void) +{ + mSysIRQ_Enable; +} + +/** 退出非嵌套任务临界区并触发任务调度 */ +void su_exit_critical_psv(void) +{ + s_sign_schedule = true; + mPendSV_Set; + mSysIRQ_Enable; + #if MCUCFG_ISA == __ARM__ + OS_NOPx1; + #endif + while(s_sign_schedule); +} + +/** 退出非嵌套任务临界区并返回(void *),邮箱、队列专用 */ +#if SYSCFG_MAILBOX == __ENABLED__ || SYSCFG_MSGQUEUE == __ENABLED__ +static void *_ret_vptr_(void *p) +{ + mSysIRQ_Enable; + return p; +} +#endif + + + +/* + * 操作任务 + */ + +/** + \brief 启动任务 + \param[in] hhand 任务HAND句柄 + \param[in] entry 任务函数入口 + \param[in] status 任务初始状态 + \return 错误码 [0:无错误] + */ +s_ecode_t su_startup_task(s_taskhand_tsp hhand, s_voidvoid_tfp entry, s_u8_t status) +{ + static s_tid_t _SYS_MEM_ tid = 0; + if(!hhand->tid){ + tid++; + hhand->tid = tid; + } + s_task_status0 = status; + if(entry != OS_NULL){ + hhand->entry = entry; + } + s_task_starter = hhand; + su_exit_critical_psv(); + return s_startup_code; +} + +/** + \brief 挂起任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t su_suspend_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_SUSPENDED){ + htask->status |= OS_STATUS_SUSPENDED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + uExitCritical; + return OS_ECODE_NOERROR; + } + if(htask->status & OS_STATUS_SUSPENDED){ + uExitCritical; + return OS_ECODE_TASKSUSPENDED; + } + if(htask->status & OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + else{ + uExitCritical; + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 恢复任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t su_resume_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status & OS_STATUS_SUSPENDED){ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + s_switch_ready(htask); + uExitCritical; + return OS_ECODE_NOERROR; + } + if(htask->status < OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKNOTSUSPENDED; + } + if(htask->status & OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + else{ + uExitCritical; + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 恢复指定任务并挂起自身任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t su_resume_suspend(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status & OS_STATUS_SUSPENDED){ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + } + if(htask->status == OS_STATUS_READY){ + s_task_current->status |= OS_STATUS_SUSPENDED; + s_switch_taskpri(htask); + s_sign_schedule = true; + uExitCritical; + return OS_ECODE_NOERROR; + } + if(htask->status < OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKNOTREADY; + } + if(htask->status & OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + else{ + uExitCritical; + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 删除任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t su_delete_task(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_DELETED){ + htask->status = OS_STATUS_DELETED; + if(htask == s_task_current){ + s_sign_schedule = true; + } + uExitCritical; + return OS_ECODE_NOERROR; + } + if(htask->status == OS_STATUS_DELETED){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + else{ + uExitCritical; + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 设置任务优先级 + \param[in] htask 任务句柄 + \param[in] pri 任务新优先级 + \return 错误码 [0:无错误] + */ +s_ecode_t su_set_taskpri(s_tasknode_tsp htask, s_u8_t pri) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_STOPPED){ + if(htask->pri != pri){ + htask->pri = pri; + s_set_taskpri(htask); + s_sign_schedule = true; + uExitCritical; + return OS_ECODE_NOERROR; + } + else{ + uExitCritical; + return OS_ECODE_TASKPRIUNCHANGED; + } + } + if(htask->status & OS_STATUS_STOPPED){ + uExitCritical; + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + else{ + uExitCritical; + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 设置阻塞(时间) + \param[in] htask 任务句柄 + \param[in] tick 阻塞时间 [单位:滴答周期,0:等效于清除阻塞,~0:无限阻塞] + \return 错误码 [0:无错误] + */ +s_ecode_t su_set_block(s_tasknode_tsp htask, s_delay_t tick) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + if(!tick){ + htask->status = OS_STATUS_READY; + s_switch_taskpri(htask); + } + htask->timer = tick; + uExitCritical; + return OS_ECODE_NOERROR; + } + else{ + uExitCritical; + return OS_ECODE_TASKNOTBLOCKED; + } +} + +/** + \brief 清除阻塞(状态) + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t su_clear_block(s_tasknode_tsp htask) +{ + if(htask == OS_NULL){ + uExitCritical; + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + htask->status = OS_STATUS_READY; + htask->timer = 0; + s_switch_taskpri(htask); + uExitCritical; + return OS_ECODE_NOERROR; + } + else{ + uExitCritical; + return OS_ECODE_TASKNOTBLOCKED; + } +} + +/** + \brief 自身任务阻塞延时 + \param[in] tick 延时时间 [单位:滴答周期,~0:无限延时] + \return 无 + */ +void su_delay_block(s_delay_t tick) +{ + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->timer = tick; + su_exit_critical_psv(); +} + +/** + \brief 自身任务就绪延时 + \param[in] tick 延时时间 [单位:滴答周期,~0:无限延时] + \return 无 + */ +void su_delay_ready(s_delay_t tick) +{ + #if MCUCFG_ISA == __ARM__ + s_task_current->timer = tick; + while(s_task_current->timer); + #else + mSysIRQ_Disable; + s_task_current->timer = tick; + do{ + mSysIRQ_Enable; + while(s_task_current->timer); + mSysIRQ_Disable; + }while(s_task_current->timer); + mSysIRQ_Enable; + #endif +} + +/** + \brief 切换任务 + \param[in] htask 任务句柄 + \return 无 + */ +void su_switch_task(s_tasknode_tsp htask) +{ + if(htask != OS_NULL && htask->status < OS_STATUS_STOPPED){ + s_switch_taskpri(htask); + } + uExitCritical; +} + +/** + \brief 禅让任务 + \param 无 + \return 无 + */ +void su_yield_tasking(void) +{ + uEnterCritical; + s_tick_counter = ~0; + s_sign_schedule = true; + uExitCritical; +} + + + +/* + * 互斥信号量 + */ +#if SYSCFG_MUTEX == __ENABLED__ +/** + \brief 获取互斥信号量 + \param[in] hmut 互斥信号量句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_take_mutex(s_mutex_tsp hmut, s_delay_t tick) +{ + if(!hmut->mutex) goto __RET_TRUE1; + if(s_task_current == hmut->htask) goto __RET_TRUE2; + if(!tick) goto __RET_FALSE; + + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MUTEX | 0x0F; + s_task_current->timer = tick; + s_task_current->handle = hmut; + if(s_task_current->pri > hmut->htask->pri){ + hmut->htask->pri = s_task_current->pri; + s_set_taskpri(hmut->htask); + } + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hmut = (s_mutex_tsp)s_task_current->handle; + #endif + if(!hmut->mutex) goto __RET_TRUE1; + +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE1: + hmut->htask = s_task_current; + hmut->oldpri = s_task_current->pri; + +__RET_TRUE2: + hmut->mutex++; + mSysIRQ_Enable; + return true; +} + +/** + \brief 归还互斥信号量 + \param[in] hmut 互斥信号量句柄 + \return 无 + */ +void su_back_mutex(s_mutex_tsp hmut) +{ + if(!hmut->mutex); + else if(s_task_current == hmut->htask){ + hmut->mutex--; + if(!hmut->mutex){ + if(s_task_current->pri > hmut->oldpri){ + s_task_current->pri = hmut->oldpri; + s_set_taskpri(s_task_current); + s_sign_schedule = true; + } + } + } + uExitCritical; +} +#endif + + + +/* + * 二值信号量 + */ +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 等待二值信号量 + \param[in] hbin 二值信号量句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_wait_binary(s_binary_tsp hbin, s_delay_t tick) +{ + if(hbin->binary) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + hbin->htask = s_task_current; + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_BINARY | sizeof(hbin->binary); + s_task_current->timer = tick; + s_task_current->handle = hbin; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hbin = (s_binary_tsp)s_task_current->handle; + #endif + hbin->htask = OS_NULL; + if(hbin->binary) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE: + mSysIRQ_Enable; + return true; +} + +/** + \brief 获取二值信号量 + \param[in] hbin 二值信号量句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_take_binary(s_binary_tsp hbin, s_delay_t tick) +{ + if(hbin->binary) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(hbin->htask == OS_NULL || s_task_current->pri > hbin->htask->pri){ + hbin->htask = s_task_current; + } + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_BINARY | sizeof(hbin->binary); + s_task_current->timer = tick; + s_task_current->handle = hbin; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hbin = (s_binary_tsp)s_task_current->handle; + #endif + hbin->htask = OS_NULL; + if(hbin->binary) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE: + hbin->binary = false; + mSysIRQ_Enable; + return true; +} + +/** + \brief 给予二值信号量 + \param[in] hbin 二值信号量句柄 + \return 无 + */ +void su_give_binary(s_binary_tsp hbin) +{ + hbin->binary = true; + s_switch_notnull(hbin->htask); + uExitCritical; +} +#endif + + + +/* + * 计数信号量 + */ +#if SYSCFG_SEMAPHORE == __ENABLED__ +/** + \brief 获取计数信号量 + \param[in] hsem 计数信号量句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_take_semaphore(s_semaph_tsp hsem, s_delay_t tick) +{ + if(hsem->counter) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + if(hsem->htask == OS_NULL || s_task_current->pri > hsem->htask->pri){ + hsem->htask = s_task_current; + } + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_SEMAPHORE | sizeof(hsem->counter); + s_task_current->timer = tick; + s_task_current->handle = hsem; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hsem = (s_semaph_tsp)s_task_current->handle; + #endif + hsem->htask = OS_NULL; + if(hsem->counter) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE: + (hsem->counter)--; + mSysIRQ_Enable; + return true; +} + +/** + \brief 给予计数信号量 + \param[in] hsem 计数信号量句柄 + \return 无 + */ +void su_give_semaphore(s_semaph_tsp hsem) +{ + if(hsem->counter < hsem->maximum){ + hsem->counter++; + } + s_switch_notnull(hsem->htask); + uExitCritical; +} +#endif + + + +/* + * 私信 + */ +#if SYSCFG_TASKMSG == __ENABLED__ +/** + \brief 接收私信 + \param[in] flag 私信标志,有新私信时,该标志为真 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_recv_taskmsg(m_taskmsg_t _STATIC_MEM_ *flag, s_delay_t tick) +{ + if(*flag) goto __RET_TRUE; + if(!tick) goto __RET_FALSE; + + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_TASKMSG | sizeof(*flag); + s_task_current->timer = tick; + s_task_current->handle = flag; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + flag = (m_taskmsg_t *)s_task_current->handle; + #endif + if(*flag) goto __RET_TRUE; + +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE: + *flag = false; + return true; +} +#endif + + + +/* + * 飞信 + */ +#if SYSCFG_FETION == __ENABLED__ +/** + \brief 接收飞信 + \param[in] htbox 信箱句柄 + \return 飞信数据 [false:失败] + */ +static m_fetion_t _recv_fetion_(s_tionbox_tsp htbox) +{ + m_fetion_t fetion = htbox->fetion; + htbox->fetion = false; + mSysIRQ_Enable; + return fetion; +} + +/** + \brief 接收飞信 + \param[in] htbox 信箱句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 飞信数据 [false:失败] + */ +m_fetion_t su_recv_fetion(s_tionbox_tsp htbox, s_delay_t tick) +{ + if(htbox->fetion) goto __RET_TION; + if(!tick) goto __RET_FALSE; + + htbox->htask = s_task_current; + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_FETION | sizeof(htbox->fetion); + s_task_current->timer = tick; + s_task_current->handle = htbox; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + htbox = (s_tionbox_tsp)s_task_current->handle; + #endif + htbox->htask = OS_NULL; + +__RET_TION: + return _recv_fetion_(htbox); + +__RET_FALSE: + mSysIRQ_Enable; + return false; +} +#endif + + + +/* + * 邮箱 + */ +#if SYSCFG_MAILBOX == __ENABLED__ +/** + \brief 接收邮件 + \param[in] hmbox 邮箱句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 邮件指针 [NULL:失败] + */ +void *su_recv_mail(s_mailbox_tsp hmbox, s_delay_t tick) +{ + if(hmbox->flag) goto __RET_MAIL; + if(!tick) goto __RET_NULL; + + hmbox->htask = s_task_current; + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MAIL | sizeof(hmbox->flag); + s_task_current->timer = tick; + s_task_current->handle = hmbox; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hmbox = (s_mailbox_tsp)s_task_current->handle; + #endif + hmbox->htask = OS_NULL; + if(hmbox->flag) goto __RET_MAIL; + +__RET_NULL: + mSysIRQ_Enable; + return OS_NULL; + +__RET_MAIL: + hmbox->flag = false; + return _ret_vptr_(hmbox->mail); +} + +/** + \brief 发送邮件 + \param[in] hmbox 邮箱句柄 + \param[in] mail 邮件指针 + \return 无 + */ +void su_send_mail(s_mailbox_tsp hmbox, void *mail) +{ + hmbox->flag = false; + hmbox->mail = mail; + hmbox->flag = true; + s_switch_notnull(hmbox->htask); + uExitCritical; +} +#endif + + + +/* + * 消息队列 + */ +#if SYSCFG_MSGQUEUE == __ENABLED__ +/** + \brief 接收消息 + \param[in] hque 队列句柄 + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 消息指针 [NULL:失败] + */ +void *su_recv_msg(s_queue_tsp hque, s_delay_t tick) +{ + void *msg; + s_msgnode_tsp hmsg; + hque->mutex = false; + + if(hque->counter) goto __RECV_MSG; + if(!tick) goto __RET_NULL; + + hque->mutex = true; + hque->htask = s_task_current; + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_MSG | sizeof(hque->counter); + s_task_current->timer = tick; + s_task_current->handle = hque; + su_exit_critical_psv(); + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hque = (s_queue_tsp)s_task_current->handle; + #endif + hque->htask = OS_NULL; + hque->mutex = false; + if(!hque->counter) goto __RET_NULL; + +__RECV_MSG: + if(hque->type == __DYNAMIC__) + sRecvMsg_Dynamic(msg); + else + sRecvMsg_Static(msg); + hque->mutex = true; + return _ret_vptr_(msg); + +__RET_NULL: + hque->mutex = true; + mSysIRQ_Enable; + return OS_NULL; +} + +/** + \brief 发送消息 + \param[in] hque 队列句柄 + \param[in] msg 消息指针 + \return 错误码 [0:无错误] + */ +s_ecode_t su_send_msg(s_queue_tsp hque, void *msg) +{ + hque->mutex = false; + + if(hque->counter == hque->len){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_alarm.overflow_msgqueue = true; + #endif + hque->mutex = true; + uExitCritical; + return OS_ECODE_OVERFLOW_MSGQUEUE; + } + if(hque->type == __DYNAMIC__){ + s_msgnode_tsp hmsg = OS_NULL; + hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts)); + if(hmsg == OS_NULL){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.mallocfailed_msgnode = true; + #endif + hque->mutex = true; + uExitCritical; + return OS_ECODE_MALLOCFAIL_MSGNODE; + } + sSendMsg_Dynamic(msg); + } + else + sSendMsg_Static(msg); + + s_switch_notnull(hque->htask); + hque->mutex = true; + uExitCritical; + return OS_ECODE_NOERROR; +} +#endif + + + +/* + * 事件标志组 + */ +#if SYSCFG_FLAGGROUP == __ENABLED__ +/** + \brief 查询标志组 + \param[in] hgrp 标志组句柄 + \param[in] size sizeof(group) + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_query_group(void _STATIC_MEM_ *hgrp, s_u8_t size) +{ + switch(size){ + case 1: if(*(s_u8_t *)hgrp) goto __RET_TRUE; break; + case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break; + case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break; + } + uExitCritical; + return false; + +__RET_TRUE: + uExitCritical; + return true; +} + +/** + \brief 等待标志组 + \param[in] hgrp 标志组句柄 + \param[in] size sizeof(group) + \param[in] tick 超时时间 [单位:滴答周期,0:立即返回,~0:无限等待] + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_wait_group(void _STATIC_MEM_ *hgrp, s_u8_t size, s_delay_t tick) +{ + switch(size){ + case 1: if(*(s_u8_t *)hgrp) goto __RET_TRUE; break; + case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break; + case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break; + } + if(!tick) goto __RET_FALSE; + + s_task_current->status = OS_STATUS_BLOCKED; + s_task_current->blocktype = OS_BLOCKED_FLAGGROUP | size; + s_task_current->timer = tick; + s_task_current->handle = hgrp; + su_exit_critical_psv(); + #if SYSCFG_MCUCORE == 8051 || SYSCFG_MCUCORE == 80251 + size = s_task_current->blocktype & 0x0F; + #endif + s_task_current->blocktype = 0; + #if SYSCFG_MCUCORE == 8051 + hgrp = s_task_current->handle; + #endif + switch(size){ + case 1: if(*(s_u8_t *)hgrp) goto __RET_TRUE; break; + case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break; + case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break; + } +__RET_FALSE: + mSysIRQ_Enable; + return false; + +__RET_TRUE: + mSysIRQ_Enable; + return true; +} +#endif + + + +/* + * 动态内存 + */ +#if SYSCFG_DYNMEMMGE == __ENABLED__ +/** + \brief uxalloc + \param[in] p + \return 指针 [NULL:失败] + */ +void _MALLOC_MEM_ *su_xalloc(void _MALLOC_MEM_ *p) +{ + uExitCritical; + return p; +} + +/** + \brief 初始化线程内存池 + \param[in] hmem 线程内存句柄 + \param[in] size 内存池大小 + \return 结果 [true:成功,false:失败] + */ +s_bool_t su_init_mempool(s_thrmem_tsp hmem, size_t size) +{ + hmem->head = hmem->move = (void _MALLOC_MEM_ *)s_malloc(size); + if(hmem->head == OS_NULL){ + uExitCritical; + return false; + } + else{ + hmem->size = size; + uExitCritical; + return true; + } +} + +/** + \brief 线程内存分配 + \param[in] hmem 线程内存句柄 + \param[in] size 内存块大小 + \return 指针 [NULL:分配失败] + */ +void _MALLOC_MEM_ *su_talloc(s_thrmem_tsp hmem, size_t size) +{ + if(hmem->head == OS_NULL || (size_t)hmem->move - (size_t)hmem->head + size > hmem->size){ + return OS_NULL; + } + else{ + void _MALLOC_MEM_ *r = hmem->move; + hmem->move = (s_u8_t _MALLOC_MEM_ *)hmem->move + size; + return r; + } +} +#endif + +/** @} */ +/** @} */ diff --git a/System/sv_task.h b/System/sv_task.h new file mode 100644 index 00000000..c4552c4f --- /dev/null +++ b/System/sv_task.h @@ -0,0 +1,423 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_task.h + * @brief 任务服务 + * @details 仅在任务中调用并执行。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_TASK_H +#define __SV_TASK_H + +void su_forbid_schedule (void); +void su_resume_schedule (void); +void su_enter_critical (void); +void su_exit_critical (void); +void *su_return_voidptr (void *p); +void su_enter_critical_one(void); +void su_exit_critical_one (void); +void su_exit_critical_psv (void); +s_ecode_t su_startup_task (s_taskhand_tsp hhand, s_voidvoid_tfp entry, s_u8_t status); +s_ecode_t su_suspend_task (s_tasknode_tsp htask); +s_ecode_t su_resume_task (s_tasknode_tsp htask); +s_ecode_t su_resume_suspend (s_tasknode_tsp htask); +s_ecode_t su_delete_task (s_tasknode_tsp htask); +s_ecode_t su_set_taskpri (s_tasknode_tsp htask, s_u8_t pri); +s_ecode_t su_set_block (s_tasknode_tsp htask, s_delay_t tick); +s_ecode_t su_clear_block (s_tasknode_tsp htask); +void su_delay_block (s_delay_t tick); +void su_delay_ready (s_delay_t tick); +void su_switch_task (s_tasknode_tsp htask); +void su_yield_tasking (void); +s_bool_t su_take_mutex (s_mutex_tsp hmut, s_delay_t tick); +void su_back_mutex (s_mutex_tsp hmut); +s_bool_t su_wait_binary (s_binary_tsp hbin, s_delay_t tick); +s_bool_t su_take_binary (s_binary_tsp hbin, s_delay_t tick); +void su_give_binary (s_binary_tsp hbin); +s_bool_t su_take_semaphore (s_semaph_tsp hsem, s_delay_t tick); +void su_give_semaphore (s_semaph_tsp hsem); +s_bool_t su_recv_taskmsg (m_taskmsg_t _STATIC_MEM_ *flag, s_delay_t tick); +m_fetion_t su_recv_fetion (s_tionbox_tsp htbox, s_delay_t tick); +void *su_recv_mail (s_mailbox_tsp hmbox, s_delay_t tick); +void su_send_mail (s_mailbox_tsp hmbox, void *mail); +void *su_recv_msg (s_queue_tsp hque, s_delay_t tick); +s_ecode_t su_send_msg (s_queue_tsp hque, void *msg); +s_bool_t su_query_group (void _STATIC_MEM_ *hgrp, s_u8_t size); +s_bool_t su_wait_group (void _STATIC_MEM_ *hgrp, s_u8_t size, s_delay_t tick); +s_bool_t su_init_mempool (s_thrmem_tsp hmem, size_t size); +void _MALLOC_MEM_ *su_talloc (s_thrmem_tsp hmem, size_t size); +void _MALLOC_MEM_ *su_xalloc (void _MALLOC_MEM_ *p); + +/** + @addtogroup 任务服务 + @{ + */ + +/* + * 操作任务 + */ + +/** 启动任务 */ +#define sUSV_StartTask(hhand, entry, status) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_startup_task((s_taskhand_tsp)hhand, entry, !status ? OS_STATUS_READY : OS_STATUS_SUSPENDED) : OS_ECODE_NOERROR \ +) + +/** 挂起任务 */ +#define sUSV_SuspendTask(htask) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_suspend_task(htask) : OS_ECODE_NOERROR \ +) + +/** 恢复任务 */ +#define sUSV_ResumeTask(htask) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_resume_task(htask) : OS_ECODE_NOERROR \ +) + +/** 恢复指定任务并挂起自身任务 */ +#define sUSV_ResumeSuspend(htask) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_resume_suspend(htask) : OS_ECODE_NOERROR \ +) + +/** 删除任务 */ +#define sUSV_DeleteTask(htask) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_delete_task(htask) : OS_ECODE_NOERROR \ +) + +/** 设置任务优先级 */ +#define sUSV_SetTaskPri(htask, pri) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_set_taskpri(htask, pri) : OS_ECODE_NOERROR \ +) + +/** 设置阻塞(时间)*/ +#define sUSV_SetBlock(htask, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_set_block(htask, tick) : OS_ECODE_NOERROR \ +) + +/** 清除阻塞(状态)*/ +#define sUSV_ClearBlock(htask) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_clear_block(htask) : OS_ECODE_NOERROR \ +) + +/** 自身任务延时 */ +#define sUSV_Delay(tick) \ +do{ \ + if(!s_sign_schedule_forbid){ \ + mSysIRQ_Disable; \ + su_delay_block(tick); \ + } \ + else su_delay_ready(tick); \ +}while(false) + +/** 切换任务 */ +#define sUSV_SwitchTask(htask) \ +do{ \ + uEnterCritical; \ + su_switch_task(htask); \ +}while(false) + + + +/* + * 定时 + */ + +/** 定时中断 */ +#define sUSV_TimInt(tmid, tick) \ +do{ \ + uEnterCritical; \ + s_timint_handle[tmid]->timer = s_timint_handle[tmid]->reload = tick; \ + uExitCritical; \ +}while(false) + +/** 定时查询 */ +#define sUSV_TimQry(tmid, tick) \ +do{ \ + uEnterCritical; \ + s_timqry_handle[tmid]->timer = s_timqry_handle[tmid]->reload = tick; \ + uExitCritical; \ +}while(false) + + + +/* + * 互斥信号量 + */ + +/** 获取互斥信号量 */ +#define sUSV_TakeMut(mut, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_mutex(&mut, tick) : false \ +) + +/** 归还互斥信号量 */ +#define sUSV_BackMut(mut) \ +do{ \ + uEnterCritical; \ + su_back_mutex(&mut); \ +}while(false) + + + +/* + * 二值信号量 + */ + +/** 等待二值信号量 */ +#define sUSV_WaitBin(bin, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_wait_binary(&bin, tick) : false \ +) + +/** 获取二值信号量 */ +#define sUSV_TakeBin(bin, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_binary(&bin, tick) : false \ +) + +/** 给予二值信号量 */ +#define sUSV_GiveBin(bin) \ +do{ \ + uEnterCritical; \ + su_give_binary(&bin); \ +}while(false) + + + +/* + * 计数信号量 + */ + +/** 获取计数信号量 */ +#define sUSV_TakeSem(sem, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_semaphore(&sem, tick) : false \ +) + +/** 给予计数信号量 */ +#define sUSV_GiveSem(sem) \ +do{ \ + uEnterCritical; \ + su_give_semaphore(&sem); \ +}while(false) + + + +/* + * 私信 + */ + +/** 接收私信 */ +#define sUSV_RecvTaskMsg(tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true \ + ? su_recv_taskmsg(&m0_, tick) \ + ? s_memcpy(&m0 + 1, &m0_ + 1, MCUCFG_TASKMSG_SIZE) || true \ + ? (m_boolvoid_tf(su_exit_critical_one))() || true \ + : (m_boolvoid_tf(su_exit_critical_one))() || true \ + : false \ + : false \ +) + +/** 发送私信 */ +#define sUSV_SendTaskMsg(task) \ + uEnterCritical; \ + s_sign_send_taskmsg = true; \ + MCUCFG_TASKMSG_PSP; \ + s_switch_taskmsg(u_taskhandle_##task); \ + task(MCUCFG_TASKMSG_VAL, + + + +/* + * 飞信 + */ + +/** 接收飞信 */ +#define sUSV_RecvFetion(tbox, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_fetion(&tbox, tick) : false \ +) + +/** 发送飞信 */ +#define sUSV_SendFetion(tbox, tion) \ +do{ \ + uEnterCritical; \ + tbox.fetion = tion; \ + s_switch_notnull(tbox.htask); \ + uExitCritical; \ +}while(false) + + + +/* + * 邮箱 + */ + +/** 接收邮件 */ +#define sUSV_RecvMail(mbox, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_mail(&mbox, tick) : OS_NULL \ +) + +/** 发送邮件 */ +#define sUSV_SendMail(mbox, mail) \ +do{ \ + uEnterCritical; \ + su_send_mail(&mbox, mail); \ +}while(false) + + + +/* + * 消息队列 + */ + +/** 接收消息 */ +#define sUSV_RecvMsg(que, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_msg((s_queue_tsp)&que, tick) : OS_NULL \ +) + +/** 发送消息 */ +#define sUSV_SendMsg(que, msg) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_send_msg((s_queue_tsp)&que, msg) : OS_ECODE_NOERROR \ +) + + + +/* + * 事件标志组 + */ + +/** 查询标志组 */ +#define sUSV_QueryFlagGroup(group) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_query_group((void *)&group, sizeof(group)) : false \ +) + +/** 等待标志组 */ +#define sUSV_WaitFlagGroup(group, tick) \ +( \ + (m_boolvoid_tf(su_enter_critical_one))() || true ? su_wait_group((void *)&group, sizeof(group), tick) : false \ +) + +/** 清除标志组 */ +#define sUSV_ClearFlagGroup(group) \ +do{ \ + uEnterCritical; \ + sizeof(group) == 1 ? *(s_u8_t *)&group = false : MCUCFG_TERNARYMASK \ + sizeof(group) == 2 ? *(s_u16_t *)&group = false : MCUCFG_TERNARYMASK \ + sizeof(group) == 4 ? *(s_u32_t *)&group = false : false; \ + uExitCritical; \ +}while(false) + +/** 写标志位 */ +#define sUSV_WriteFlagBit(group, bit, value) \ +do{ \ + uEnterCritical; \ + group.bit = value; \ + uExitCritical; \ +}while(false) + + + +/* + * 软件RTC + */ + +/** 获取时间 */ +#define sUSV_GetTime(t) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_return_voidptr(s_memcpy(t, &s_rtc, sizeof(s_rtc_ts))) : OS_NULL \ +) + +/** 设置时间 */ +#if SYSCFG_GETRTC_INT == __ENABLED__ +#define sUSV_SetTime(t) \ +do{ \ + uEnterCritical; \ + s_memcpy(&s_rtc, t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ + s_update_rtccopy(); \ + uExitCritical; \ +}while(false) +#else +#define sUSV_SetTime(t) \ +do{ \ + uEnterCritical; \ + s_memcpy(&s_rtc, t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ + uExitCritical; \ +}while(false) +#endif + + + +/* + * 进程内存 + */ + +/** malloc */ +#define sUSV_Malloc(size) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_malloc(size)) : OS_NULL \ +) + +/** calloc */ +#define sUSV_Calloc(nmemb, size) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_calloc(nmemb, size)) : OS_NULL \ +) + +/** realloc */ +#define sUSV_Realloc(p, size) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_realloc(p, size)) : OS_NULL \ +) + +/** free */ +#define sUSV_Free(p) \ +do{ \ + uEnterCritical; \ + s_free(p); \ + uExitCritical; \ +}while(false) + + + +/* + * 线程内存 + */ + +/** 初始化线程内存池 */ +#define sUSV_InitMempool(size) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_init_mempool(&u_thrmem, size) : false \ +) + +/** 线程内存分配 */ +#define sUSV_Talloc(size) \ +( \ + (m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc(su_talloc(&u_thrmem, size)) : OS_NULL \ +) + +/** 释放线程内存池 */ +#define sUSV_FreeMempool \ +do{ \ + sUSV_Free(u_thrmem.head); \ + u_thrmem.head = u_thrmem.move = OS_NULL; \ +}while(false) + +/** @} */ + +#endif diff --git a/System/sv_tick.c b/System/sv_tick.c new file mode 100644 index 00000000..7d4a80e5 --- /dev/null +++ b/System/sv_tick.c @@ -0,0 +1,335 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_tick.c + * @brief 滴答服务 + * @details 仅在 SysTick 中调用并执行,包括在滴答钩子、定时中断钩子、 + 定时查询钩子、定时查询事件等处调用。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#include "os_var.h" +#include "os_api.h" + +/** + @addtogroup CosyOS_内核服务 + @{ + *//** + \defgroup 滴答服务 + \brief 仅在 SysTick 中调用并执行,包括在滴答钩子、定时中断钩子、 + 定时查询钩子、定时查询事件等处调用。 + @{ + */ + +/** + \brief 清除就绪延时 + \param 无 + \return 结果 [true:成功,false:失败] + */ +s_bool_t st_clear_delay(void) MCUCFG_C51USING +{ + if(s_sign_schedule_forbid){ + s_task_current->timer = 0; + return true; + } + return false; +} + +/** + \brief 挂起任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t st_suspend_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_SUSPENDED){ + htask->status |= OS_STATUS_SUSPENDED; + return OS_ECODE_NOERROR; + } + if(htask->status & OS_STATUS_SUSPENDED){ + return OS_ECODE_TASKSUSPENDED; + } + if(htask->status & OS_STATUS_STOPPED){ + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + return OS_ECODE_TASKNOTSTARTED; + } + else{ + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 恢复任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t st_resume_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status & OS_STATUS_SUSPENDED){ + htask->status &= (~OS_STATUS_SUSPENDED & 0xFF); + return OS_ECODE_NOERROR; + } + if(htask->status < OS_STATUS_STOPPED){ + return OS_ECODE_TASKNOTSUSPENDED; + } + if(htask->status & OS_STATUS_STOPPED){ + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + return OS_ECODE_TASKNOTSTARTED; + } + else{ + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 删除任务 + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t st_delete_task(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_DELETED){ + htask->status = OS_STATUS_DELETED; + return OS_ECODE_NOERROR; + } + if(htask->status == OS_STATUS_DELETED){ + return OS_ECODE_TASKNOTSTARTED; + } + else{ + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 设置任务优先级 + \param[in] htask 任务句柄 + \param[in] pri 任务优先级 + \return 错误码 [0:无错误] + */ +s_ecode_t st_set_taskpri(s_tasknode_tsp htask, s_u8_t pri) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status < OS_STATUS_STOPPED){ + if(htask->pri != pri){ + htask->pri = pri; + s_set_taskpri(htask); + return OS_ECODE_NOERROR; + } + else{ + return OS_ECODE_TASKPRIUNCHANGED; + } + } + if(htask->status & OS_STATUS_STOPPED){ + return OS_ECODE_TASKSTOPPED; + } + if(htask->status == OS_STATUS_DELETED){ + return OS_ECODE_TASKNOTSTARTED; + } + else{ + return OS_ECODE_DONOTKNOW; + } +} + +/** + \brief 设置阻塞(时间) + \param[in] htask 任务句柄 + \param[in] tick 阻塞时间 [单位:滴答周期,0:等效于清除阻塞,~0:无限阻塞] + \return 错误码 [0:无错误] + */ +s_ecode_t st_set_block(s_tasknode_tsp htask, s_delay_t tick) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + if(!tick){ + htask->status = OS_STATUS_READY; + } + htask->timer = tick; + return OS_ECODE_NOERROR; + } + return OS_ECODE_TASKNOTBLOCKED; +} + +/** + \brief 清除阻塞(状态) + \param[in] htask 任务句柄 + \return 错误码 [0:无错误] + */ +s_ecode_t st_clear_block(s_tasknode_tsp htask) MCUCFG_C51USING +{ + if(htask == OS_NULL){ + return OS_ECODE_TASKNOTSTARTED; + } + if(htask->status == OS_STATUS_BLOCKED || htask->status == OS_STATUS_FLOATING){ + htask->status = OS_STATUS_READY; + htask->timer = 0; + return OS_ECODE_NOERROR; + } + return OS_ECODE_TASKNOTBLOCKED; +} + +#if SYSCFG_BINARY == __ENABLED__ +/** + \brief 获取二值信号量 + \param[in] hbin 二值信号量句柄 + \return 结果 [true:成功,false:失败] + */ +s_bool_t st_take_binary(s_binary_tsp hbin) MCUCFG_C51USING +{ + if(hbin->binary){ + hbin->binary = false; + return true; + } + return false; +} +#endif + +#if SYSCFG_SEMAPHORE == __ENABLED__ +/** + \brief 获取计数信号量 + \param[in] hsem 计数信号量句柄 + \return 结果 [true:成功,false:失败] + */ +s_bool_t st_take_semaphore(s_semaph_tsp hsem) MCUCFG_C51USING +{ + if(hsem->counter){ + (hsem->counter)--; + return true; + } + return false; +} + +/** + \brief 给予计数信号量 + \param[in] hsem 计数信号量句柄 + \return 无 + */ +void st_give_semaphore(s_semaph_tsp hsem) MCUCFG_C51USING +{ + if(hsem->counter < hsem->maximum){ + hsem->counter++; + } +} +#endif + +#if SYSCFG_FETION == __ENABLED__ +/** + \brief 接收飞信 + \param[in] htbox 信箱句柄 + \return 飞信数据 [false:失败] + */ +m_fetion_t st_recv_fetion(s_tionbox_tsp htbox) MCUCFG_C51USING +{ + m_fetion_t fetion = htbox->fetion; + htbox->fetion = false; + return fetion; +} +#endif + +#if SYSCFG_MAILBOX == __ENABLED__ +/** + \brief 接收邮件 + \param[in] hmbox 邮箱句柄 + \return 邮件指针 [NULL:失败] + */ +void *st_recv_mail(s_mailbox_tsp hmbox) MCUCFG_C51USING +{ + if(hmbox->flag){ + hmbox->flag = false; + return hmbox->mail; + } + return OS_NULL; +} + +/** + \brief 发送邮件 + \param[in] hmbox 邮箱句柄 + \param[in] mail 邮件指针 + \return 无 + */ +void st_send_mail(s_mailbox_tsp hmbox, void *mail) MCUCFG_C51USING +{ + hmbox->flag = false; + hmbox->mail = mail; + hmbox->flag = true; +} +#endif + +#if SYSCFG_MSGQUEUE == __ENABLED__ +/** + \brief 接收消息 + \param[in] hque 队列句柄 + \return 消息指针 [NULL:失败] + */ +void *st_recv_msg(s_queue_tsp hque) MCUCFG_C51USING +{ + void *msg = OS_NULL; + s_msgnode_tsp hmsg; + hque->mutex = false; + + if(!hque->counter); + else if(hque->type == __DYNAMIC__) + sRecvMsg_Dynamic(msg); + else + sRecvMsg_Static(msg); + + hque->mutex = true; + return msg; +} + +/** + \brief 发送消息 + \param[in] hque 队列句柄 + \param[in] msg 消息指针 + \return 错误码 [0:无错误] + */ +s_ecode_t st_send_msg(s_queue_tsp hque, void *msg) MCUCFG_C51USING +{ + hque->mutex = false; + + if(hque->counter == hque->len){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_alarm.overflow_msgqueue = true; + #endif + hque->mutex = true; + return OS_ECODE_OVERFLOW_MSGQUEUE; + } + if(hque->type == __DYNAMIC__){ + s_msgnode_tsp hmsg = OS_NULL; + hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts)); + if(hmsg == OS_NULL){ + #if SYSCFG_DEBUGGING == __ENABLED__ + s_fault.mallocfailed_msgnode = true; + #endif + hque->mutex = true; + return OS_ECODE_MALLOCFAIL_MSGNODE; + } + sSendMsg_Dynamic(msg); + } + else + sSendMsg_Static(msg); + + hque->mutex = true; + return OS_ECODE_NOERROR; +} +#endif + +/** @} */ +/** @} */ diff --git a/System/sv_tick.h b/System/sv_tick.h new file mode 100644 index 00000000..05c966dd --- /dev/null +++ b/System/sv_tick.h @@ -0,0 +1,96 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file sv_tick.h + * @brief 滴答服务 + * @details 仅在 SysTick 中调用并执行,包括在滴答钩子、定时中断钩子、 + 定时查询钩子、定时查询事件等处调用。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __SV_TICK_H +#define __SV_TICK_H + +s_bool_t st_clear_delay (void); +s_ecode_t st_suspend_task (s_tasknode_tsp htask); +s_ecode_t st_resume_task (s_tasknode_tsp htask); +s_ecode_t st_delete_task (s_tasknode_tsp htask); +s_ecode_t st_set_taskpri (s_tasknode_tsp htask, s_u8_t pri); +s_ecode_t st_set_block (s_tasknode_tsp htask, s_delay_t tick); +s_ecode_t st_clear_block (s_tasknode_tsp htask); +s_bool_t st_take_binary (s_binary_tsp hbin); +s_bool_t st_take_semaphore (s_semaph_tsp hsem); +void st_give_semaphore (s_semaph_tsp hsem); +m_fetion_t st_recv_fetion (s_tionbox_tsp htbox); +void *st_recv_mail (s_mailbox_tsp hmbox); +void st_send_mail (s_mailbox_tsp hmbox, void *mail); +void *st_recv_msg (s_queue_tsp hque); +s_ecode_t st_send_msg (s_queue_tsp hque, void *msg); + +/** + @addtogroup 滴答服务 + @{ + */ + +#define sTSV_ClearDelay st_clear_delay() /*!< 清除就绪延时 */ +#define sTSV_SuspendTask(htask) st_suspend_task(htask) /*!< 挂起任务 */ +#define sTSV_ResumeTask(htask) st_resume_task(htask) /*!< 恢复任务 */ +#define sTSV_DeleteTask(htask) st_delete_task(htask) /*!< 删除任务 */ +#define sTSV_SetTaskPri(htask, pri) st_set_taskpri(htask, pri) /*!< 设置任务优先级 */ +#define sTSV_SetBlock(htask, tick) st_set_block(htask, tick) /*!< 设置阻塞(时间)*/ +#define sTSV_ClearBlock(htask) st_clear_block(htask) /*!< 清除阻塞(状态)*/ +#define sTSV_TakeBin(bin) st_take_binary(&bin) /*!< 获取二值信号量 */ +#define sTSV_TakeSem(sem) st_take_semaphore(&sem) /*!< 获取计数信号量 */ +#define sTSV_GiveSem(sem) st_give_semaphore(&sem) /*!< 给予计数信号量 */ +#define sTSV_RecvFetion(tbox) st_recv_fetion(&tbox) /*!< 接收飞信 */ +#define sTSV_RecvMail(mbox) st_recv_mail(&mbox) /*!< 接收邮件 */ +#define sTSV_SendMail(mbox, mail) st_send_mail(&mbox, mail) /*!< 发送邮件 */ +#define sTSV_RecvMsg(que) st_recv_msg((s_queue_tsp)&que) /*!< 接收消息 */ +#define sTSV_SendMsg(que, msg) st_send_msg((s_queue_tsp)&que, msg) /*!< 发送消息 */ +#define sTSV_TimInt(tmid, tick) s_timint_handle[tmid]->timer = s_timint_handle[tmid]->reload = tick /*!< 定时中断 */ +#define sTSV_TimQry(tmid, tick) s_timqry_handle[tmid]->timer = s_timqry_handle[tmid]->reload = tick /*!< 定时查询 */ +#define sTSV_GetTime(t) s_memcpy(t, &s_rtc, sizeof(s_rtc_ts)) /*!< 获取时间 */ + +/** 设置时间 */ +#if SYSCFG_GETRTC_INT == __ENABLED__ +#define sTSV_SetTime(t) \ +do{ \ + s_memcpy(&s_rtc, t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ + s_update_rtccopy(); \ +}while(false) +#else +#define sTSV_SetTime(t) \ +do{ \ + s_memcpy(&s_rtc, t, sizeof(s_rtc_ts)); \ + s_sign_every.set = true; \ +}while(false) +#endif + +/** 发送私信 */ +#define sTSV_SendTaskMsg(task) \ + s_sign_send_taskmsg = true; \ + MCUCFG_TASKMSG_PSP; \ + task(MCUCFG_TASKMSG_VAL, + +/** 查询标志组 */ +#define sTSV_QueryFlagGroup(group) \ +( \ + sizeof(group) == 1 ? *(s_u8_t *)&group ? true : false \ + : sizeof(group) == 2 ? *(s_u16_t *)&group ? true : false \ + : sizeof(group) == 4 ? *(s_u32_t *)&group ? true : false \ + : false \ +) + +/** 清除标志组 */ +#define sTSV_ClearFlagGroup(group) \ +do{ \ + sizeof(group) == 1 ? *(s_u8_t *)&group = false : MCUCFG_TERNARYMASK \ + sizeof(group) == 2 ? *(s_u16_t *)&group = false : MCUCFG_TERNARYMASK \ + sizeof(group) == 4 ? *(s_u32_t *)&group = false : false; \ +}while(false) + +/** @} */ + +#endif diff --git a/System/ur_api.h b/System/ur_api.h new file mode 100644 index 00000000..8196bc5f --- /dev/null +++ b/System/ur_api.h @@ -0,0 +1,1789 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file ur_api.h + * @brief 用户API + * @details 用户API定义,含注释说明,所有内核服务的API说明均在此文件中,并支持 doxygen。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __UR_API_H +#define __UR_API_H + +/** + \defgroup CosyOS_用户API + \brief 用户通过调用API来实现对系统服务的调用,所有API均为宏定义, + 所有系统服务也为宏定义,所有API参数均支持宏定义。 + @{ + */ + +/** + \page API说明: + \li API分类 + + \li 创建API
+ 静态创建:前缀为“u”,分为声明对象(uExtern)、创建对象(uCreate)、定义对象(uDef)。
+ 动态创建:前缀为“d”,分为声明对象(dExtern)、创建对象(dCreate)。 + + \li 任务API
+ 前缀为“u”,指仅在任务中调用。 + + \li 滴答API
+ 前缀为“t”,指仅在系统滴答中断中调用,包括在滴答钩子、定时中断钩子、
+ 定时查询钩子、定时查询事件等处调用。 + + \li 中断API
+ 前缀为“i”,指仅在用户中断中调用。 + + \li PSVAPI
+ 前缀为“p”,指仅在 pendsv_hook 中调用。 + + \li 公共API
+ 前缀为“x”,指可在任意处(任务、滴答、中断)调用。 + +
+ + \li API返回 + + \li 无返回
+ (1)服务的执行结果一定是成功的,所以不需要返回。
+ (2)所有中断挂起服务均无返回。 + + \li 返回错误码
+ 服务的执行结果可能会失败,导致失败的原因可能有多个。
+ (1)绿码:无错误。
+ (2)黄码:由于结果已经成功,导致本次并未执行。
+ (3)红码:失败。 + + \li 返回结果
+ 服务的执行结果可能会失败,但导致失败的原因是唯一的。
+ 执行结果为 bool 类型,true 为成功,false 为失败。 + + \li 返回指针
+ 返回一个指针,(void *) 类型,true 为成功,false(NULL)为失败。 + + \li 返回值
+ 返回一个数值,特定的数据类型,true 为成功,false(0)为失败。 + +
+ */ + + + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 任务 + @{ + */ + +/** + \ingroup 任务 + \defgroup 声明任务 + \brief 任务线程的声明 + @{ + */ + +/** + \brief 静态声明任务(无私信) + \param[in] task 任务名称 + \return 无 + */ +#define uExternTask(task) \ + sCSV_ExternTask(task) + +/** + \brief 动态声明任务(无私信) + \param[in] task 任务名称 + \return 无 + */ +#define dExternTask(task) \ + dCSV_ExternTask(task) + +/** + \brief 静态声明任务(有私信) + \param[in] task 任务名称 + \param[in] add...) 附加私信参数 + \return 无 + */ +#define uExternTask_Msg(task) \ + sCSV_ExternTask_Msg(task) + +/** + \brief 动态声明任务(有私信) + \param[in] task 任务名称 + \param[in] add...) 附加私信参数 + \return 无 + */ +#define dExternTask_Msg(task) \ + dCSV_ExternTask_Msg(task) + +/** @} */ + +/** + \ingroup 任务 + \defgroup 创建任务 + @{ + */ + +/** + \brief 静态创建一般任务 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define uCreateTask(task, pri, tss, srt, ntm) \ + sCSV_CreateTask(task, pri, tss, srt, ntm, OS_NULL) + +/** + \brief 动态创建一般任务 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define dCreateTask(task, pri, tss, srt, ntm) \ + dCSV_CreateTask(task, pri, tss, srt, ntm, OS_NULL) + +/** + \brief 静态创建定时中断任务 + \param[in] tmid 定时中断定时器ID + \param[in] arl 自动重装载 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define uCreateTask_TimInt(tmid, arl, task, pri, tss, srt, ntm) \ + sCSV_CreateTask_TimInt(tmid, arl, task, pri, tss, srt, ntm) + +/** + \brief 动态创建定时中断任务 + \param[in] tmid 定时中断定时器ID + \param[in] arl 自动重装载 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define dCreateTask_TimInt(tmid, arl, task, pri, tss, srt, ntm) \ + dCSV_CreateTask_TimInt(tmid, arl, task, pri, tss, srt, ntm) + +/** + \brief 静态创建定时查询任务 + \param[in] tmid 定时查询定时器ID + \param[in] event 定时查询事件 + \param[in] arl 自动重装载 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define uCreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, ntm) \ + sCSV_CreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, ntm) + +/** + \brief 动态创建定时查询任务 + \param[in] tmid 定时查询定时器ID + \param[in] event 定时查询事件 + \param[in] arl 自动重装载 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \param[in] tss 任务栈大小(单位为字节) + \param[in] srt 安全运行时(单位为时间片,0为无限长) + \param[in] ntm 私信参数的数量(0为无私信) + \param[in] add(...) 附加私信参数(当ntm为0时无此项) + \param[in] add{...} 附加任务代码 + \return 无 + */ +#define dCreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, ntm) \ + dCSV_CreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, ntm) + +/** @} */ + +/** + \ingroup 任务 + \defgroup 启动任务 + \warning 所有定时中断任务和定时查询任务均由操作系统自动启动,用户不可启动。 + \warning 不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + @{ + */ + +/** + \brief 启动任务 + \details 启动任务并置任务的初始状态为设定状态。 + \param[in] task 任务名称 + \param[in] status 任务的初始状态
+ 0:就绪状态
+ 1:挂起状态 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出 + \retval OS_ECODE_OVERFLOW_TASKQUEUE 任务队列溢出 + \retval OS_ECODE_MALLOCFAIL_TASKNODE 任务节点内存分配失败 + \retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败 + */ +#define uStartTask(task, status) \ + sUSV_StartTask(&u_taskhand_##task, (s_voidvoid_tfp)task, status) + +/** + \brief 启动任务并就绪 + \details 启动任务并置任务的初始状态为就绪状态。 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出 + \retval OS_ECODE_OVERFLOW_TASKQUEUE 任务队列溢出 + \retval OS_ECODE_MALLOCFAIL_TASKNODE 任务节点内存分配失败 + \retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败 + */ +#define uStartTask_Ready(task) \ + uStartTask(task, OS_STATUS_READY) + +/** + \brief 启动任务并挂起 + \details 启动任务并置任务的初始状态为挂起状态。 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出 + \retval OS_ECODE_OVERFLOW_TASKQUEUE 任务队列溢出 + \retval OS_ECODE_MALLOCFAIL_TASKNODE 任务节点内存分配失败 + \retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败 + */ +#define uStartTask_Suspend(task) \ + uStartTask(task, OS_STATUS_SUSPENDED) + +/** @} */ + +/** + \ingroup 任务 + \defgroup 操作任务 + @{ + */ + +/** + \brief 清除就绪延时 + \details 清除当前任务的就绪延时,前提是当前任务已在禁止调度中。 + \param 无 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ iClearDelay,无返回。
+ pClearDelay,无返回。 + */ +#define tClearDelay sTSV_ClearDelay + +/** + \brief 切换任务(尝试切换至某任务) + \param[in] task 任务名称 + \return 无 + \note 同型服务:
+ iSwitchTask(task)。
+ pSwitchTask(task)。 + */ +#define uSwitchTask(task) \ + sUSV_SwitchTask(u_taskhandle_##task) + +/** + \brief 恢复任务 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTSUSPENDED 任务未挂起 + \retval OS_ECODE_TASKSTOPPED 任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tResumeTask(task),同返回。
+ iResumeTask(task),无返回。
+ pResumeTask(task),无返回。 + */ +#define uResumeTask(task) \ + sUSV_ResumeTask(u_taskhandle_##task) + +/** + \brief 挂起任务 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKSUSPENDED 任务已挂起 + \retval OS_ECODE_TASKSTOPPED 任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSuspendTask(task),同返回。
+ iSuspendTask(task),无返回。
+ pSuspendTask(task),无返回。 + */ +#define uSuspendTask(task) \ + sUSV_SuspendTask(u_taskhandle_##task) + +/** + \brief 删除任务 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tDeleteTask(task),同返回。
+ iDeleteTask(task),无返回。
+ pDeleteTask(task),无返回。 + */ +#define uDeleteTask(task) \ + sUSV_DeleteTask(u_taskhandle_##task) + +/** + \brief 设置任务优先级 + \param[in] task 任务名称 + \param[in] pri 任务优先级 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKPRIUNCHANGED 任务优先级未改变 + \retval OS_ECODE_TASKSTOPPED 任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetTaskPri(task, pri),同返回。
+ iSetTaskPri(task, pri),无返回。
+ pSetTaskPri(task, pri),无返回。 + */ +#define uSetTaskPri(task, pri) \ + sUSV_SetTaskPri(u_taskhandle_##task, pri) + +/** + \brief 清除阻塞(状态) + \details 清除指定任务的阻塞状态并使其就绪。 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tClearBlock(task),同返回。
+ iClearBlock(task),无返回。
+ pClearBlock(task),无返回。 + */ +#define uClearBlock(task) \ + sUSV_ClearBlock(u_taskhandle_##task) + +/** + \ingroup 操作任务 + \defgroup 设置阻塞(时间) + \brief 设置、修改指定任务的阻塞时间,前提是该任务当前已为阻塞或浮动状态。
+ 理想误差:-1tick。 + \warning 按 毫秒、秒钟、分钟、小时 设置,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + \warning 无限阻塞(阻塞时间为无限长),仅能通过调用 xSetBlock_tc(task, ~0) 来实现。 + @{ + */ + +/** + \brief 设置阻塞-滴答周期 + \param[in] task 任务名称 + \param[in] tc 滴答周期(阻塞时间)
+ +0:清除阻塞
+ ~0:无限阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_tc(task, tc),同返回。
+ iSetBlock_tc(task, tc),无返回。
+ pSetBlock_tc(task, tc),无返回。 + */ +#define uSetBlock_tc(task, tc) sUSV_SetBlock(u_taskhandle_##task, tc) + +/** + \brief 设置阻塞-毫秒 + \param[in] task 任务名称 + \param[in] ms 毫秒(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_ms(task, ms),同返回。
+ iSetBlock_ms(task, ms),无返回。
+ pSetBlock_ms(task, ms),无返回。 + */ +#define uSetBlock_ms(task, ms) uSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/** + \brief 设置阻塞-秒钟 + \param[in] task 任务名称 + \param[in] s 秒钟(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_s(task, s),同返回。
+ iSetBlock_s(task, s),无返回。
+ pSetBlock_s(task, s),无返回。 + */ +#define uSetBlock_s(task, s) uSetBlock_ms(task, 1000UL * (s)) + +/** + \brief 设置阻塞-分钟 + \param[in] task 任务名称 + \param[in] m 分钟(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_m(task, m),同返回。
+ iSetBlock_m(task, m),无返回。
+ pSetBlock_m(task, m),无返回。 + */ +#define uSetBlock_m(task, m) uSetBlock_s(task, 60UL * (m)) + +/** + \brief 设置阻塞-小时 + \param[in] task 任务名称 + \param[in] h 小时(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_h(task, h),同返回。
+ iSetBlock_h(task, h),无返回。
+ pSetBlock_h(task, h),无返回。 + */ +#define uSetBlock_h(task, h) uSetBlock_m(task, 60UL * (h)) + +/** @} */ +/** @} */ +/** + \ingroup 任务 + \defgroup 操作自身任务 + \brief 仅适用于对自身任务的操作。 + @{ + */ + +/** + \brief 禅让任务 + \details 自身任务主动禅让CPU使用权给其它相同优先级的任务。 + \return 无 + \note 多个相同优先级的任务,通过禅让的方式可实现合作式任务。 + */ +#define uYieldTasking su_yield_tasking() + +/** + \brief 设置自身任务优先级 + \param[in] pri 任务优先级 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TPLUNCHANGED 优先级未改变 + */ +#define uSetTaskingPri(pri) sUSV_SetTaskPri(s_task_current, pri) + +/** + \brief 挂起自身任务 + \return 错误码(s_ecode_t) + \note 虽然也返回错误码,但在正常情况下结果一定是成功的,不必查看错误码。 + */ +#define uSuspendTasking sUSV_SuspendTask(s_task_current) + +/** + \brief 删除自身任务 + \return 错误码(s_ecode_t) + \note 虽然也返回错误码,但在正常情况下结果一定是成功的,不必查看错误码。 + */ +#define uDeleteTasking sUSV_DeleteTask(s_task_current) + +/** + \brief 恢复指定任务并挂起自身任务 + \param[in] task 指定任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTREADY 指定任务未就绪 + \retval OS_ECODE_TASKSTOPPED 指定任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 指定任务未启动/已删除 + \note 当返回错误时,指定任务未能成功恢复,自身任务不会挂起。 + */ +#define uResumeSuspend(task) sUSV_ResumeSuspend(u_taskhandle_##task) + +/** + \brief 结束自身任务 + \details 所有任务线程的最后一句代码。 + \return 无 + */ +#define uEndTasking }while(true) + +/** + \ingroup 操作自身任务 + \defgroup 自身任务延时 + \brief 自身任务延时分为阻塞延时和就绪延时。
+ 理想误差:-1tick。 + \note 阻塞延时:在延时期间,任务会进入阻塞状态,把CPU使用权转让给其它任务。 + \note 就绪延时:在延时期间,任务会维持就绪状态,原地等待延时时间到达,不转让CPU使用权。 + \note 当在禁止调度中,自动选择为就绪延时,否则选择为阻塞延时。 + \warning 按 毫秒、秒钟、分钟、小时 延时,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + \warning 无限延时(延时时间为无限长),仅能通过调用 uDelay_tc(~0) 来实现。 + \warning 不支持在临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + @{ + */ + +/** + \brief 延时-滴答周期 + \param[in] tc 滴答周期(延时时间)
+ ~0:无限延时 + \return 无 + */ +#define uDelay_tc(tc) sUSV_Delay(tc) + +/** + \brief 延时-毫秒 + \param[in] ms 毫秒(延时时间) + \return 无 + */ +#define uDelay_ms(ms) uDelay_tc((1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/** + \brief 延时-秒钟 + \param[in] s 秒钟(延时时间) + \return 无 + */ +#define uDelay_s(s) uDelay_ms(1000UL * (s)) + +/** + \brief 延时-分钟 + \param[in] m 分钟(延时时间) + \return 无 + */ +#define uDelay_m(m) uDelay_s(60UL * (m)) + +/** + \brief 延时-小时 + \param[in] h 小时(延时时间) + \return 无 + */ +#define uDelay_h(h) uDelay_m(60UL * (h)) +/** @} */ +/** @} */ +/** @} */ +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 创建钩子 + @{ + */ + +/** + \brief 创建定时中断钩子 + \param[in] tmid 定时器ID + \param[in] arl 自动重装载设置 [0:关闭自动重装载,1:开启自动重装载] + \param[in] hook 钩子函数 + \param[in] add{...} 附加钩子代码 + \return 无 + */ +#define uCreateHook_TimInt(tmid, arl, hook) \ + sCSV_CreateHook_TimInt(tmid, arl, hook) + +/** + \brief 创建定时查询钩子 + \param[in] tmid 定时器ID + \param[in] event 定时查询事件 + \param[in] arl 自动重装载设置 [0:关闭自动重装载,1:开启自动重装载] + \param[in] hook 钩子函数 + \param[in] add{...} 附加钩子代码 + \return 无 + */ +#define uCreateHook_TimQry(tmid, event, arl, hook) \ + sCSV_CreateHook_TimQry(tmid, event, arl, hook) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 定时中断_查询 + @{ + */ + +/** + \ingroup 定时中断_查询 + \defgroup 定时中断 + \brief 定时中断定时器的相关设置,包括设置定时时间、自动重装载设置等。
+ 理想误差:-1tick。 + \warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + @{ + */ + +/** + \brief 定时中断-滴答周期 + \param[in] tmid 定时中断定时器ID + \param[in] tc 滴答周期(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_tc(tmid, tc)。
+ iTimInt_tc(tmid, tc)。 + */ +#define uTimInt_tc(tmid, tc) sUSV_TimInt(tmid, tc) + +/** + \brief 定时中断-毫秒 + \param[in] tmid 定时中断定时器ID + \param[in] ms 毫秒(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_ms(tmid, ms)。
+ iTimInt_ms(tmid, ms)。 + */ +#define uTimInt_ms(tmid, ms) uTimInt_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/** + \brief 定时中断-秒钟 + \param[in] tmid 定时中断定时器ID + \param[in] s 秒钟(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_s(tmid, s)。
+ iTimInt_s(tmid, s)。 + */ +#define uTimInt_s(tmid, s) uTimInt_ms(tmid, 1000UL * (s)) + +/** + \brief 定时中断-分钟 + \param[in] tmid 定时中断定时器ID + \param[in] m 分钟(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_m(tmid, m)。
+ iTimInt_m(tmid, m)。 + */ +#define uTimInt_m(tmid, m) uTimInt_s(tmid, 60UL * (m)) + +/** + \brief 定时中断-小时 + \param[in] tmid 定时中断定时器ID + \param[in] h 小时(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_h(tmid, h)。
+ iTimInt_h(tmid, h)。 + */ +#define uTimInt_h(tmid, h) uTimInt_m(tmid, 60UL * (h)) + +/** + \brief 终止定时中断 + \param[in] tmid 定时中断定时器ID + \return 无 + \note 同型服务:
+ tTimInt_Cancel(tmid)。
+ iTimInt_Cancel(tmid)。 + */ +#define uTimInt_Cancel(tmid) uTimInt_tc(tmid, 0) + +/** + \brief 定时中断定时器自动重装载 + \param[in] tmid 定时中断定时器ID + \param[in] arl 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \return 无 + */ +#define xTimInt_AutoReload(tmid, arl) s_timint_autoreload[tmid] = arl + +/** @} */ + +/** + \ingroup 定时中断_查询 + \defgroup 定时查询 + \brief 定时查询定时器的相关设置,包括设置定时时间、自动重装载设置等。
+ 理想误差:-1tick。 + \warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + @{ + */ + +/** + \brief 定时查询-滴答周期 + \param[in] tmid 定时查询定时器ID + \param[in] tc 滴答周期(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_tc(tmid, tc)。
+ iTimQry_tc(tmid, tc)。 + */ +#define uTimQry_tc(tmid, tc) sUSV_TimQry(tmid, tc) + +/** + \brief 定时查询-毫秒 + \param[in] tmid 定时查询定时器ID + \param[in] ms 毫秒(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_ms(tmid, ms)。
+ iTimQry_ms(tmid, ms)。 + */ +#define uTimQry_ms(tmid, ms) uTimQry_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/** + \brief 定时查询-秒钟 + \param[in] tmid 定时查询定时器ID + \param[in] s 秒钟(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_s(tmid, s)。
+ iTimQry_s(tmid, s)。 + */ +#define uTimQry_s(tmid, s) uTimQry_ms(tmid, 1000UL * (s)) + +/** + \brief 定时查询-分钟 + \param[in] tmid 定时查询定时器ID + \param[in] m 分钟(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_m(tmid, m)。
+ iTimQry_m(tmid, m)。 + */ +#define uTimQry_m(tmid, m) uTimQry_s(tmid, 60UL * (m)) + +/** + \brief 定时查询-小时 + \param[in] tmid 定时查询定时器ID + \param[in] h 小时(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_h(tmid, h)。
+ iTimQry_h(tmid, h)。 + */ +#define uTimQry_h(tmid, h) uTimQry_m(tmid, 60UL * (h)) + +/** + \brief 终止定时查询 + \param[in] tmid 定时查询定时器ID + \return 无 + \note 同型服务:
+ tTimQry_Cancel(tmid)。
+ iTimQry_Cancel(tmid)。 + */ +#define uTimQry_Cancel(tmid) uTimQry_tc(tmid, ~0) + +/** + \brief 定时查询定时器自动重装载 + \param[in] tmid 定时查询定时器ID + \param[in] arl 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \return 无 + */ +#define xTimQry_AutoReload(tmid, arl) s_timqry_autoreload[tmid] = arl + +/** @} */ +/** @} */ +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 信号量 + @{ + */ + +/** + \ingroup 信号量 + \defgroup 互斥信号量 + \brief 仅适用于任务中对任务级公共资源的互斥访问。 + \details 任务必须先成功获取互斥量,而后才能访问资源,当资源访问结束时,需归还互斥量。 + \note 有优先级继承机制,以抑制优先级反转的发生。 + \note 互斥信号量均支持递归,最大嵌套深度:255。 + \note 如果任务中调用了获取互斥量,应谨慎操作该任务,如操作不当可能会导致获取相同互斥量的其它任务死锁。 + @{ + */ + +/** + \brief 声明互斥信号量 + \param[in] mut 互斥信号量名称 + \return 无 + */ +#define uExternMut(mut) sCSV_ExternMut(mut) + +/** + \brief 创建互斥信号量 + \param[in] mut 互斥信号量名称 + \return 无 + \warning 创建互斥信号量时,系统将自动赋初值,用户不可赋初值。 + */ +#define uCreateMut(mut) sCSV_CreateMut(mut) + +/** + \brief 获取互斥信号量 + \param[in] mut 互斥信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \warning 不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uTakeMut(mut, tc) sUSV_TakeMut(mut, tc) + +/** + \brief 归还互斥信号量 + \param[in] mut 互斥信号量名称 + \return 无 + */ +#define uBackMut(mut) sUSV_BackMut(mut) + +/** @} */ + +/** + \ingroup 信号量 + \defgroup 二值信号量 + \brief 二值信号量常用于线程同步、互斥访问。 + + @{ + */ + +/** + \brief 声明二值信号量 + \param[in] bin 二值信号量名称 + \return 无 + */ +#define uExternBin(bin) sCSV_ExternBin(bin) + +/** + \brief 创建二值信号量 + \param[in] bin 二值信号量名称 + \param[in] init 二值信号量初始值 [0:上锁,1:xx] + \return 无 + */ +#define uCreateBin(bin, init) sCSV_CreateBin(bin, init) + +/** + \brief 上锁二值信号量 + \details 用于终止线程的无限同步。 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tLockBin(bin)。
+ iLockBin(bin)。
+ pLockBin(bin)。 + */ +#define uLockBin(bin) bin.binary = false + +/** + \brief 等待二值信号量 + \details 在指定的超时时间内等待二值信号量为真,适用于任务的无限同步,与获取的区别是不上锁。 + \param[in] bin 二值信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \warning 不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uWaitBin(bin, tc) sUSV_WaitBin(bin, tc) + +/** + \brief 给予二值信号量 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tGiveBin(bin)。
+ iGiveBin(bin)。
+ pGiveBin(bin)。 + */ +#define uGiveBin(bin) sUSV_GiveBin(bin) + +/** + \brief 获取二值信号量 + \param[in] bin 二值信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ tTakeBin(bin)。
+ iTakeBin(bin)。 + \warning 任务中获取,不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uTakeBin(bin, tc) sUSV_TakeBin(bin, tc) + +/** + \brief 归还二值信号量 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tBackBin(bin)。
+ iBackBin(bin)。 + */ +#define uBackBin(bin) uGiveBin(bin) + +/** @} */ + +/** + \ingroup 信号量 + \defgroup 计数信号量 + \brief 计数信号量常用于线程同步、资源管理。 + @{ + */ + +/** + \brief 声明计数信号量 + \param[in] sem 计数信号量名称 + \return 无 + */ +#define uExternSem(sem) sCSV_ExternSem(sem) + +/** + \brief 创建计数信号量 + \param[in] sem 计数信号量名称 + \param[in] init 计数信号量初始值 + \param[in] max 计数信号量最大值 + \return 无 + */ +#define uCreateSem(sem, init, max) sCSV_CreateSem(sem, init, max) + +/** + \brief 给予计数信号量 + \param[in] sem 计数信号量名称 + \return 无 + \note 同型服务:
+ tGiveSem(sem)。
+ iGiveSem(sem)。 + */ +#define uGiveSem(sem) sUSV_GiveSem(sem) + +/** + \brief 获取计数信号量 + \param[in] sem 计数信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ tTakeSem(sem)。 + \warning 任务中获取,不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uTakeSem(sem, tc) sUSV_TakeSem(sem, tc) + +/** + \brief 归还计数信号量 + \param[in] sem 计数信号量名称 + \return 无 + \note 同型服务:
+ tBackSem(sem)。 + */ +#define uBackSem(sem) uGiveSem(sem) + +/** @} */ +/** @} */ +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 私信 + \brief 私信是CosyOS独创的一种任务间通信方式,典型特征是 随意定义、灵活多变。 + @{ + */ + +/** + \brief 接收私信
+
+ 别名
+           + uRecvTM + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \warning 不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uRecvTaskMsg(tc) sUSV_RecvTaskMsg(tc) + +/** + \brief 发送私信
+
+ 别名
+           + uSendTM + \param[in] task 任务名称 + \param[in] add...) 附加私信实参 + \return 无 + \note 同型服务:
+ tSendTaskMsg(task) / tSendTM。 + \warning 如果在条件分支内调用,分支语句的{}不可省略。 + */ +#define uSendTaskMsg(task) sUSV_SendTaskMsg(task) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 飞信 + \brief 飞信是轻量型的、超高速的线程通信工具,典型特征是 极简类型、极速通信。 + \details 仅使用一个变量,同时即是消息,又是新消息标志。
+ 飞信为0时,表示无消息;飞信非0时,表示有消息;
+ 因此, + \warning 用户传输的有效消息必须为真值。 + \note 架构          数据类型
+ 8051         uint8_t
+ 80251       uint16_t
+ Arm32      uint32_t
+ 通用别名   m_fetion_t + @{ + */ + +/** + \brief 声明信箱 + \param[in] tbox 信箱名称 + \return 无 + */ +#define uExternTionbox(tbox) sCSV_ExternTionbox(tbox) + +/** + \brief 创建信箱 + \param[in] tbox 信箱名称 + \return 无 + */ +#define uCreateTionbox(tbox) sCSV_CreateTionbox(tbox) + +/** + \brief 接收飞信
+
+ 别名
+           + uRecvFet + \param[in] tbox 信箱名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 飞信(m_fetion_t) + \retval false 无飞信 + \note 同型服务:
+ tRecvFetion(tbox) / tRecvFet。
+ iRecvFetion(tbox) / iRecvFet。 + \warning 任务中接收,不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uRecvFetion(tbox, tc) sUSV_RecvFetion(tbox, tc) + +/** + \brief 发送飞信
+
+ 别名
+           + uSendFet + \param[in] tbox 信箱名称 + \param[in] tion 飞信 + \return 无 + \note 同型服务:
+ tSendFetion(tbox, tion) / tSendFet。
+ iSendFetion(tbox, tion) / iSendFet。 + */ +#define uSendFetion(tbox, tion) sUSV_SendFetion(tbox, tion) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 邮箱 + @{ + */ + +/** + \brief 声明邮箱 + \param[in] mbox 邮箱名称 + \return 无 + */ +#define uExternMailbox(mbox) sCSV_ExternMailbox(mbox) + +/** + \brief 创建邮箱 + \param[in] mbox 邮箱名称 + \return 无 + */ +#define uCreateMailbox(mbox) sCSV_CreateMailbox(mbox) + +/** + \brief 接收邮件 + \param[in] mbox 邮箱名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 邮件指针(void *) + \retval NULL 无邮件 + \note 同型服务:
+ tRecvMail(mbox)。
+ iRecvMail(mbox)。 + \warning 任务中接收,不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uRecvMail(mbox, tc) sUSV_RecvMail(mbox, tc) + +/** + \brief 发送邮件 + \param[in] mbox 邮箱名称 + \param[in] mail 邮件指针 + \return 无 + \note 同型服务:
+ tSendMail(mbox, mail)。
+ iSendMail(mbox, mail)。 + */ +#define uSendMail(mbox, mail) sUSV_SendMail(mbox, mail) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 消息队列 + \brief 消息队列是唯一能够实现并发消息同步的手段。 + \details 消息队列包括静态队列和动态队列。
+ 静态队列:收发消息的效率高,队列占用固定的内存;
+ 动态队列:收发消息的效率低,接收消息后,队列内存可被回收。 + \note 每个队列,用户应当自己明确消息的类型和size,此事与OS无关。 + @{ + */ + +/** + \brief 声明静态队列 + \param[in] que 队列名称 + \return 无 + */ +#define uExternQueue_Static(que) sCSV_ExternQueue_Static(que) + +/** + \brief 声明动态队列 + \param[in] que 队列名称 + \return 无 + */ +#define uExternQueue_Dynamic(que) sCSV_ExternQueue_Dynamic(que) + +/** + \brief 创建静态队列 + \param[in] que 队列名称 + \param[in] mode 传输模式
+ 0:FIFO(先入先出)
+ 1:LIFO(后入先出) + \param[in] len 队列长度 + \return 无 + */ +#define uCreateQueue_Static(que, mode, len) sCSV_CreateQueue_Static(que, mode, len) + +/** + \brief 创建动态队列 + \param[in] que 队列名称 + \param[in] mode 传输模式
+ 0:FIFO(先入先出)
+ 1:LIFO(后入先出) + \param[in] len 队列长度 + \return 无 + */ +#define uCreateQueue_Dynamic(que, mode, len) sCSV_CreateQueue_Dynamic(que, mode, len) + +/** + \brief 接收消息 + \param[in] que 队列名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 消息指针(void *) + \retval NULL 无消息 + \note 同型服务:
+ tRecvMsg(que)。
+ iRecvMsg(que)。 + \warning 任务中接收,不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + \warning 中断中接收,队列只能是静态队列,消息缓存只能是静态缓存。 + */ +#define uRecvMsg(que, tc) sUSV_RecvMsg(que, tc) + +/** + \brief 发送消息 + \param[in] que 队列名称 + \param[in] msg 消息指针 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval ECODE_OVERFLOW_MSGQUEUE 消息队列溢出 + \retval ECODE_MALLOCFAIL_MSGNODE 消息节点内存分配失败 + \note 同型服务:
+ tSendMsg(que, msg),同返回。
+ iSendMsg(que, msg),无返回。 + \warning 中断中发送,消息缓存只能是静态缓存。 + */ +#define uSendMsg(que, msg) sUSV_SendMsg(que, msg) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 事件标志组 + \note 名词解释
+ 组名:标志组的名称
+ 位名:标志位的名称
+ 空位:空标志位
+ \note 查询标志位:任务、滴答、中断中,均直接查询。 + @{ + */ + +/** + \brief 声明标志组 + \param[in] group 组名 + \param[in] bits 定义各标志位,分号间隔 + \return 无 + */ +#define uExternFlagGroup(group, bits) sCSV_ExternFlagGroup(group, bits) + +/** + \brief 定义标志位 + \param[in] bit 位名 + \return 无 + */ +#define uDefFlagBit(bit) sDefBitField(bit) + +/** + \brief 定义空位 + \param[in] nvb 空位的数量 + \return 无 + */ +#define uDefVoidBits(nvb) sDefVoidBits(nvb) + +/** + \brief 创建标志组 + \param[in] group 组名 + \param[in] add={...} 附加代码(赋初值) + \return 无 + */ +#define uCreateFlagGroup(group) sCSV_CreateFlagGroup(group) + +/** + \brief 等待标志组 + \param[in] group 组名 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \warning 不支持在禁止调度中、临界区中(包括任务临界区和全局临界区)或关闭总中断时调用。 + */ +#define uWaitFlagGroup(group, tc) sUSV_WaitFlagGroup(group, tc) + +/** + \brief 查询标志组 + \param[in] group 组名 + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ tQueryFlagGroup(group)。
+ iQueryFlagGroup(group)。 + */ +#define uQueryFlagGroup(group) sUSV_QueryFlagGroup(group) + +/** + \brief 清除标志组 + \param[in] group 组名 + \return 无 + \note 同型服务:
+ tClearFlagGroup(group)。
+ iClearFlagGroup(group)。 + */ +#define uClearFlagGroup(group) sUSV_ClearFlagGroup(group) + +/** + \brief 设置标志位 + \param[in] group 组名 + \param[in] bit 位名 + \return 无 + \note 同型服务:
+ iSetFlagBit(group, bit)。 + \note 滴答中直接设置,任务中也可在任务临界区中设置。 + */ +#define uSetFlagBit(group, bit) sUSV_WriteFlagBit(group, bit, true) + +/** + \brief 清除标志位 + \param[in] group 组名 + \param[in] bit 位名 + \return 无 + \note 同型服务:
+ iClearFlagBit(group, bit)。 + \note 滴答中直接清除,任务中也可在任务临界区中清除。 + */ +#define uClearFlagBit(group, bit) sUSV_WriteFlagBit(group, bit, false) + +/** + \brief 设置多标志位 + \param[in] group 组名 + \param[in] nbit 标志位的数量 + \param[in] add...) 各位名,逗号间隔 + \return 无 + \note 滴答中直接设置,任务中在任务临界区中设置。 + */ +#define iSetFlagBits(group, nbit) sPSV_WriteFlagBits(group, +, nbit) + +/** + \brief 清除多标志位 + \param[in] group 组名 + \param[in] nbit 标志位的数量 + \param[in] add...) 各位名,逗号间隔 + \return 无 + \note 滴答中直接清除,任务中在任务临界区中清除。 + */ +#define iClearFlagBits(group, nbit) sPSV_WriteFlagBits(group, -, nbit) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 全局变量访问 + @{ + */ + +/** + \brief 更新全局变量副本 + \param[in] code 更新副本的代码 + \return 无 + */ +#define xUpdateCopy(code) sUpdateCopy(code) + +/** + \brief 读哪一个全局变量? + \return 结果(s_bool_t) + \retval true 读正本 + \retval false 读副本 + */ +#define iWhichGVar_Read s_sign_updatecopy + +/** + \brief 写全局变量 + \param[in] gv 全局变量名称 + \param[in] lv 局部变量名称 + \return 无 + */ +#define iWriteGVar(gv, lv) sPSV_WriteGVar((void *)&gv, (void *)&lv, sizeof(gv)) + +/** + \brief 写全局数组 + \param[in] gp 全局数组指针 + \param[in] lp 局部数组指针 + \param[in] size 拷贝的大小(字节数) + \return 无 + */ +#define iWriteGAry(gp, lp, size) sPSV_WriteGVar(gp, lp, size) + +/** + \brief 写全局字符串 + \param[in] gs 全局字符串指针 + \param[in] ls 局部字符串指针 + \return 无 + */ +#define iWriteGStr(gs, ls) sPSV_WriteGVar(gs, ls, 0) + +/** + \brief 挂起服务调用 + \param[in] fp 函数指针 + \return 无 + */ +#define iPendSVC(fp) sPSV_PendSVC(fp) + +/** + \brief 发送信号 + \param[in] sign 信号名称 + \return 无 + */ +#define iSendSign(sign) sPSV_SendSign(sign) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 软件RTC + @{ + */ + +/** + \brief 获取时间 + \param[in] t 本地时间的指针(s_rtc_ts) + \return 本地时间的指针 + \note 同型服务:
+ tGetTime(t)。
+ iGetTime(t)。 + */ +#define uGetTime(t) sUSV_GetTime(t) + +/** + \brief 设置时间 + \param[in] t 本地时间的指针(s_rtc_ts) + \return 无 + \note 同型服务:
+ tSetTime(t)。
+ iSetTime(t)。 + */ +#define uSetTime(t) sUSV_SetTime(t) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 动态内存 + @{ + */ + +/** + \ingroup 动态内存 + \defgroup 进程内存 + \brief 以进程为单位初始化内存池,各进程独享自己的内存池。 + @{ + */ + +/** + \brief malloc + \details 在进程内存池或堆中分配一块内存。 + \param[in] size 内存块的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uMalloc(size) sUSV_Malloc(size) + +/** + \brief calloc + \details 在进程内存池或堆中连续分配多块内存。 + \param[in] nmemb 内存块的数量 + \param[in] size 内存块的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uCalloc(nmemb, size) sUSV_Calloc(nmemb, size) + +/** + \brief realloc + \details 重新分配内存。 + \param[in] p 预重分配的指针 + \param[in] size 预重分配的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uRealloc(p, size) sUSV_Realloc(p, size) + +/** + \brief free + \param[in] p 释放的指针 + \return 无 + */ +#define uFree(p) sUSV_Free(p) + +/** @} */ + +/** + \ingroup 动态内存 + \defgroup 线程内存 + \brief 以线程为单位初始化内存池,各线程独享自己的内存池。 + \note 线程内存的分配效率远高于进程内存,因为每一次调用uTalloc都是在自己的线程内存池中直接按序分配内存。 + \note 在某线程中,如果需要多次动态内存分配,可考虑采用线程内存以提高性能。 + \note 线程内存的应用法则:当所有uTalloc的内存都可以释放时,再一次性释放所有内存(线程内存池)。 + @{ + */ + +/** + \brief 创建线程内存池 + \details 实为定义变量(线程内存控制块),C89模式时可考虑在线程的开始处创建。 + \return 无 + */ +#define uCreateMempool sCSV_CreateMempool + +/** + \brief 初始化线程内存池 + \details 实质上是通过调用malloc,从进程内存池或堆中分配一块内存来做为线程内存池。 + \param[in] size 线程内存池的大小(字节数) + \return 结果(s_bool_t) + \retval false 失败 + \retval true 成功 + */ +#define uInitMempool(size) sUSV_InitMempool(size) + +/** + \brief 线程内存分配 + \details 在线程内存池中分配一块内存。 + \param[in] size 内存块的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uTalloc(size) sUSV_Talloc(size) + +/** + \brief 释放线程内存池 + */ +#define uFreeMempool sUSV_FreeMempool + +/** @} */ +/** @} */ +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 禁止调度 + \brief 仅是禁止任务调度,不会关闭系统中断(SysTick、PendSV),仅支持在任务中调用。 + \note 禁止调度适用于在任务中,对大段的任务级公共资源和程序过程的保护。 + \note 支持嵌套功能(最大嵌套深度255),嵌套使用时,禁止调度与恢复调度必须配对使用。 + \note 禁止调度与任务临界区之间可随意互相嵌套,但仅推荐在禁止调度中嵌套任务临界区。 + @{ + */ + +/** + \brief 禁止调度 + \return 无 + */ +#define uForbidSchedule su_forbid_schedule() + +/** + \brief 恢复调度 + \return 无 + */ +#define uResumeSchedule su_resume_schedule() + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 临界区 + @{ + */ + +/** + \ingroup 临界区 + \defgroup 任务临界区 + \brief 任务级的临界区保护,同时也是系统级的临界区保护(当做为服务层临界区的一部分),
+ 仅关闭系统中断(SysTick、PendSV),仅支持在任务中调用。 + \note 支持嵌套功能(最大嵌套深度255),嵌套使用时,进入临界区与退出临界区必须配对使用。 + \note 任务临界区与禁止调度之间可随意互相嵌套,但仅推荐在禁止调度中嵌套任务临界区。 + @{ + */ + +/** + \brief 进入任务临界区 + \return 无 + */ +#define uEnterCritical su_enter_critical() + +/** + \brief 退出任务临界区 + \return 无 + */ +#define uExitCritical su_exit_critical() + +/** @} */ + +/** + \ingroup 临界区 + \defgroup 全局临界区 + \brief 系统级的临界区保护,通常会关闭总中断,支持在任意处调用。 + \note 除M0等MCU外,CosyOS内核中从来不会进入全局临界区,提供此项服务只是为了便于用户
+ 对全局公共资源和程序过程的保护。 + @{ + */ +#if MCUCFG_ISA != __ARM__ +/** + \ingroup 全局临界区 + \defgroup 操作-EA + \note 支持嵌套功能(最大嵌套深度255),嵌套使用时,进入临界区与退出临界区必须配对使用。 + @{ + */ + +/** + \brief 进入全局临界区 + \return 无 + */ +#define xDisableIRQ mxDisableIRQ + +/** + \brief 退出全局临界区 + \return 无 + */ +#define xResumeIRQ mxResumeIRQ + +/** @} */ +#else +/** + \ingroup 全局临界区 + \defgroup 操作-PRIMASK + \note 支持嵌套功能,嵌套使用时,进入临界区与退出临界区必须配对使用。 + @{ + */ + +/** + \brief 进入全局临界区 + \return oldirq PRIMASK上一次的值(uint32_t类型) + */ +#define xDisableIRQ mxDisableIRQ + +/** + \brief 退出全局临界区 + \param[in] oldirq PRIMASK上一次的值(uint32_t类型) + \return 无 + */ +#define xResumeIRQ(oldirq) mxResumeIRQ(oldirq) + +/** @} */ + +/** + \ingroup 全局临界区 + \defgroup 操作-BASEPRI + \note 使用条件:
+ 1、MCU必须有 BASEPRI 寄存器;
+ 2、MCU配置中,系统中断配置必须选择 TIMn_IRQHandler + XXX_IRQHandler。 + \note 使用说明:
+ 1、关于newpri,例如中断优先级分组选择 NVIC_PriorityGoup_4,那么中断优先级从高到低为 0~15。
+ 如果需要掩蔽(3~15)的中断,newpri应输入3。
+ 2、支持嵌套功能,嵌套使用时,进入临界区与退出临界区必须配对使用。
+ 3、嵌套使用时,仅能逐步扩大掩蔽范围(newpri越来越小),否则新的掩蔽范围不会生效(将维持上一次的掩蔽范围)。 + @{ + */ + +/** + \brief 进入全局临界区 + \param[in] newpri 掩蔽范围的最高优先级的优先级号(uint32_t类型) + \return oldpri BASEPRI的原值(uint32_t类型) + */ +#define xMaskingPRI(newpri) mxMaskingPRI(newpri) + +/** + \brief 退出全局临界区 + \param[in] oldpri BASEPRI的原值(uint32_t类型) + \return 无 + */ +#define xResumePRI(oldpri) mxResumePRI(oldpri) + +/** @} */ +#endif +/** @} */ +/** @} */ +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 杂项 + @{ + */ + +/** + \ingroup 杂项 + \defgroup DEBUG + \code +应用示例: + +一、8051/251-UART1 +void UART1_Isr(void) interrupt 4 +{ + if(TI){ + TI = 0; + if(*s_debug_sendptr){ + SBUF = *s_debug_sendptr++; + } + else{ + iDebugSend; + } + } + if(RI){ + RI = 0; + if(s_debug_recvptr - s_debug_recvbuff < OS_DEBUGRECVBUFFSIZE - 1){ + *s_debug_recvptr++ = SBUF; + } + iDebugRecv; + } +} + +二、STM32-USART1 +void USART1_IRQHandler(void) +{ + if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET){ + if(*s_debug_sendptr){ + USART_SendData(USART1, *s_debug_sendptr++); + } + else{ + USART_ITConfig(USART1, USART_IT_TXE, DISABLE); + iDebugSend; + } + } + if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ + if(s_debug_recvptr - s_debug_recvbuff < OS_DEBUGRECVBUFFSIZE - 1){ + *s_debug_recvptr++ = USART_ReceiveData(USART1); + } + iDebugRecv; + } +} + \endcode + @{ + */ +#define iDebugSend s_sign_debug_send = true +#define iDebugRecv s_sign_debug_recv = true + +/** @} */ + +/** + \ingroup 杂项 + \defgroup 时间单位转换 + \brief 把其它单位的时间转换为滴答周期。 + @{ + */ + +/** + \brief 毫秒转换为滴答周期 + \param[in] ms 毫秒 + \return 滴答周期 + */ +#define xTick_ms(ms) ((1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/** + \brief 秒钟转换为滴答周期 + \param[in] s 秒钟 + \return 滴答周期 + */ +#define xTick_s(s) xTick_ms(1000UL * (s)) + +/** + \brief 分钟转换为滴答周期 + \param[in] m 分钟 + \return 滴答周期 + */ +#define xTick_m(m) xTick_s(60UL * (m)) + +/** + \brief 小时转换为滴答周期 + \param[in] h 小时 + \return 滴答周期 + */ +#define xTick_h(h) xTick_m(60UL * (h)) + +/** @} */ + +/** + \ingroup 杂项 + \defgroup 触发PendSV + \note 在用户中断中,当采用中断挂起服务FLAG队列执行服务时,用户在设置标志位后需手动触发PendSV, + 而后在 pendsv_hook() 中执行服务。 + @{ + */ + +#define iPendSV_Set mPendSV_Set + +/** @} */ +/** @} */ + + +/** @} */ +#endif diff --git a/System/ur_eapi.h b/System/ur_eapi.h new file mode 100644 index 00000000..d647f7b3 --- /dev/null +++ b/System/ur_eapi.h @@ -0,0 +1,217 @@ +/**************************************************************************//** + * @item CosyOS-II Kernel + * @file ur_eapi.h + * @brief 用户API扩展 + * @details 用户API的补充扩展定义,仅是定义无注释说明,所有内核服务的API说明 + 均在 ur_api.h 中,并支持 doxygen。 + * @author 迟凯峰 + * @version V3.2.0 + * @date 2024.12.13 + ******************************************************************************/ + +#ifndef __UR_EAPI_H +#define __UR_EAPI_H + + + +/* 清除就绪延时 */ +#define iClearDelay sPSV_ClearDelay +#define pClearDelay sPS2_ClearDelay + +/* 切换任务 */ +#define iSwitchTask(task) sPSV_SwitchTask(u_taskhandle_##task) +#define pSwitchTask(task) sPS2_SwitchTask(u_taskhandle_##task) + +/* 恢复任务 */ +#define tResumeTask(task) sTSV_ResumeTask(u_taskhandle_##task) +#define iResumeTask(task) sPSV_ResumeTask(u_taskhandle_##task) +#define pResumeTask(task) sPS2_ResumeTask(u_taskhandle_##task) + +/* 挂起任务 */ +#define tSuspendTask(task) sTSV_SuspendTask(u_taskhandle_##task) +#define iSuspendTask(task) sPSV_SuspendTask(u_taskhandle_##task) +#define pSuspendTask(task) sPS2_SuspendTask(u_taskhandle_##task) + +/* 删除任务 */ +#define tDeleteTask(task) sTSV_DeleteTask(u_taskhandle_##task) +#define iDeleteTask(task) sPSV_DeleteTask(u_taskhandle_##task) +#define pDeleteTask(task) sPS2_DeleteTask(u_taskhandle_##task) + +/* 设置任务优先级 */ +#define tSetTaskPri(task, pri) sTSV_SetTaskPri(u_taskhandle_##task, pri) +#define iSetTaskPri(task, pri) sPSV_SetTaskPri(u_taskhandle_##task, pri) +#define pSetTaskPri(task, pri) sPS2_SetTaskPri(u_taskhandle_##task, pri) + +/* 清除阻塞(状态)*/ +#define tClearBlock(task) sTSV_ClearBlock(u_taskhandle_##task) +#define iClearBlock(task) sPSV_ClearBlock(u_taskhandle_##task) +#define pClearBlock(task) sPS2_ClearBlock(u_taskhandle_##task) + +/* 设置阻塞-滴答周期 */ +#define tSetBlock_tc(task, tc) sTSV_SetBlock(u_taskhandle_##task, tc) +#define iSetBlock_tc(task, tc) sPSV_SetBlock(u_taskhandle_##task, tc) +#define pSetBlock_tc(task, tc) sPS2_SetBlock(u_taskhandle_##task, tc) + +/* 设置阻塞-毫秒 */ +#define tSetBlock_ms(task, ms) tSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) +#define iSetBlock_ms(task, ms) iSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) +#define pSetBlock_ms(task, ms) pSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/* 设置阻塞-秒钟 */ +#define tSetBlock_s(task, s) tSetBlock_ms(task, 1000UL * (s)) +#define iSetBlock_s(task, s) iSetBlock_ms(task, 1000UL * (s)) +#define pSetBlock_s(task, s) pSetBlock_ms(task, 1000UL * (s)) + +/* 设置阻塞-分钟 */ +#define tSetBlock_m(task, m) tSetBlock_s(task, 60UL * (m)) +#define iSetBlock_m(task, m) iSetBlock_s(task, 60UL * (m)) +#define pSetBlock_m(task, m) pSetBlock_s(task, 60UL * (m)) + +/* 设置阻塞-小时 */ +#define tSetBlock_h(task, h) tSetBlock_m(task, 60UL * (h)) +#define iSetBlock_h(task, h) iSetBlock_m(task, 60UL * (h)) +#define pSetBlock_h(task, h) pSetBlock_m(task, 60UL * (h)) + +/* 定时中断-滴答周期 */ +#define tTimInt_tc(tmid, tc) sTSV_TimInt(tmid, tc) +#define iTimInt_tc(tmid, tc) sPSV_TimInt(tmid, tc) + +/* 定时中断-毫秒 */ +#define tTimInt_ms(tmid, ms) tTimInt_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) +#define iTimInt_ms(tmid, ms) iTimInt_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/* 定时中断-秒钟 */ +#define tTimInt_s(tmid, s) tTimInt_ms(tmid, 1000UL * (s)) +#define iTimInt_s(tmid, s) iTimInt_ms(tmid, 1000UL * (s)) + +/* 定时中断-分钟 */ +#define tTimInt_m(tmid, m) tTimInt_s(tmid, 60UL * (m)) +#define iTimInt_m(tmid, m) iTimInt_s(tmid, 60UL * (m)) + +/* 定时中断-小时 */ +#define tTimInt_h(tmid, h) tTimInt_m(tmid, 60UL * (h)) +#define iTimInt_h(tmid, h) iTimInt_m(tmid, 60UL * (h)) + +/* 终止定时中断 */ +#define tTimInt_Cancel(tmid) tTimInt_tc(tmid, 0) +#define iTimInt_Cancel(tmid) iTimInt_tc(tmid, 0) + +/* 定时查询-滴答周期 */ +#define tTimQry_tc(tmid, tc) sTSV_TimQry(tmid, tc) +#define iTimQry_tc(tmid, tc) sPSV_TimQry(tmid, tc) + +/* 定时查询-毫秒 */ +#define tTimQry_ms(tmid, ms) tTimQry_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) +#define iTimQry_ms(tmid, ms) iTimQry_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE) + +/* 定时查询-秒钟 */ +#define tTimQry_s(tmid, s) tTimQry_ms(tmid, 1000UL * (s)) +#define iTimQry_s(tmid, s) iTimQry_ms(tmid, 1000UL * (s)) + +/* 定时查询-分钟 */ +#define tTimQry_m(tmid, m) tTimQry_s(tmid, 60UL * (m)) +#define iTimQry_m(tmid, m) iTimQry_s(tmid, 60UL * (m)) + +/* 定时查询-小时 */ +#define tTimQry_h(tmid, h) tTimQry_m(tmid, 60UL * (h)) +#define iTimQry_h(tmid, h) iTimQry_m(tmid, 60UL * (h)) + +/* 终止定时查询 */ +#define tTimQry_Cancel(tmid) tTimQry_tc(tmid, ~0) +#define iTimQry_Cancel(tmid) iTimQry_tc(tmid, ~0) + +/* 上锁二值信号量 */ +#define tLockBin(bin) bin.binary = false +#define iLockBin(bin) sPSV_WriteBin(bin, false) +#define pLockBin(bin) sPS2_WriteBin(bin, false) + +/* 给予二值信号量 */ +#define tGiveBin(bin) bin.binary = true +#define iGiveBin(bin) sPSV_WriteBin(bin, true) +#define pGiveBin(bin) sPS2_WriteBin(bin, true) + +/* 获取二值信号量 */ +#define tTakeBin(bin) sTSV_TakeBin(bin) +#define iTakeBin(bin) sISV_TakeBin(bin) + +/* 归还二值信号量 */ +#define tBackBin(bin) bin.binary = true +#define iBackBin(bin) \ +do{ \ + bin.binary = true; \ + iGiveBin(bin); \ +}while(false) + +/* 给予计数信号量 */ +#define tGiveSem(sem) sTSV_GiveSem(sem) +#define iGiveSem(sem) sPSV_GiveSem(sem) + +/* 获取计数信号量 */ +#define tTakeSem(sem) sTSV_TakeSem(sem) + +/* 归还计数信号量 */ +#define tBackSem(sem) tGiveSem(sem) + +/* 发送私信 */ +#define tSendTaskMsg(task) sTSV_SendTaskMsg(task) + +/* 接收飞信 */ +#define tRecvFetion(tbox) sTSV_RecvFetion(tbox) +#define iRecvFetion(tbox) sISV_RecvFetion(tbox) + +/* 发送飞信 */ +#define tSendFetion(tbox, tion) tbox.fetion = tion +#define iSendFetion(tbox, tion) sPSV_SendFetion(tbox, tion) + +/* 接收邮件 */ +#define tRecvMail(mbox) sTSV_RecvMail(mbox) +#define iRecvMail(mbox) sISV_RecvMail(mbox) + +/* 发送邮件 */ +#define tSendMail(mbox, mail) sTSV_SendMail(mbox, mail) +#define iSendMail(mbox, mail) sPSV_SendMail(mbox, mail) + +/* 接收消息 */ +#define tRecvMsg(que) sTSV_RecvMsg(que) +#define iRecvMsg(que) sISV_RecvMsg(que) + +/* 发送消息 */ +#define tSendMsg(que, msg) sTSV_SendMsg(que, msg) +#define iSendMsg(que, msg) sPSV_SendMsg(que, msg) + +/* 查询标志组 */ +#define tQueryFlagGroup(group) sTSV_QueryFlagGroup(group) +#define iQueryFlagGroup(group) sISV_QueryFlagGroup(group) + +/* 清除标志组 */ +#define tClearFlagGroup(group) sTSV_ClearFlagGroup(group) +#define iClearFlagGroup(group) sPSV_ClearFlagGroup(group) + +/* 设置标志位 */ +#define iSetFlagBit(group, bit) iSetFlagBits(group, 1) bit) + +/* 清除标志位 */ +#define iClearFlagBit(group, bit) iClearFlagBits(group, 1) bit) + +/* 获取时间 */ +#define tGetTime(t) sTSV_GetTime(t) +#define iGetTime(t) sISV_GetTime(t) + +/* 设置时间 */ +#define tSetTime(t) sTSV_SetTime(t) +#define iSetTime(t) sPSV_SetTime(t) + +/* 别名定义(API简化)*/ +#define uRecvTM uRecvTaskMsg +#define uSendTM uSendTaskMsg +#define tSendTM tSendTaskMsg +#define uRecvFet uRecvFetion +#define tRecvFet tRecvFetion +#define iRecvFet iRecvFetion +#define uSendFet uSendFetion +#define tSendFet tSendFetion +#define iSendFet iSendFetion + + + +#endif