Files
cosyos/System/ur_api.h
T
零中断延迟的RTOS 9b4f65be0f update CosyOS-内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2025-02-26 14:57:37 +00:00

1747 lines
58 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**************************************************************************//**
* @item CosyOS-III Kernel
* @file ur_api.h
* @brief 用户API
* @details 用户API定义,含注释说明,所有内核服务的API说明均在此文件中,并支持 doxygen。
* @author 迟凯峰
* @version V1.0.2
* @date 2025.02.26
******************************************************************************/
#ifndef __UR_API_H
#define __UR_API_H
/**
\defgroup CosyOS_用户API
\brief 用户通过调用API来实现对系统服务的调用,所有API均为宏定义,
所有系统服务也为宏定义,所有API参数均支持宏定义。
@{
*/
/**
\page API说明:
\li <strong>API分类</strong>
\li 创建API<br>
静态创建:前缀为“u”,分为声明对象(uExtern)、创建对象(uCreate)、定义对象(uDef)。<br>
动态创建:前缀为“d”,分为声明对象(dExtern)、创建对象(dCreate)。
\li 任务API<br>
前缀为“u”,指仅在任务中调用。
\li 滴答API<br>
前缀为“t”,指仅在系统滴答中断中调用,包括在滴答钩子、定时中断钩子、<br>
定时查询钩子、定时查询事件等处调用。
\li 中断API<br>
前缀为“i”,指仅在用户中断中调用。
\li PSVAPI<br>
前缀为“p”,指仅在 pendsv_hook 中调用。
\li 公共API<br>
前缀为“x”,指可在任意处(任务、滴答、中断)调用。
<br>
\li <strong>API返回</strong>
\li 无返回<br>
(1)服务的执行结果一定是成功的,所以不需要返回。<br>
(2)所有中断挂起服务均无返回。
\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>
*/
/**************************************************************************//**
\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)
/** @} */
/**
\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, 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, 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 uCreateTask_TimInt(tmid, arl, task, pri, tss, srt, res) \
sCSV_CreateTask_TimInt(tmid, arl, task, pri, tss, srt, 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, 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, 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, res)
/** @} */
/**
\ingroup 任务
\defgroup 启动任务
\brief 任务线程的启动。任务只有在启动以后,才能加入到任务队列参与调度并运行。
\warning 所有定时中断任务和定时查询任务均由操作系统自动启动,用户不要启动。
\warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
@{
*/
/**
\brief 启动任务
\details 启动任务并置任务的初始状态为设定状态。
\param[in] task 任务名称
\param[in] status 任务的初始状态<br>
0:就绪状态<br>
1:挂起状态
\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(task, status) \
sUSV_StartTask(&u_taskhand_##task, status)
/**
\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_Suspend(task) \
uStartTask(task, OS_STATUS_SUSPENDED)
/** @} */
/**
\ingroup 任务
\defgroup 操作任务
\brief 对任意任务的操作,如 恢复、挂起、删除、设置优先级 等。
@{
*/
/**
\brief 清除就绪延时
\details 清除当前任务的就绪延时,前提是当前任务已在就绪延时中。
\param 无
\return 无
\note 同型服务:<br>
iClearDelay,无返回。<br>
pClearDelay,无返回。
*/
#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>
iResumeTask(task),无返回。<br>
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 同型服务:<br>
tSuspendTask(task),同返回。<br>
iSuspendTask(task),无返回。<br>
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 同型服务:<br>
tDeleteTask(task),同返回。<br>
iDeleteTask(task),无返回。<br>
pDeleteTask(task),无返回。
*/
#define uDeleteTask(task) \
sUSV_DeleteTask(u_taskhandle_##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>
iSetTaskPri(task, npri),无返回。<br>
pSetTaskPri(task, npri),无返回。
*/
#define uSetTaskPri(task, npri) \
sUSV_SetTaskPri(u_taskhandle_##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>
iClearBlock(task),无返回。<br>
pClearBlock(task),无返回。
*/
#define uClearBlock(task) \
sUSV_ClearBlock(u_taskhandle_##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>
iSetBlock_tc(task, tc),无返回。<br>
pSetBlock_tc(task, tc),无返回。
*/
#define uSetBlock_tc(task, tc) sUSV_SetBlock(u_taskhandle_##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>
iSetBlock_ms(task, ms),无返回。<br>
pSetBlock_ms(task, ms),无返回。
*/
#define uSetBlock_ms(task, ms) uSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICKCYCLE)
/**
\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>
iSetBlock_s(task, s),无返回。<br>
pSetBlock_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>
iSetBlock_m(task, m),无返回。<br>
pSetBlock_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>
iSetBlock_h(task, h),无返回。<br>
pSetBlock_h(task, h),无返回。
*/
#define uSetBlock_h(task, h) uSetBlock_m(task, 60UL * (h))
/** @} */
/** @} */
/**
\ingroup 任务
\defgroup 操作自身任务
\brief 仅适用于对自身任务的操作
@{
*/
/**
\brief 禅让任务
\details 自身任务主动禅让CPU使用权,轮转至下一个相同优先级的任务运行。
\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 挂起自身任务
\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)
/**
\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_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 由用户定时操作,当定时器溢出时,系统将自动恢复/调用与其绑定的任务/钩子并可自动重复定时。
\note 理想误差:-1tick。
\warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。
@{
*/
/**
\brief 创建定时中断钩子
\param[in] tmid 定时器ID
\param[in] arl 自动重装载设置<br>
0:关闭自动重装载<br>
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] 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_SYSTICKCYCLE)
/**
\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] hook 钩子函数
\param[in] add{...} 附加钩子代码
\return 无
*/
#define uCreateHook_TimQry(tmid, event, arl, hook) \
sCSV_CreateHook_TimQry(tmid, event, arl, hook)
/**
\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_SYSTICKCYCLE)
/**
\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 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
\warning 当tc为~0时(无限等待),仍建议用户查询返回值,原因是当在多个相同优先级的任务中<br>
获取同一个互斥信号量时(采用时间片轮转调度),其返回结果仍然有失败的可能。
*/
#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>
0:已上锁<br>
1:已解锁
\return 无
*/
#define uCreateBin(bin, init) sCSV_CreateBin(bin, init)
/**
\brief 上锁二值信号量
\details 用于终止线程的无限同步。
\param[in] bin 二值信号量名称
\return 无
\note 同型服务:<br>
tLockBin(bin)。<br>
iLockBin(bin)。<br>
pLockBin(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>
iGiveBin(bin)。<br>
pGiveBin(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 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
\warning 当用于资源同步时(互斥访问),当tc为~0时(无限等待),仍建议用户查询返回值,原因是<br>
当在多个相同优先级的任务中获取同一个二值信号量时(采用时间片轮转调度),其返回结果仍然有失败的可能。
*/
#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 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。
\warning 当用于资源同步时(互斥访问),当tc为~0时(无限等待),仍建议用户查询返回值,原因是<br>
当在多个相同优先级的任务中获取同一个计数信号量时(采用时间片轮转调度),其返回结果仍然有失败的可能。
*/
#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 仅使用一个变量,同时即是消息,又是新消息标志。<br>
飞信为0时,表示无消息;飞信非0时,表示有消息;<br>
因此,
\warning 用户传输的有效消息必须为真值。
\note 架构&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数据类型<br>
8051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t<br>
80251&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint16_t<br>
Arm32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint32_t<br>
通用别名&nbsp;&nbsp;&nbsp;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 接收飞信<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>
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 传输模式<br>
0FIFO(先入先出)<br>
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 滴答周期(超时时间)<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 适用于对一类事件的、多对一关系的事件同步。
\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 由CosyOS内核提供服务支持,可实现在“任务、滴答、中断”中,对非原子全局变量
的安全访问,同时不会破坏零中断延迟。
@{
*/
/**
\brief 更新全局变量副本
\param[in] code 更新副本的代码
\return 无
*/
#define xUpdateCopy(code) sUpdateCopy(code)
/**
\brief 读哪一个全局变量?
\return 结果(bool
\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 适用于没有硬件RTC的物联网设备。
\note 实际应用中,可每间隔一段时间(如一小时)同步一次网络时间,以修正误差。
@{
*/
/**
\brief 获取时间
\param[in] t 本地时间的指针(s_rtc_ts)
\return 本地时间的指针
\note 同型服务:<br>
tGetTime(t)。<br>
iGetTime(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模式时可考虑在线程的开始处创建。
\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 释放线程内存池
*/
#define uFreeMempool sUSV_FreeMempool
/** @} */
/** @} */
/**************************************************************************//**
\ingroup CosyOS_用户API
\defgroup 临界区
\note CosyOS的临界区包括任务临界区、服务层临界区、全局临界区,均支持嵌套使用。<br>
各临界区之间也可随意互相嵌套,但通常推荐在任务临界区中嵌套服务层临界区,<br>
在服务层临界区中嵌套全局临界区,以逐步扩大保护范围。
@{
*/
/**
\ingroup 临界区
\defgroup 调度锁(任务临界区)
\brief 通过上锁任务调度器的方式,实现任务级的临界区保护,仅支持在任务中调用。
\note 仅是上锁任务调度器,不关闭系统中断(SysTick、PendSV),所以即使是长时间的、<br>
对大段的任务级公共资源的独占访问,也不会影响系统节拍的精度和内核服务的执行。
\note 调度锁支持嵌套使用,最大嵌套深度255,调度上锁与调度解锁必须配对使用。
\note 调度锁不会破坏零中断延迟,当需要任务级的临界区保护时,可以考虑。
@{
*/
/**
\brief 调度上锁(进入任务临界区)
\return 无
*/
#define uScheduleLock su_schedule_locks()
/**
\brief 调度解锁(退出任务临界区)
\return 无
*/
#define uScheduleUnlock su_schedule_unlocks()
/** @} */
/**
\ingroup 临界区
\defgroup 内核锁(服务层临界区)
\brief OS内核级的临界区保护,会关闭系统中断(SysTick、PendSV),仅支持在任务中调用。
\note 由 系统滴答、PendSV、内核锁,共同组成大的服务层临界区,当处理得当时,可实现全局的临界区保护。<br>
实现过程:<br>
任务中:对内核上锁后访问。<br>
滴答中:直接访问即可。<br>
中断中:采用中断挂起服务。
\note 内核锁支持嵌套使用,最大嵌套深度255,内核上锁与内核解锁必须配对使用。
\note 内核锁不会破坏零中断延迟,当需要全局的临界区保护时,应首先予以考虑。
\note 内核锁应遵循快进快出的原则,临界段代码的执行时间应远小于系统滴答周期,否则可能会导致<br>
丢失系统节拍、延误中断挂起服务和滴答服务的执行,对系统实时性造成不利影响。
\note 当在任务中对事件标志组进行 设置位、清除位 等操作时,需采用内核锁。
\note 当在任务中访问非原子全局变量时(包括读访问、写访问、自运算),<br>
可采用内核锁实现全局的临界区保护(参见 全局变量访问示例)。
@{
*/
/**
\brief 内核上锁(进入服务层临界区)
\return 无
*/
#define uKernelLock su_kernel_locks()
/**
\brief 内核解锁(退出服务层临界区)
\return 无
*/
#define uKernelUnlock su_kernel_unlocks()
/** @} */
/**
\ingroup 临界区
\defgroup 中断锁(全局临界区)
\brief 全局的临界区保护,通常会关闭总中断,支持在任意处调用。
\note CosyOS内核中从来不会关闭总中断,提供此项服务只是为了便于用户<br>
对全局公共资源和程序过程的保护。
\note 全局临界区会破坏零中断延迟,应做为最后的选项,慎重使用。
@{
*/
#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 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 DEBUG
\brief 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
\brief 手动触发PendSVfor 中断挂起服务_FLAG。
\note 在用户中断中,当采用中断挂起服务FLAG队列执行服务时,用户在设置标志位后,<br>
需手动触发PendSV,而后在 pendsv_hook() 中执行服务。
@{
*/
#define iPendSV_Set mPendSV_Set
/** @} */
/** @} */
/** @} */
#endif