mirror of
https://gitee.com/cosyos/cosyos.git
synced 2026-08-18 09:08:13 +08:00
1747 lines
58 KiB
C
1747 lines
58 KiB
C
/**************************************************************************//**
|
||
* @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 架构 数据类型<br>
|
||
8051 uint8_t<br>
|
||
80251 uint16_t<br>
|
||
Arm32 uint32_t<br>
|
||
通用别名 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>
|
||
|
||
<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>
|
||
|
||
<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>
|
||
0:FIFO(先入先出)<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>
|
||
0:FIFO(先入先出)<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 手动触发PendSV,for 中断挂起服务_FLAG。
|
||
\note 在用户中断中,当采用中断挂起服务FLAG队列执行服务时,用户在设置标志位后,<br>
|
||
需手动触发PendSV,而后在 pendsv_hook() 中执行服务。
|
||
@{
|
||
*/
|
||
|
||
#define iPendSV_Set mPendSV_Set
|
||
|
||
/** @} */
|
||
/** @} */
|
||
|
||
|
||
/** @} */
|
||
#endif
|