Files
cosyos/System/ur_api.h
零中断延迟的RTOS 7d8fa7f232 update 内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2026-02-03 07:05:55 +00:00

1968 lines
66 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**************************************************************************//**
* @item CosyOS-III Kernel
* @file ur_api.h
* @brief 用户API
* @details 用户API定义含注释说明所有内核服务的API说明均在此文件中并支持doxygen。
* @author 迟凯峰
* @version V2.3.0
* @date 2026.02.01
******************************************************************************/
#ifndef __UR_API_H
#define __UR_API_H
#include "os_redef.h"
/**
\page CosyOS_API_DESCRIBE 概述API说明
用户通过调用API来实现对系统服务的调用所有API均为宏定义所有API参数均支持宏定义。
<br>
\li <strong>API分类</strong>
\li 创建API<br>
静态创建前缀为“u”分为 声明对象uExtern、创建对象uCreate、定义对象uDef。<br>
动态创建前缀为“d”分为 声明对象dExtern、创建对象dCreate
\li 任务API<br>
前缀为“u”指仅在 任务 中调用。
\li 滴答API<br>
前缀为“t”指仅在 SysTick中断 中调用,包括在 滴答钩子tick_hook、<br>
定时中断钩子u_timint_##tmid、定时查询钩子u_timqry_##tmid、<br>
定时查询事件u_timqryevent_##tmid中调用。
\li PSVAPI<br>
前缀为“p”指仅在 PendSV中断 中调用包括通过挂起服务调用iPendSVC间接调用、<br>
在挂起服务钩子pendsv_hook中调用。
\li 中断API<br>
前缀为“i”指仅在 用户中断 中调用,包括 中断本地服务、中断挂起服务_FIFO。
\li 公共API<br>
前缀为“x”指可在 任意处 调用。
<br>
\li <strong>API返回</strong>
\li 无返回<br>
1服务的执行结果一定是成功的所以不需要返回。<br>
2所有中断挂起服务_FIFO均无法直接返回但其中的部分服务允许支持错误调用返回。
\li 返回错误码<br>
服务的执行结果可能会失败,导致失败的原因可能有多个。<br>
1无错误。<br>
2由于结果已经成功导致本次并未执行。<br>
3失败。
\li 返回结果<br>
服务的执行结果可能会失败,但导致失败的原因是唯一的。<br>
执行结果为 bool 类型true 为成功false 为失败。
\li 返回指针<br>
返回一个指针,(void *) 类型NULL 为失败。
\li 返回值<br>
返回一个数值特定的数据类型0 为失败。
<br>
\li <strong>名词解释</strong>
\li 无限阻塞<br>
阻塞时间为无限长。
\li 无限等待<br>
超时时间为无限长。
\li 无限延时<br>
延时时间为无限长。
\li 无限同步<br>
仅同步一次,事件处理线程便可不限次数的周期运行处理事件。<br>
仅二值信号量支持该功能,可通过上锁的方式来终止无限同步。
<br>
*/
/**
\defgroup CosyOS_用户API
@{
*/
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 构建系统
\brief 系统构建相关服务。
@{
*/
/**
\brief 启动-CosyOS
\param 无
\return 错误码
\note 用户应自主创建main函数并在其末尾处调用该函数来启动-CosyOS<br>
在正常情况下,该函数并不会返回,而是直接调度至 Starter 运行;<br>
只有在 Sysidle / Starter 启动失败时,才会返回错误码提示用户。
*/
s_ecode_t uStartCosyOS(void);
/**
\brief CosyOS-滴答
\param 无
\return 无
\note 对于Arm用户来说您应自主创建 SysTick_Handler(),并在其中调用该服务。
\warning 对于51/251用户来说系统滴答中断固定采用定时器0中断并由CosyOS托管<br>
您应屏蔽掉工程中原有的定时器0中断函数以避免冲突。
*/
void tCosyTick_Handler(void);
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 任务
\brief 任务线程的声明、创建、启动,及操作。
@{
*/
/**
\ingroup 任务
\defgroup 声明任务
\brief 任务线程的声明
\note 首先声明任务不一定是必须的当仅在一个c文件中启动、操作任务时时常并不需要声明。
\note 在声明任务时通常无论是在h文件中声明还是在c文件中声明都应采用完整声明方式<br>
只有在编译器发出警告,与该任务相关的全局变量未引用时,再考虑简化声明方式。<br>
通常这种情况并不会发生典型的是在使用GCC(GNU)编译器时,可能偶尔会出现这种警告。
@{
*/
/**
\brief 简化声明静态一般任务
\param[in] task 任务名称
\return 无
*/
#define uExtTask(task) sCSV_ExtTask(task)(void)
/**
\brief 简化声明动态一般任务
\param[in] task 任务名称
\return 无
*/
#define dExtTask(task) dCSV_ExtTask(task)(void)
/**
\brief 完整声明静态一般任务
\param[in] task 任务名称
\return 无
*/
#define uExternTask(task) sCSV_ExternTask(task)(void)
/**
\brief 完整声明动态一般任务
\param[in] task 任务名称
\return 无
*/
#define dExternTask(task) dCSV_ExternTask(task)(void)
/**
\brief 简化声明静态私信任务
\param[in] task 任务名称
\param[in] add(...) 附加私信形参
\return 无
*/
#define uExtTaskmsg(task) sCSV_ExtTask(task)
/**
\brief 简化声明动态私信任务
\param[in] task 任务名称
\param[in] add(...) 附加私信形参
\return 无
*/
#define dExtTaskmsg(task) dCSV_ExtTask(task)
/**
\brief 完整声明静态私信任务
\param[in] task 任务名称
\param[in] add(...) 附加私信形参
\return 无
*/
#define uExternTaskmsg(task) sCSV_ExternTask(task)
/**
\brief 完整声明动态私信任务
\param[in] task 任务名称
\param[in] add(...) 附加私信形参
\return 无
*/
#define dExternTaskmsg(task) dCSV_ExternTask(task)
/** @} */
/**
\ingroup 任务
\defgroup 创建任务
\brief 任务线程的创建
@{
*/
/**
\brief 静态创建一般任务
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define uCreateTask(task, pri, tss, srt, res) \
sCSV_CreateTask(task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/**
\brief 动态创建一般任务
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define dCreateTask(task, pri, tss, srt, res) \
dCSV_CreateTask(task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/**
\brief 静态创建私信任务
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] ntm 私信参数数量1~8 个)
\param[in] add(...) 附加私信形参<br>
形参类型:任意数据类型<br>
形参名称:必须依次为 tm1、tm2...<br>
示 例:(int tm1, float tm2, char *tm3)
\param[in] add{...} 附加任务代码
\return 无
*/
#define uCreateTaskmsg(task, pri, tss, srt, res, ntm) \
sCSV_CreateTaskmsg(task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res), ntm)
/**
\brief 动态创建私信任务
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] ntm 私信参数数量1~8 个)
\param[in] add(...) 附加私信形参<br>
形参类型:任意数据类型<br>
形参名称:必须依次为 tm1、tm2...<br>
示 例:(int tm1, float tm2, char *tm3)
\param[in] add{...} 附加任务代码
\return 无
*/
#define dCreateTaskmsg(task, pri, tss, srt, res, ntm) \
dCSV_CreateTaskmsg(task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res), ntm)
/**
\brief 静态创建定时中断任务
\param[in] tmid 定时中断定时器ID
\param[in] arl 自动重装载
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define uCreateTask_TimInt(tmid, arl, task, pri, tss, srt, res) \
sCSV_CreateTask_TimInt(tmid, arl, task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/**
\brief 动态创建定时中断任务
\param[in] tmid 定时中断定时器ID
\param[in] arl 自动重装载
\param[in] task 任务名称
\param[in] pri 任务优先级
\param[in] tss 任务栈大小(单位为字节)
\param[in] srt 安全运行时单位为滴答周期0为无限长
\param[in] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define dCreateTask_TimInt(tmid, arl, task, pri, tss, srt, res) \
dCSV_CreateTask_TimInt(tmid, arl, task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/**
\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] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define uCreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, res) \
sCSV_CreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/**
\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] res 任务名称文本
\param[in] add{...} 附加任务代码
\return 无
*/
#define dCreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, res) \
dCSV_CreateTask_TimQry(tmid, event, arl, task, pri, tss, srt, SYSCFG_CREATETASKCUSTOM(task, res))
/** @} */
/**
\ingroup 任务
\defgroup 启动任务
\brief 任务线程的启动。任务只有在启动以后,才能加入到任务队列参与调度并运行。
\warning 所有定时中断任务和定时查询任务均由操作系统自动启动,用户不要启动。
\warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
@{
*/
/**
\brief 启动任务
\details 启动任务并置任务的初始状态为设定状态。
\param[in] task 任务名称
\param[in] status 任务初始状态<br>
就绪状态OS_STATUS_READY<br>
阻塞状态OS_STATUS_BLOCKED阻塞类型为延时阻塞延时时间为无限长。<br>
挂起状态OS_STATUS_SUSPENDED先前状态为就绪状态。
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出
\retval OS_ECODE_MALLOCFAIL_TASKNODE 任务节点内存分配失败
\retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败
*/
#if (SYSCFG_TASKMSG == __ENABLED__)
#define uStartTask(task, status) \
sUSV_StartTask_1(&sCat2Str(u_taskhand_, task), status, sCat2Str(u_task_, task))
#else
#define uStartTask(task, status) \
sUSV_StartTask_0(&sCat2Str(u_taskhand_, task), status)
#endif
/**
\brief 启动任务并就绪
\details 启动任务并置任务的初始状态为就绪状态。
\param[in] task 任务名称
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出
\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_MALLOCFAIL_TASKNODE 任务节点内存分配失败
\retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败
*/
#define uStartTask_Block(task) \
uStartTask(task, OS_STATUS_BLOCKED)
/**
\brief 启动任务并挂起
\details 启动任务并置任务的初始状态为挂起状态(先前状态为就绪状态)。
\param[in] task 任务名称
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_OVERFLOW_TASKSTACK 任务栈溢出
\retval OS_ECODE_MALLOCFAIL_TASKNODE 任务节点内存分配失败
\retval OS_ECODE_MALLOCFAIL_TASKSTACK 任务栈内存分配失败
*/
#define uStartTask_Suspend(task) \
uStartTask(task, OS_STATUS_SUSPENDED)
/** @} */
/**
\ingroup 任务
\defgroup 操作任务
\brief 对任意任务的操作,如 恢复、挂起、删除、设置优先级 等。
@{
*/
/**
\brief 清除就绪延时
\details 清除当前任务的就绪延时,前提是当前任务已在就绪延时中。
\param 无
\return 无
\note 同型服务:<br>
pClearDelay()。<br>
iClearDelay()。
*/
#define tClearDelay() sTSV_ClearDelay()
/**
\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 同型服务:<br>
tResumeTask(task),同返回。<br>
pResumeTask(task),同返回。<br>
iResumeTask(task),无返回/错误调用返回。
*/
#define uResumeTask(task) sUSV_ResumeTask(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 同型服务:<br>
tSuspendTask(task),同返回。<br>
pSuspendTask(task),同返回。<br>
iSuspendTask(task),无返回/错误调用返回。
*/
#define uSuspendTask(task) sUSV_SuspendTask(task)
/**
\brief 删除任务
\param[in] task 任务名称
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tDeleteTask(task),同返回。<br>
pDeleteTask(task),同返回。<br>
iDeleteTask(task),无返回/错误调用返回。
*/
#define uDeleteTask(task) sUSV_DeleteTask(task)
/**
\brief 设置任务优先级
\param[in] task 任务名称
\param[in] npri 新优先级
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKPRIUNCHANGED 任务优先级未改变
\retval OS_ECODE_TASKSTOPPED 任务已停止
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetTaskPri(task, npri),同返回。<br>
pSetTaskPri(task, npri),同返回。<br>
iSetTaskPri(task, npri),无返回/错误调用返回。
*/
#define uSetTaskPri(task, npri) sUSV_SetTaskPri(task, npri)
/**
\brief 清除阻塞(状态)
\details 清除指定任务的阻塞状态并使其就绪。
\param[in] task 任务名称
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tClearBlock(task),同返回。<br>
pClearBlock(task),同返回。<br>
iClearBlock(task),无返回/错误调用返回。
*/
#define uClearBlock(task) sUSV_ClearBlock(task)
/**
\ingroup 操作任务
\defgroup 设置阻塞(时间)
\brief 设置、修改指定任务的阻塞时间,前提是该任务当前已为阻塞状态。
\note 理想误差:-1tick。
\warning 按 毫秒、秒钟、分钟、小时 设置,用户需自己保证时间的有效性(可被系统滴答周期整除)。
\warning 无限阻塞,仅能通过调用 xSetBlock_tc(task, ~0) 来实现。
@{
*/
/**
\brief 设置阻塞-滴答周期
\param[in] task 任务名称
\param[in] tc 滴答周期(阻塞时间)<br>
+0清除阻塞<br>
~0无限阻塞
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetBlock_tc(task, tc),同返回。<br>
pSetBlock_tc(task, tc),同返回。<br>
iSetBlock_tc(task, tc),无返回/错误调用返回。
*/
#define uSetBlock_tc(task, tc) sUSV_SetBlock(task, tc)
/**
\brief 设置阻塞-毫秒
\param[in] task 任务名称
\param[in] ms 毫秒(阻塞时间)<br>
0清除阻塞
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetBlock_ms(task, ms),同返回。<br>
pSetBlock_ms(task, ms),同返回。<br>
iSetBlock_ms(task, ms),无返回/错误调用返回。
*/
#define uSetBlock_ms(task, ms) uSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE)
/**
\brief 设置阻塞-秒钟
\param[in] task 任务名称
\param[in] s 秒钟(阻塞时间)<br>
0清除阻塞
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetBlock_s(task, s),同返回。<br>
pSetBlock_s(task, s),同返回。<br>
iSetBlock_s(task, s),无返回/错误调用返回。
*/
#define uSetBlock_s(task, s) uSetBlock_ms(task, 1000UL * (s))
/**
\brief 设置阻塞-分钟
\param[in] task 任务名称
\param[in] m 分钟(阻塞时间)<br>
0清除阻塞
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetBlock_m(task, m),同返回。<br>
pSetBlock_m(task, m),同返回。<br>
iSetBlock_m(task, m),无返回/错误调用返回。
*/
#define uSetBlock_m(task, m) uSetBlock_s(task, 60UL * (m))
/**
\brief 设置阻塞-小时
\param[in] task 任务名称
\param[in] h 小时(阻塞时间)<br>
0清除阻塞
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞
\retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除
\note 同型服务:<br>
tSetBlock_h(task, h),同返回。<br>
pSetBlock_h(task, h),同返回。<br>
iSetBlock_h(task, h),无返回/错误调用返回。
*/
#define uSetBlock_h(task, h) uSetBlock_m(task, 60UL * (h))
/** @} */
/** @} */
/**
\ingroup 任务
\defgroup 操作自身任务
\brief 仅适用于对自身任务的操作
@{
*/
/**
\brief 禅让任务
\details 自身任务主动禅让CPU使用权轮转至下一个相同优先级的任务运行。
\param 无
\return 无
\note 多个相同优先级的任务,通过禅让的方式可实现合作式任务。
\note 禅让是自身任务主动时间片到期,禅让后任务仍为就绪状态。
\warning 当开启相同优先级任务的时间片轮转调度时,才支持此服务。
*/
#define uYieldTasking() su_yield_tasking()
/**
\brief 设置自身任务优先级
\param[in] npri 新优先级
\return 错误码s_ecode_t
\retval OS_ECODE_NOERROR 无错误
\retval OS_ECODE_TPLUNCHANGED 优先级未改变
*/
#define uSetTaskingPri(npri) sUSV_SetTaskPri(s_task_current, npri)
/**
\brief 挂起自身任务
\param 无
\return 错误码s_ecode_t
\note 虽然也返回错误码,但在正常情况下结果一定是成功的,不必查看错误码。
*/
#define uSuspendTasking() sUSV_SuspendTask(s_task_current)
/**
\brief 删除自身任务
\param 无
\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(task)
/**
\ingroup 操作自身任务
\defgroup 自身任务延时
\brief 自身任务延时分为阻塞延时和就绪延时。
\note 阻塞延时在延时期间任务会进入阻塞状态把CPU使用权转让给其它任务。
\note 就绪延时在延时期间任务会维持就绪状态原地等待延时时间到达不转让CPU使用权。
\note 当在任务临界区中,自动选择为就绪延时,否则选择为阻塞延时。
\note 理想误差:-1tick。
\warning 按 毫秒、秒钟、分钟、小时 延时,用户需自己保证时间的有效性(可被系统滴答周期整除)。
\warning 无限延时,仅能通过调用 uDelay_tc(~0) 来实现。
\warning 不支持在服务层临界区、全局临界区,或关闭总中断时调用。
@{
*/
/**
\brief 延时-滴答周期
\param[in] tc 滴答周期(延时时间)<br>
~0无限延时
\return 无
*/
#define uDelay_tc(tc) sUSV_Delay(tc)
/**
\brief 延时-毫秒
\param[in] ms 毫秒(延时时间)
\return 无
*/
#define uDelay_ms(ms) uDelay_tc((1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE)
/**
\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 由用户定时操作,当定时器溢出时,系统将自动恢复/调用与其绑定的任务/钩子并可自动重复定时。
\note 理想误差:-1tick。
\warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。
@{
*/
/**
\brief 创建定时中断钩子
\param[in] tmid 定时器ID
\param[in] arl 自动重装载设置<br>
0关闭自动重装载<br>
1开启自动重装载
\param[in] add{...} 附加钩子代码
\return 无
*/
#define uCreateHook_TimInt(tmid, arl) \
sCSV_CreateHook_TimInt(tmid, arl)
/**
\brief 定时中断-滴答周期
\param[in] tmid 定时中断定时器ID
\param[in] tc 滴答周期(定时时间)
\return 无
\note 同型服务:<br>
tTimInt_tc(tmid, tc)。<br>
iTimInt_tc(tmid, tc)。
*/
#define uTimInt_tc(tmid, tc) sUSV_TimInt(tmid, tc)
/**
\brief 定时中断-毫秒
\param[in] tmid 定时中断定时器ID
\param[in] ms 毫秒(定时时间)
\return 无
\note 同型服务:<br>
tTimInt_ms(tmid, ms)。<br>
iTimInt_ms(tmid, ms)。
*/
#define uTimInt_ms(tmid, ms) uTimInt_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE)
/**
\brief 定时中断-秒钟
\param[in] tmid 定时中断定时器ID
\param[in] s 秒钟(定时时间)
\return 无
\note 同型服务:<br>
tTimInt_s(tmid, s)。<br>
iTimInt_s(tmid, s)。
*/
#define uTimInt_s(tmid, s) uTimInt_ms(tmid, 1000UL * (s))
/**
\brief 定时中断-分钟
\param[in] tmid 定时中断定时器ID
\param[in] m 分钟(定时时间)
\return 无
\note 同型服务:<br>
tTimInt_m(tmid, m)。<br>
iTimInt_m(tmid, m)。
*/
#define uTimInt_m(tmid, m) uTimInt_s(tmid, 60UL * (m))
/**
\brief 定时中断-小时
\param[in] tmid 定时中断定时器ID
\param[in] h 小时(定时时间)
\return 无
\note 同型服务:<br>
tTimInt_h(tmid, h)。<br>
iTimInt_h(tmid, h)。
*/
#define uTimInt_h(tmid, h) uTimInt_m(tmid, 60UL * (h))
/**
\brief 终止定时中断
\param[in] tmid 定时中断定时器ID
\return 无
\note 同型服务:<br>
tTimInt_Cancel(tmid)。<br>
iTimInt_Cancel(tmid)。
*/
#define uTimInt_Cancel(tmid) uTimInt_tc(tmid, 0)
/**
\brief 定时中断定时器自动重装载
\param[in] tmid 定时中断定时器ID
\param[in] arl 自动重装载设置<br>
0关闭自动重装载<br>
1开启自动重装载
\return 无
*/
#define xTimInt_AutoReload(tmid, arl) s_timint_autoreload[tmid] = arl
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 定时查询
\brief 由用户定时操作,当定时器溢出后,系统在每个滴答周期都会查询用户定义的事件,
若事件为真,系统将自动恢复/调用与其绑定的任务/钩子并可自动重复定时。
\note 理想误差:-1tick。
\warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。
@{
*/
/**
\brief 创建定时查询钩子
\param[in] tmid 定时器ID
\param[in] event 定时查询事件
\param[in] arl 自动重装载设置<br>
0关闭自动重装载<br>
1开启自动重装载
\param[in] add{...} 附加钩子代码
\return 无
*/
#define uCreateHook_TimQry(tmid, event, arl) \
sCSV_CreateHook_TimQry(tmid, event, arl)
/**
\brief 定时查询-滴答周期
\param[in] tmid 定时查询定时器ID
\param[in] tc 滴答周期(定时时间)
\return 无
\note 同型服务:<br>
tTimQry_tc(tmid, tc)。<br>
iTimQry_tc(tmid, tc)。
*/
#define uTimQry_tc(tmid, tc) sUSV_TimQry(tmid, tc)
/**
\brief 定时查询-毫秒
\param[in] tmid 定时查询定时器ID
\param[in] ms 毫秒(定时时间)
\return 无
\note 同型服务:<br>
tTimQry_ms(tmid, ms)。<br>
iTimQry_ms(tmid, ms)。
*/
#define uTimQry_ms(tmid, ms) uTimQry_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE)
/**
\brief 定时查询-秒钟
\param[in] tmid 定时查询定时器ID
\param[in] s 秒钟(定时时间)
\return 无
\note 同型服务:<br>
tTimQry_s(tmid, s)。<br>
iTimQry_s(tmid, s)。
*/
#define uTimQry_s(tmid, s) uTimQry_ms(tmid, 1000UL * (s))
/**
\brief 定时查询-分钟
\param[in] tmid 定时查询定时器ID
\param[in] m 分钟(定时时间)
\return 无
\note 同型服务:<br>
tTimQry_m(tmid, m)。<br>
iTimQry_m(tmid, m)。
*/
#define uTimQry_m(tmid, m) uTimQry_s(tmid, 60UL * (m))
/**
\brief 定时查询-小时
\param[in] tmid 定时查询定时器ID
\param[in] h 小时(定时时间)
\return 无
\note 同型服务:<br>
tTimQry_h(tmid, h)。<br>
iTimQry_h(tmid, h)。
*/
#define uTimQry_h(tmid, h) uTimQry_m(tmid, 60UL * (h))
/**
\brief 终止定时查询
\param[in] tmid 定时查询定时器ID
\return 无
\note 同型服务:<br>
tTimQry_Cancel(tmid)。<br>
iTimQry_Cancel(tmid)。
*/
#define uTimQry_Cancel(tmid) uTimQry_tc(tmid, ~0)
/**
\brief 定时查询定时器自动重装载
\param[in] tmid 定时查询定时器ID
\param[in] arl 自动重装载设置<br>
0关闭自动重装载<br>
1开启自动重装载
\return 无
*/
#define xTimQry_AutoReload(tmid, arl) s_timqry_autoreload[tmid] = arl
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 互斥信号量
\brief 仅适用于在任务中对任务级公共资源的互斥访问。
\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 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\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 CosyOS_用户API
\defgroup 二值信号量
\brief 常用于事件同步、互斥访问(中断与任务之间的互斥)。
@{
*/
/**
\brief 声明二值信号量
\param[in] bin 二值信号量名称
\return 无
*/
#define uExternBin(bin) sCSV_ExternBin(bin)
/**
\brief 创建二值信号量
\param[in] bin 二值信号量名称
\param[in] init 二值信号量初始值<br>
false0已上锁无法立即成功获取<br>
true1 :已解锁,可以立即成功获取
\return 无
\note 当用于互斥访问时初始值应为true。
*/
#define uCreateBin(bin, init) sCSV_CreateBin(bin, init)
/**
\brief 上锁二值信号量
\details 用于终止线程的无限同步。
\param[in] bin 二值信号量名称
\return 无
\note 同型服务:<br>
tLockBin(bin)。<br>
pLockBin(bin)。<br>
iLockBin(bin)。
*/
#define uLockBin(bin) bin.binary = false
/**
\brief 等待二值信号量
\details 在指定的超时时间内等待二值信号量为真,适用于任务的无限同步,与获取的区别是不上锁。
\param[in] bin 二值信号量名称
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\retval false 失败
\retval true 成功
\warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uWaitBin(bin, tc) sUSV_WaitBin(bin, tc)
/**
\brief 给予二值信号量
\details 专用于事件同步。
\param[in] bin 二值信号量名称
\return 无
\note 同型服务:<br>
tGiveBin(bin)。<br>
pGiveBin(bin)。<br>
iGiveBin(bin)。
*/
#define uGiveBin(bin) sUSV_GiveBin(bin)
/**
\brief 获取二值信号量
\details 用于事件同步或互斥访问。
\param[in] bin 二值信号量名称
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\retval false 失败
\retval true 成功
\note 同型服务:<br>
tTakeBin(bin)。<br>
iTakeBin(bin)。
\warning 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uTakeBin(bin, tc) sUSV_TakeBin(bin, tc)
/**
\brief 归还二值信号量
\details 专用于互斥访问。
\param[in] bin 二值信号量名称
\return 无
\note 同型服务:<br>
tBackBin(bin)。<br>
iBackBin(bin)。
*/
#define uBackBin(bin) uGiveBin(bin)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\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 同型服务:<br>
tGiveSem(sem)。<br>
iGiveSem(sem)。
*/
#define uGiveSem(sem) sUSV_GiveSem(sem)
/**
\brief 获取计数信号量
\param[in] sem 计数信号量名称
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\retval false 失败
\retval true 成功
\note 同型服务:<br>
tTakeSem(sem)。
\warning 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uTakeSem(sem, tc) sUSV_TakeSem(sem, tc)
/**
\brief 归还计数信号量
\param[in] sem 计数信号量名称
\return 无
\note 同型服务:<br>
tBackSem(sem)。
*/
#define uBackSem(sem) uGiveSem(sem)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 事件标志组
\brief 适用于对一类事件的事件同步。
\details 某一类事件,它的发生线程可能会有多个,均同步至同一个事件处理线程中统一处理该类事件。
\note 名词解释<br>
组名:标志组的名称<br>
位名:标志位的名称<br>
空位:空标志位<br>
\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 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\retval false 失败
\retval true 成功
\warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
\warning 事件的各个发生线程中设置标志位后,应调用 uClearBlock(task) 来手动完成事件同步。
*/
#define uWaitFlagGroup(group, tc) sUSV_WaitFlagGroup(group, tc)
/**
\brief 查询标志组
\param[in] group 组名
\return 结果bool
\retval false 失败
\retval true 成功
\note 同型服务:<br>
tQueryFlagGroup(group)。<br>
iQueryFlagGroup(group)。
*/
#define uQueryFlagGroup(group) sUSV_QueryFlagGroup(group)
/**
\brief 清除标志组
\param[in] group 组名
\return 无
\note 同型服务:<br>
tClearFlagGroup(group)。<br>
iClearFlagGroup(group)。
*/
#define uClearFlagGroup(group) sUSV_ClearFlagGroup(group)
/**
\brief 设置标志位
\param[in] group 组名
\param[in] bit 位名
\return 无
\note 同型服务:<br>
tSetFlagBit(group, bit)。<br>
iSetFlagBit(group, bit)。
*/
#define uSetFlagBit(group, bit) uSetFlagBits(group, 1) bit)
/**
\brief 清除标志位
\param[in] group 组名
\param[in] bit 位名
\return 无
\note 同型服务:<br>
tClearFlagBit(group, bit)。<br>
iClearFlagBit(group, bit)。
*/
#define uClearFlagBit(group, bit) uClearFlagBits(group, 1) bit)
/**
\brief 设置多标志位
\param[in] group 组名
\param[in] nbit 标志位的数量
\param[in] add...) 各位名,逗号间隔
\return 无
\note 同型服务:<br>
tSetFlagBits(group, nbit)。<br>
iSetFlagBits(group, nbit)。
*/
#define uSetFlagBits(group, nbit) sUSV_WriteFlagBits(group, true, nbit)
/**
\brief 清除多标志位
\param[in] group 组名
\param[in] nbit 标志位的数量
\param[in] add...) 各位名,逗号间隔
\return 无
\note 同型服务:<br>
tClearFlagBits(group, nbit)。<br>
iClearFlagBits(group, nbit)。
*/
#define uClearFlagBits(group, nbit) sUSV_WriteFlagBits(group, false, nbit)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 私信
\brief 随意定义、灵活多变。
\details 私信是CosyOS独创的一种任务间通信方式其实质就是任务函数形参。
\note 私信参数说明:<br>
1、私信参数的数量支持1~8 个;<br>
2、各个参数的数据类型可为任意类型只要编译器支持即可<br>
3、各个参数的名称必须依次为tm1、tm2...,用户可自行宏定义别名提高易用性。
@{
*/
/**
\brief 接收私信<br>
<br>
<strong>别名</strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<strong>uRecvTM</strong>
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 结果bool
\retval false 失败
\retval true 成功
\warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uRecvTaskmsg(tc) sUSV_RecvTaskmsg(tc)
/**
\brief 发送私信<br>
<br>
<strong>别名</strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<strong>uSendTM</strong>
\param[in] task 任务名称
\param[in] add(...) 附加私信实参
\return 无
\note 同型服务:<br>
tSendTaskmsg(task) / <strong>tSendTM</strong>。
\warning 如果在条件分支内调用,分支语句的{}不可省略。
*/
#define uSendTaskmsg(task) sUSV_SendTaskmsg(task)
/**
\brief 结束私信任务
\details 私信任务的最后一句代码。
\return 无
*/
#define uEndTaskmsg() }while(true)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 飞信
\brief 原子类型、传输数据。
\details 仅使用一个变量,同时即是消息,又是新消息标志。<br>
飞信为0时表示无消息飞信非0时表示有消息<br>
因此:
\warning 用户传输的有效消息必须为真值。
\note 架构&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据类型<br>
8051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t<br>
80251&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16_t<br>
Arm32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32_t<br>
通用别名&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m_fetion_t<br>
@{
*/
/**
\brief 声明信箱
\param[in] tbox 信箱名称
\return 无
*/
#define uExternTionbox(tbox) sCSV_ExternTionbox(tbox)
/**
\brief 创建信箱
\param[in] tbox 信箱名称
\return 无
*/
#define uCreateTionbox(tbox) sCSV_CreateTionbox(tbox)
/**
\brief 接收飞信<br>
<br>
<strong>别名</strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<strong>uRecvFet</strong>
\param[in] tbox 信箱名称
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 飞信m_fetion_t
\retval false 无飞信
\note 同型服务:<br>
tRecvFetion(tbox) / <strong>tRecvFet</strong>。<br>
iRecvFetion(tbox) / <strong>iRecvFet</strong>。
\warning 任务中接收,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uRecvFetion(tbox, tc) sUSV_RecvFetion(tbox, tc)
/**
\brief 发送飞信<br>
<br>
<strong>别名</strong><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<strong>uSendFet</strong>
\param[in] tbox 信箱名称
\param[in] tion 飞信
\return 无
\note 同型服务:<br>
tSendFetion(tbox, tion) / <strong>tSendFet</strong>。<br>
iSendFetion(tbox, tion) / <strong>iSendFet</strong>。
*/
#define uSendFetion(tbox, tion) sUSV_SendFetion(tbox, tion)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 消息邮箱
\brief 任意类型、传输指针。
@{
*/
/**
\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 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 邮件指针void *
\retval NULL 无邮件
\note 同型服务:<br>
tRecvMail(mbox)。<br>
iRecvMail(mbox)。
\warning 任务中接收,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
*/
#define uRecvMail(mbox, tc) sUSV_RecvMail(mbox, tc)
/**
\brief 发送邮件
\param[in] mbox 邮箱名称
\param[in] mail 邮件指针
\return 无
\note 同型服务:<br>
tSendMail(mbox, mail)。<br>
iSendMail(mbox, mail)。
*/
#define uSendMail(mbox, mail) sUSV_SendMail(mbox, mail)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 消息队列
\brief 任意类型、传输指针,是唯一能够实现并发消息同步的手段。
\details 消息队列包括静态队列和动态队列。<br>
静态队列:收发消息的效率高,队列占用固定的内存;<br>
动态队列:收发消息的效率低,接收消息后,队列内存可被回收。
\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 传输模式<br>
0FIFO先入先出<br>
1LIFO后入先出
\param[in] len 队列长度
\return 无
*/
#define uCreateQueue_Static(que, mode, len) sCSV_CreateQueue_Static(que, mode, len)
/**
\brief 创建动态队列
\param[in] que 队列名称
\param[in] mode 传输模式<br>
0FIFO先入先出<br>
1LIFO后入先出
\param[in] len 队列长度
\return 无
*/
#define uCreateQueue_Dynamic(que, mode, len) sCSV_CreateQueue_Dynamic(que, mode, len)
/**
\brief 接收消息
\param[in] que 队列名称
\param[in] tc 滴答周期(超时时间)<br>
+0立即返回<br>
~0无限等待
\return 消息指针void *
\retval NULL 无消息
\note 同型服务:<br>
tRecvMsg(que)。<br>
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 同型服务:<br>
tSendMsg(que, msg),同返回。<br>
iSendMsg(que, msg),无返回/错误调用返回。
\warning 中断中发送,消息缓存只能是静态缓存。
*/
#define uSendMsg(que, msg) sUSV_SendMsg(que, msg)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 全局变量访问
\brief 由CosyOS内核提供服务支持可实现在任务、滴答、中断中对非原子型
全局变量的线程安全访问,同时不会破坏零中断延迟。
\note 全局的结构体、数组、字符串等,都可视为非原子型全局变量。
\note 原子型访问:<br>
滴答中:直接->读访问、写访问、自运算。<br>
任务中:直接->读访问、写访问,内核上锁后->自运算。<br>
中断中:直接->读访问,调用服务->写访问、自运算。
\note 非原子型访问:<br>
滴答中:直接->读访问、写访问、自运算。<br>
任务中:内核上锁后->读访问、写访问、自运算。<br>
中断中:不可以读访问,调用服务->写访问、自运算。
\note 不可以读访问:<br>
建议挂起到PendSV中或同步至某任务中处理事件。<br>
挂起到PendSV中iPendSVC(fp) 或 pendsv_hook(),均可直接->读访问;<br>
同步至某任务中:内核上锁后->读访问。
@{
*/
/**
\brief 写全局变量
\param[in] gv 全局变量名称
\param[in] lv 局部变量名称
\return 无
*/
#define iWriteGVar(gv, lv) sIPS_WriteGVar((void *)&gv, (void *)&lv, sizeof(gv))
/**
\brief 写全局数组
\param[in] gp 全局数组指针
\param[in] lp 局部数组指针
\param[in] size 拷贝的大小(字节数)
\return 无
*/
#define iWriteGAry(gp, lp, size) sIPS_WriteGVar(gp, lp, size)
/**
\brief 写全局字符串
\param[in] gs 全局字符串指针
\param[in] ls 局部字符串指针
\return 无
*/
#define iWriteGStr(gs, ls) sIPS_WriteGVar(gs, ls, 0)
/**
\brief 挂起服务调用
\param[in] fp 函数指针
\return 无
\note 适用于全局变量自运算、事件处理等。
*/
#define iPendSVC(fp) sIPS_PendSVC(fp)
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 软件RTC
\brief 适用于没有硬件RTC的物联网终端设备。
\note 实际应用中,可每间隔一段时间(如一小时)同步一次网络时间,以校正误差。
@{
*/
/**
\brief 获取时间
\param[in] t 本地时间的指针s_rtc_ts *
\return tvoid *
\note 同型服务:<br>
tGetTime(t)。
*/
#define uGetTime(t) sUSV_GetTime(t)
/**
\brief 设置时间
\param[in] t 本地时间的指针s_rtc_ts *
\return 无
\note 同型服务:<br>
tSetTime(t)。<br>
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模式时可考虑在线程的开始处创建。
\param 无
\return 无
*/
#define uCreateMempool() sCSV_CreateMempool()
/**
\brief 初始化线程内存池
\details 实质上是通过调用malloc从进程内存池或堆中分配一块内存来做为线程内存池。
\param[in] size 线程内存池的大小(字节数)
\return 结果bool
\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 释放线程内存池
\param 无
\return 无
*/
#define uFreeMempool() sUSV_FreeMempool()
/** @} */
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 临界区
\note CosyOS的临界区包括任务临界区、服务层临界区、全局临界区均支持嵌套使用。<br>
各临界区之间也可随意互相嵌套,但通常推荐在任务临界区中嵌套服务层临界区,<br>
在服务层临界区中嵌套全局临界区,以逐步扩大保护范围。
@{
*/
/**
\ingroup 临界区
\defgroup 调度锁(任务临界区)
\brief 通过上锁任务调度器的方式,来实现任务级的临界区保护,仅支持在任务中调用。
\note 仅是上锁任务调度器不关闭系统中断SysTick、PendSV所以即使是长时间的、<br>
对大段的任务级公共资源的独占访问,也不会影响系统节拍和内核服务的执行。
\note 调度锁支持嵌套使用最大嵌套深度255调度上锁与调度解锁必须配对使用。
\note 调度锁不会破坏零中断延迟,当需要任务级的临界区保护时,可以考虑。
@{
*/
/**
\brief 调度上锁(进入任务临界区)
\param 无
\return 无
*/
#define uScheduleLock() su_schedule_locks()
/**
\brief 调度解锁(退出任务临界区)
\param 无
\return 无
*/
#define uScheduleUnlock() su_schedule_unlocks()
/** @} */
/**
\ingroup 临界区
\defgroup 内核锁(服务层临界区)
\brief OS内核级的临界区保护会关闭系统中断SysTick、PendSV仅支持在任务中调用。
\note 由SysTick、PendSV、内核锁共同组成大的服务层临界区当处理得当时可实现全局的临界区保护。<br>
实现过程:<br>
滴答中:直接访问即可。<br>
任务中:内核上锁后访问。<br>
中断中:采用中断挂起服务。
\note 内核锁支持嵌套使用最大嵌套深度255内核上锁与内核解锁必须配对使用。
\note 内核锁不会破坏零中断延迟,当需要全局的临界区保护时,应首先予以考虑。
\note 内核锁应遵循快进快出的原则,临界段代码的执行时间应远小于系统滴答周期,<br>
否则可能会导致丢失系统节拍、延误其它内核服务的执行,对系统实时性造成不利影响。
\note 当在任务中访问非原子全局变量时,可采用内核锁实现全局的临界区保护。
@{
*/
/**
\brief 内核上锁(进入服务层临界区)
\param 无
\return 无
*/
#define uKernelLock() su_kernel_locks()
/**
\brief 内核解锁(退出服务层临界区)
\param 无
\return 无
*/
#define uKernelUnlock() su_kernel_unlocks()
/** @} */
/**
\ingroup 临界区
\defgroup 中断锁(全局临界区)
\brief 全局的临界区保护,通常会关闭总中断,支持在任意处调用。
\note CosyOS内核中从来不会关闭总中断提供此项服务只是为了便于用户<br>
对全局公共资源和程序过程的保护。
\note 全局临界区会破坏零中断延迟,应做为最后的选项,慎重使用。
@{
*/
#if (MCUCFG_ISA != __ARM__)
/**
\ingroup 全局临界区
\defgroup 操作-EA
\note 支持嵌套使用最大嵌套深度255进入临界区与退出临界区必须配对使用。
@{
*/
/**
\brief 进入全局临界区
\param 无
\return 无
*/
#define xDisableIRQ() mxDisableIRQ()
/**
\brief 退出全局临界区
\param 无
\return 无
*/
#define xResumeIRQ() mxResumeIRQ()
/** @} */
#else
/**
\ingroup 全局临界区
\defgroup 操作-PRIMASK
\note 支持嵌套使用,进入临界区与退出临界区必须配对使用。
@{
*/
/**
\brief 进入全局临界区
\param 无
\return oirq PRIMASK上一次的值uint32_t类型
*/
#define xDisableIRQ() mxDisableIRQ()
/**
\brief 退出全局临界区
\param[in] oirq PRIMASK上一次的值uint32_t类型
\return 无
*/
#define xResumeIRQ(oirq) mxResumeIRQ(oirq)
/** @} */
/**
\ingroup 全局临界区
\defgroup 操作-BASEPRI
\note 使用条件:<br>
1、MCU必须有 BASEPRI 寄存器;<br>
2、MCU配置中系统中断配置必须选择 TIMn_IRQHandler + XXX_IRQHandler。
\note 使用说明:<br>
1、关于npri例如中断优先级分组选择 NVIC_PriorityGoup_4那么中断优先级从高到低为 0~15。<br>
如果需要掩蔽3~15的中断npri应输入3。<br>
2、支持嵌套使用进入临界区与退出临界区必须配对使用。<br>
3、嵌套使用时仅能逐步扩大掩蔽范围npri越来越小否则新的掩蔽范围不会生效将维持上一次的掩蔽范围
@{
*/
/**
\brief 进入全局临界区
\param[in] npri 掩蔽范围的最高优先级的优先级号uint32_t类型
\return opri BASEPRI的原值uint32_t类型
*/
#define xMaskingPRI(npri) mxMaskingPRI(npri)
/**
\brief 退出全局临界区
\param[in] opri BASEPRI的原值uint32_t类型
\return 无
*/
#define xResumePRI(opri) mxResumePRI(opri)
/** @} */
#endif
/** @} */
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 杂项
@{
*/
/**
\ingroup 杂项
\defgroup 中断挂起服务_FIFO-错误调用返回
\note 当需要回调时,下列的回调函数可以在用户文件中实现。
\note 对于8051来说如果系统中断被配置为使用独立的REGBANK与任务使用不同的REGBANK<br>
下列的回调函数需要添加using属性、或声明为相对寄存器访问。参见 tick_hook.c 中示例。
@{
*/
/**
\brief iResumeTask(task) error callback
\param[in] htask 任务句柄
\return 无
*/
void pResumeTask_ErrorCallback(s_tasknode_tsp htask);
/**
\brief iSuspendTask(task) error callback
\param[in] htask 任务句柄
\return 无
*/
void pSuspendTask_ErrorCallback(s_tasknode_tsp htask);
/**
\brief iDeleteTask(task) error callback
\param[in] htask 任务句柄
\return 无
*/
void pDeleteTask_ErrorCallback(s_tasknode_tsp htask);
/**
\brief iClearBlock(task) error callback
\param[in] htask 任务句柄
\return 无
*/
void pClearBlock_ErrorCallback(s_tasknode_tsp htask);
/**
\brief iSetBlock_x(task, x) error callback
\details iSetBlock_tc(task, tc)、iSetBlock_ms(task, ms)、iSetBlock_s(task, s)、
iSetBlock_m(task, m)、iSetBlock_h(task, h),都通过该函数实现错误调用返回。
\param[in] htask 任务句柄
\param[in] tick 滴答周期(阻塞时间)
\return 无
*/
void pSetBlock_ErrorCallback(s_tasknode_tsp htask, s_delay_t tick);
/**
\brief iSetTaskPri(task, npri) error callback
\param[in] htask 任务句柄
\param[in] npri 新优先级
\return 无
*/
void pSetTaskPri_ErrorCallback(s_tasknode_tsp htask, s_u8_t npri);
/**
\brief iSendMsg(que, msg) error callback
\param[in] hque 队列句柄
\param[in] msg 消息指针
\return 无
*/
void pSendMsg_ErrorCallback(s_msgque_tsp hque, void *msg);
/**
\brief error code of error callback
\param 无
\return 错误码s_ecode_t
*/
#define pECode_ErrorCallback() s_psvfifo_ecode
/** @} */
/**
\ingroup 杂项
\defgroup DEBUG
\brief DEBUG接口串口发送与接收的实现。
@{
*/
/**
\brief DEBUG发送完成
\param 无
\return 无
*/
#define xDebugSend_Complete() s_debug_sendsign = true
/**
\brief DEBUG接收解析
\param[in] p 接收缓存的开始指针
\param[in] len 接收数据包的长度
\return 无
*/
#define xDebugRecv_Handler(p, len) \
do{ \
s_debug_recvptr = p; \
s_debug_recvlen = len; \
}while(false)
/** @} */
/**
\ingroup 杂项
\defgroup 时间单位转换
\brief 把其它单位的时间转换为滴答周期。
@{
*/
/**
\brief 毫秒转换为滴答周期
\param[in] ms 毫秒
\return 滴答周期
*/
#define xTick_ms(ms) ((1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE)
/**
\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))
/** @} */
/**
\brief 触发PendSV
\details 在用户中断中当采用中断挂起服务FLAG队列执行服务时用户在设置标志位后<br>
需手动触发PendSV而后在 pendsv_hook() 中执行服务。
\param 无
\return 无
*/
#define iPendSV_Set() mPendSV_Set()
/** @} */
/** @} */
#endif