From d0d14cca1e1e23451afc7b0f42259f2597ac38a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B6=E4=B8=AD=E6=96=AD=E5=BB=B6=E8=BF=9F=E7=9A=84RTOS?= Date: Fri, 27 Jun 2025 10:12:03 +0000 Subject: [PATCH] =?UTF-8?q?update=20CosyOS-=E5=86=85=E6=A0=B8=E6=96=87?= =?UTF-8?q?=E4=BB=B6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 零中断延迟的RTOS --- System/ur_api.h | 1777 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1777 insertions(+) create mode 100644 System/ur_api.h diff --git a/System/ur_api.h b/System/ur_api.h new file mode 100644 index 0000000..b37b397 --- /dev/null +++ b/System/ur_api.h @@ -0,0 +1,1777 @@ +/**************************************************************************//** + * @item CosyOS-III Kernel + * @file ur_api.h + * @brief 用户API + * @details 用户API定义,含注释说明,所有内核服务的API说明均在此文件中,并支持doxygen。 + * @author 迟凯峰 + * @version V1.2.9 + * @date 2025.06.27 + ******************************************************************************/ + +#ifndef __UR_API_H +#define __UR_API_H + +/** + \page CosyOS_API_DESCRIBE 概述:API说明 + 用户通过调用API来实现对系统服务的调用,所有API均为宏定义,所有API参数均支持宏定义。 + +
+ + \li API分类 + + \li 创建API
+ 静态创建:前缀为“u”,分为声明对象(uExtern)、创建对象(uCreate)、定义对象(uDef)。
+ 动态创建:前缀为“d”,分为声明对象(dExtern)、创建对象(dCreate)。 + + \li 任务API
+ 前缀为“u”,指仅在任务中调用。 + + \li 滴答API
+ 前缀为“t”,指仅在 SysTick_Handler 中调用,包括但不限于在滴答钩子、定时中断钩子、
+ 定时查询钩子、定时查询事件等处调用。 + + \li 中断API
+ 前缀为“i”,指仅在用户中断中调用。 + + \li PSVAPI
+ 前缀为“p”,指仅在 PendSV_Handler(pendsv_hook)中调用。 + + \li 公共API
+ 前缀为“x”,指可在任意处调用。 + +
+ + \li API返回 + + \li 无返回
+ (1)服务的执行结果一定是成功的,所以不需要返回。
+ (2)所有中断挂起服务均无返回。 + + \li 返回错误码
+ 服务的执行结果可能会失败,导致失败的原因可能有多个。
+ (1)无错误。
+ (2)由于结果已经成功,导致本次并未执行。
+ (3)失败。 + + \li 返回结果
+ 服务的执行结果可能会失败,但导致失败的原因是唯一的。
+ 执行结果为 bool 类型,true 为成功,false 为失败。 + + \li 返回指针
+ 返回一个指针,(void *) 类型,NULL 为失败。 + + \li 返回值
+ 返回一个数值,特定的数据类型,0 为失败。 + +
+ + \li 名词解释 + + \li 无限阻塞
+ 阻塞时间为无限长。 + + \li 无限等待
+ 超时时间为无限长。 + + \li 无限延时
+ 延时时间为无限长。 + + \li 无限同步
+ 仅同步一次,事件处理线程便可不限次数的周期运行处理事件。
+ 仅二值信号量支持该功能,可通过上锁的方式来终止无限同步。 + +
+ */ + +/** + \defgroup CosyOS_用户API + @{ + */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 构建系统 + \brief 系统构建相关服务。 + @{ + */ + +/** + \brief 启动-CosyOS + \param 无 + \return 错误码 + \note 用户应自主创建main函数,并在其末尾处调用该函数来启动-CosyOS;
+ 在正常情况下,该函数并不会返回,而是直接调度至 Starter 运行;
+ 只有在 Sysidle / Starter 启动失败时,才会返回错误码提示用户。 + */ +s_ecode_t uStartCosyOS(void); + +/** + \brief CosyOS-滴答 + \param 无 + \return 无 + \note 对于Arm用户来说,您应自主创建 SysTick_Handler(),并在其中调用该服务。 + \warning 对于51/251用户来说,系统滴答中断固定采用定时器0中断,并由CosyOS托管,
+ 您应屏蔽掉工程中原有的定时器0中断函数以避免冲突。 + */ +void tCosyTick_Handler(void); + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 任务 + \brief 任务线程的声明、创建、启动,及操作。 + @{ + */ + +/** + \ingroup 任务 + \defgroup 声明任务 + \brief 任务线程的声明 + \note 首先,声明任务不一定是必须的,当仅在一个c文件中启动、操作任务时,时常并不需要声明。 + \note 在声明任务时,通常无论是在h文件中声明还是在c文件中声明,都应采用完整声明方式,
+ 只有在编译器发出警告,与该任务相关的全局变量未引用时,再考虑简化声明方式。 + \note 通常这种情况并不会发生,典型的是在您使用GCC(GNU)编译器时,可能偶尔会出现这种警告。 + @{ + */ + +/** + \brief 简化声明静态任务 + \param[in] task 任务名称 + \return 无 + */ +#define uExtTask(task) \ + sCSV_ExtTask(task) + +/** + \brief 简化声明动态任务 + \param[in] task 任务名称 + \return 无 + */ +#define dExtTask(task) \ + dCSV_ExtTask(task) + +/** + \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, 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] 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 任务的初始状态
+ 就绪状态:OS_STATUS_READY
+ 阻塞状态:OS_STATUS_BLOCKED,阻塞类型为延时阻塞,延时时间为无限长。
+ 挂起状态: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 任务栈内存分配失败 + */ +#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_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 同型服务:
+ iClearDelay(),无返回。
+ 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 同型服务:
+ tResumeTask(task),同返回。
+ iResumeTask(task),无返回。
+ pResumeTask(task),无返回。 + */ +#define uResumeTask(task) \ + sUSV_ResumeTask(u_taskhandle_##task) + +/** + \brief 挂起任务 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKSUSPENDED 任务已挂起 + \retval OS_ECODE_TASKSTOPPED 任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSuspendTask(task),同返回。
+ iSuspendTask(task),无返回。
+ pSuspendTask(task),无返回。 + */ +#define uSuspendTask(task) \ + sUSV_SuspendTask(u_taskhandle_##task) + +/** + \brief 删除任务 + \param[in] task 任务名称 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tDeleteTask(task),同返回。
+ iDeleteTask(task),无返回。
+ pDeleteTask(task),无返回。 + */ +#define uDeleteTask(task) \ + sUSV_DeleteTask(u_taskhandle_##task) + +/** + \brief 设置任务优先级 + \param[in] task 任务名称 + \param[in] npri 新优先级 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKPRIUNCHANGED 任务优先级未改变 + \retval OS_ECODE_TASKSTOPPED 任务已停止 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetTaskPri(task, npri),同返回。
+ iSetTaskPri(task, npri),无返回。
+ 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 同型服务:
+ tClearBlock(task),同返回。
+ iClearBlock(task),无返回。
+ 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 滴答周期(阻塞时间)
+ +0:清除阻塞
+ ~0:无限阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_tc(task, tc),同返回。
+ iSetBlock_tc(task, tc),无返回。
+ pSetBlock_tc(task, tc),无返回。 + */ +#define uSetBlock_tc(task, tc) sUSV_SetBlock(u_taskhandle_##task, tc) + +/** + \brief 设置阻塞-毫秒 + \param[in] task 任务名称 + \param[in] ms 毫秒(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_ms(task, ms),同返回。
+ iSetBlock_ms(task, ms),无返回。
+ pSetBlock_ms(task, ms),无返回。 + */ +#define uSetBlock_ms(task, ms) uSetBlock_tc(task, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE) + +/** + \brief 设置阻塞-秒钟 + \param[in] task 任务名称 + \param[in] s 秒钟(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_s(task, s),同返回。
+ iSetBlock_s(task, s),无返回。
+ pSetBlock_s(task, s),无返回。 + */ +#define uSetBlock_s(task, s) uSetBlock_ms(task, 1000UL * (s)) + +/** + \brief 设置阻塞-分钟 + \param[in] task 任务名称 + \param[in] m 分钟(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_m(task, m),同返回。
+ iSetBlock_m(task, m),无返回。
+ pSetBlock_m(task, m),无返回。 + */ +#define uSetBlock_m(task, m) uSetBlock_s(task, 60UL * (m)) + +/** + \brief 设置阻塞-小时 + \param[in] task 任务名称 + \param[in] h 小时(阻塞时间)
+ 0:清除阻塞 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval OS_ECODE_TASKNOTBLOCKED 任务未阻塞 + \retval OS_ECODE_TASKNOTSTARTED 任务未启动/已删除 + \note 同型服务:
+ tSetBlock_h(task, h),同返回。
+ iSetBlock_h(task, h),无返回。
+ pSetBlock_h(task, h),无返回。 + */ +#define uSetBlock_h(task, h) uSetBlock_m(task, 60UL * (h)) + +/** @} */ +/** @} */ +/** + \ingroup 任务 + \defgroup 操作自身任务 + \brief 仅适用于对自身任务的操作 + @{ + */ + +/** + \brief 禅让任务 + \details 自身任务主动禅让CPU使用权,轮转至下一个相同优先级的任务运行。 + \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(u_taskhandle_##task) + +/** + \ingroup 操作自身任务 + \defgroup 自身任务延时 + \brief 自身任务延时分为阻塞延时和就绪延时。 + \note 阻塞延时:在延时期间,任务会进入阻塞状态,把CPU使用权转让给其它任务。 + \note 就绪延时:在延时期间,任务会维持就绪状态,原地等待延时时间到达,不转让CPU使用权。 + \note 当在任务临界区中,自动选择为就绪延时,否则选择为阻塞延时。 + \note 理想误差:-1tick。 + \warning 按 毫秒、秒钟、分钟、小时 延时,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + \warning 无限延时,仅能通过调用 uDelay_tc(~0) 来实现。 + \warning 不支持在服务层临界区、全局临界区,或关闭总中断时调用。 + @{ + */ + +/** + \brief 延时-滴答周期 + \param[in] tc 滴答周期(延时时间)
+ ~0:无限延时 + \return 无 + */ +#define uDelay_tc(tc) sUSV_Delay(tc) + +/** + \brief 延时-毫秒 + \param[in] ms 毫秒(延时时间) + \return 无 + */ +#define uDelay_ms(ms) uDelay_tc((1000UL * (ms)) / SYSCFG_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 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \param[in] hook 钩子函数 + \param[in] add{...} 附加钩子代码 + \return 无 + */ +#define uCreateHook_TimInt(tmid, arl, hook) \ + sCSV_CreateHook_TimInt(tmid, arl, hook) + +/** + \brief 定时中断-滴答周期 + \param[in] tmid 定时中断定时器ID + \param[in] tc 滴答周期(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_tc(tmid, tc)。
+ iTimInt_tc(tmid, tc)。 + */ +#define uTimInt_tc(tmid, tc) sUSV_TimInt(tmid, tc) + +/** + \brief 定时中断-毫秒 + \param[in] tmid 定时中断定时器ID + \param[in] ms 毫秒(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_ms(tmid, ms)。
+ iTimInt_ms(tmid, ms)。 + */ +#define uTimInt_ms(tmid, ms) uTimInt_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE) + +/** + \brief 定时中断-秒钟 + \param[in] tmid 定时中断定时器ID + \param[in] s 秒钟(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_s(tmid, s)。
+ iTimInt_s(tmid, s)。 + */ +#define uTimInt_s(tmid, s) uTimInt_ms(tmid, 1000UL * (s)) + +/** + \brief 定时中断-分钟 + \param[in] tmid 定时中断定时器ID + \param[in] m 分钟(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_m(tmid, m)。
+ iTimInt_m(tmid, m)。 + */ +#define uTimInt_m(tmid, m) uTimInt_s(tmid, 60UL * (m)) + +/** + \brief 定时中断-小时 + \param[in] tmid 定时中断定时器ID + \param[in] h 小时(定时时间) + \return 无 + \note 同型服务:
+ tTimInt_h(tmid, h)。
+ iTimInt_h(tmid, h)。 + */ +#define uTimInt_h(tmid, h) uTimInt_m(tmid, 60UL * (h)) + +/** + \brief 终止定时中断 + \param[in] tmid 定时中断定时器ID + \return 无 + \note 同型服务:
+ tTimInt_Cancel(tmid)。
+ iTimInt_Cancel(tmid)。 + */ +#define uTimInt_Cancel(tmid) uTimInt_tc(tmid, 0) + +/** + \brief 定时中断定时器自动重装载 + \param[in] tmid 定时中断定时器ID + \param[in] arl 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \return 无 + */ +#define xTimInt_AutoReload(tmid, arl) s_timint_autoreload[tmid] = arl + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 定时查询 + \brief 由用户定时操作,当定时器溢出后,系统在每个滴答周期都会查询用户定义的事件, + 若事件为真,系统将自动恢复/调用与其绑定的任务/钩子并可自动重复定时。 + \note 理想误差:-1tick。 + \warning 按 毫秒、秒钟、分钟、小时 定时,用户需自己保证时间的有效性(可被系统滴答周期整除)。 + @{ + */ + +/** + \brief 创建定时查询钩子 + \param[in] tmid 定时器ID + \param[in] event 定时查询事件 + \param[in] arl 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \param[in] hook 钩子函数 + \param[in] add{...} 附加钩子代码 + \return 无 + */ +#define uCreateHook_TimQry(tmid, event, arl, hook) \ + sCSV_CreateHook_TimQry(tmid, event, arl, hook) + +/** + \brief 定时查询-滴答周期 + \param[in] tmid 定时查询定时器ID + \param[in] tc 滴答周期(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_tc(tmid, tc)。
+ iTimQry_tc(tmid, tc)。 + */ +#define uTimQry_tc(tmid, tc) sUSV_TimQry(tmid, tc) + +/** + \brief 定时查询-毫秒 + \param[in] tmid 定时查询定时器ID + \param[in] ms 毫秒(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_ms(tmid, ms)。
+ iTimQry_ms(tmid, ms)。 + */ +#define uTimQry_ms(tmid, ms) uTimQry_tc(tmid, (1000UL * (ms)) / SYSCFG_SYSTICK_CYCLE) + +/** + \brief 定时查询-秒钟 + \param[in] tmid 定时查询定时器ID + \param[in] s 秒钟(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_s(tmid, s)。
+ iTimQry_s(tmid, s)。 + */ +#define uTimQry_s(tmid, s) uTimQry_ms(tmid, 1000UL * (s)) + +/** + \brief 定时查询-分钟 + \param[in] tmid 定时查询定时器ID + \param[in] m 分钟(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_m(tmid, m)。
+ iTimQry_m(tmid, m)。 + */ +#define uTimQry_m(tmid, m) uTimQry_s(tmid, 60UL * (m)) + +/** + \brief 定时查询-小时 + \param[in] tmid 定时查询定时器ID + \param[in] h 小时(定时时间) + \return 无 + \note 同型服务:
+ tTimQry_h(tmid, h)。
+ iTimQry_h(tmid, h)。 + */ +#define uTimQry_h(tmid, h) uTimQry_m(tmid, 60UL * (h)) + +/** + \brief 终止定时查询 + \param[in] tmid 定时查询定时器ID + \return 无 + \note 同型服务:
+ tTimQry_Cancel(tmid)。
+ iTimQry_Cancel(tmid)。 + */ +#define uTimQry_Cancel(tmid) uTimQry_tc(tmid, ~0) + +/** + \brief 定时查询定时器自动重装载 + \param[in] tmid 定时查询定时器ID + \param[in] arl 自动重装载设置
+ 0:关闭自动重装载
+ 1:开启自动重装载 + \return 无 + */ +#define xTimQry_AutoReload(tmid, arl) s_timqry_autoreload[tmid] = arl + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 互斥信号量 + \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 滴答周期(超时时间)
+ +0:立即返回
+ ~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 二值信号量初始值
+ false(0):已上锁,无法立即成功获取
+ true(1) :已解锁,可以立即成功获取 + \return 无 + \note 当用于互斥访问时,初始值应为true。 + */ +#define uCreateBin(bin, init) sCSV_CreateBin(bin, init) + +/** + \brief 上锁二值信号量 + \details 用于终止线程的无限同步。 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tLockBin(bin)。
+ iLockBin(bin)。
+ pLockBin(bin)。 + */ +#define uLockBin(bin) bin.binary = false + +/** + \brief 等待二值信号量 + \details 在指定的超时时间内等待二值信号量为真,适用于任务的无限同步,与获取的区别是不上锁。 + \param[in] bin 二值信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(bool) + \retval false 失败 + \retval true 成功 + \warning 不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + */ +#define uWaitBin(bin, tc) sUSV_WaitBin(bin, tc) + +/** + \brief 给予二值信号量 + \details 专用于事件同步。 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tGiveBin(bin)。
+ iGiveBin(bin)。
+ pGiveBin(bin)。 + */ +#define uGiveBin(bin) sUSV_GiveBin(bin) + +/** + \brief 获取二值信号量 + \details 用于事件同步或互斥访问。 + \param[in] bin 二值信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(bool) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ tTakeBin(bin)。
+ iTakeBin(bin)。 + \warning 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + */ +#define uTakeBin(bin, tc) sUSV_TakeBin(bin, tc) + +/** + \brief 归还二值信号量 + \details 专用于互斥访问。 + \param[in] bin 二值信号量名称 + \return 无 + \note 同型服务:
+ tBackBin(bin)。
+ 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 同型服务:
+ tGiveSem(sem)。
+ iGiveSem(sem)。 + */ +#define uGiveSem(sem) sUSV_GiveSem(sem) + +/** + \brief 获取计数信号量 + \param[in] sem 计数信号量名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(bool) + \retval false 失败 + \retval true 成功 + \note 同型服务:
+ tTakeSem(sem)。 + \warning 任务中获取,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + */ +#define uTakeSem(sem, tc) sUSV_TakeSem(sem, tc) + +/** + \brief 归还计数信号量 + \param[in] sem 计数信号量名称 + \return 无 + \note 同型服务:
+ tBackSem(sem)。 + */ +#define uBackSem(sem) uGiveSem(sem) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 事件标志组 + \brief 适用于对一类事件的事件同步。 + \details 某一类事件,它的发生线程可能会有多个,均同步至同一个事件处理线程中统一处理该类事件。 + \note 名词解释
+ 组名:标志组的名称
+ 位名:标志位的名称
+ 空位:空标志位
+ \note 查询标志位:任务、滴答、中断中,均直接查询。 + @{ + */ + +/** + \brief 声明标志组 + \param[in] group 组名 + \param[in] bits 定义各标志位,分号间隔 + \return 无 + */ +#define uExternFlagGroup(group, bits) sCSV_ExternFlagGroup(group, bits) + +/** + \brief 定义标志位 + \param[in] bit 位名 + \return 无 + */ +#define uDefFlagBit(bit) sDefBitField(bit) + +/** + \brief 定义空位 + \param[in] nvb 空位的数量 + \return 无 + */ +#define uDefVoidBits(nvb) sDefVoidBits(nvb) + +/** + \brief 创建标志组 + \param[in] group 组名 + \param[in] add={...} 附加代码(赋初值) + \return 无 + */ +#define uCreateFlagGroup(group) sCSV_CreateFlagGroup(group) + +/** + \brief 等待标志组 + \param[in] group 组名 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 结果(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 同型服务:
+ tQueryFlagGroup(group)。
+ iQueryFlagGroup(group)。 + */ +#define uQueryFlagGroup(group) sUSV_QueryFlagGroup(group) + +/** + \brief 清除标志组 + \param[in] group 组名 + \return 无 + \note 同型服务:
+ tClearFlagGroup(group)。
+ iClearFlagGroup(group)。 + */ +#define uClearFlagGroup(group) sUSV_ClearFlagGroup(group) + +/** + \brief 设置标志位 + \param[in] group 组名 + \param[in] bit 位名 + \return 无 + \note 同型服务:
+ tSetFlagBit(group, bit)。
+ iSetFlagBit(group, bit)。 + */ +#define uSetFlagBit(group, bit) uSetFlagBits(group, 1) bit) + +/** + \brief 清除标志位 + \param[in] group 组名 + \param[in] bit 位名 + \return 无 + \note 同型服务:
+ tClearFlagBit(group, bit)。
+ iClearFlagBit(group, bit)。 + */ +#define uClearFlagBit(group, bit) uClearFlagBits(group, 1) bit) + +/** + \brief 设置多标志位 + \param[in] group 组名 + \param[in] nbit 标志位的数量 + \param[in] add...) 各位名,逗号间隔 + \return 无 + \note 同型服务:
+ tSetFlagBits(group, nbit)。
+ iSetFlagBits(group, nbit)。 + */ +#define uSetFlagBits(group, nbit) sUSV_WriteFlagBits(group, true, nbit) + +/** + \brief 清除多标志位 + \param[in] group 组名 + \param[in] nbit 标志位的数量 + \param[in] add...) 各位名,逗号间隔 + \return 无 + \note 同型服务:
+ tClearFlagBits(group, nbit)。
+ iClearFlagBits(group, nbit)。 + */ +#define uClearFlagBits(group, nbit) sUSV_WriteFlagBits(group, false, nbit) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 飞信 + \brief 原子类型、传输数据。 + \details 仅使用一个变量,同时即是消息,又是新消息标志。
+ 飞信为0时,表示无消息;飞信非0时,表示有消息;
+ 因此: + \warning 用户传输的有效消息必须为真值。 + \note 架构             数据类型
+ 8051            uint8_t
+ 80251          uint16_t
+ Arm32         uint32_t
+ 通用别名     m_fetion_t
+ @{ + */ + +/** + \brief 声明信箱 + \param[in] tbox 信箱名称 + \return 无 + */ +#define uExternTionbox(tbox) sCSV_ExternTionbox(tbox) + +/** + \brief 创建信箱 + \param[in] tbox 信箱名称 + \return 无 + */ +#define uCreateTionbox(tbox) sCSV_CreateTionbox(tbox) + +/** + \brief 接收飞信
+
+ 别名
+           + uRecvFet + \param[in] tbox 信箱名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 飞信(m_fetion_t) + \retval false 无飞信 + \note 同型服务:
+ tRecvFetion(tbox) / tRecvFet
+ iRecvFetion(tbox) / iRecvFet。 + \warning 任务中接收,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + */ +#define uRecvFetion(tbox, tc) sUSV_RecvFetion(tbox, tc) + +/** + \brief 发送飞信
+
+ 别名
+           + uSendFet + \param[in] tbox 信箱名称 + \param[in] tion 飞信 + \return 无 + \note 同型服务:
+ tSendFetion(tbox, tion) / tSendFet
+ iSendFetion(tbox, tion) / iSendFet。 + */ +#define uSendFetion(tbox, tion) sUSV_SendFetion(tbox, tion) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 消息邮箱 + \brief 任意类型、传输指针。 + @{ + */ + +/** + \brief 声明邮箱 + \param[in] mbox 邮箱名称 + \return 无 + */ +#define uExternMailbox(mbox) sCSV_ExternMailbox(mbox) + +/** + \brief 创建邮箱 + \param[in] mbox 邮箱名称 + \return 无 + */ +#define uCreateMailbox(mbox) sCSV_CreateMailbox(mbox) + +/** + \brief 接收邮件 + \param[in] mbox 邮箱名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 邮件指针(void *) + \retval NULL 无邮件 + \note 同型服务:
+ tRecvMail(mbox)。
+ iRecvMail(mbox)。 + \warning 任务中接收,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + */ +#define uRecvMail(mbox, tc) sUSV_RecvMail(mbox, tc) + +/** + \brief 发送邮件 + \param[in] mbox 邮箱名称 + \param[in] mail 邮件指针 + \return 无 + \note 同型服务:
+ tSendMail(mbox, mail)。
+ iSendMail(mbox, mail)。 + */ +#define uSendMail(mbox, mail) sUSV_SendMail(mbox, mail) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 消息队列 + \brief 任意类型、传输指针,是唯一能够实现并发消息同步的手段。 + \details 消息队列包括静态队列和动态队列。
+ 静态队列:收发消息的效率高,队列占用固定的内存;
+ 动态队列:收发消息的效率低,接收消息后,队列内存可被回收。 + \note 每个队列,用户应当自己明确消息的类型和size,此事与OS无关。 + @{ + */ + +/** + \brief 声明静态队列 + \param[in] que 队列名称 + \return 无 + */ +#define uExternQueue_Static(que) sCSV_ExternQueue_Static(que) + +/** + \brief 声明动态队列 + \param[in] que 队列名称 + \return 无 + */ +#define uExternQueue_Dynamic(que) sCSV_ExternQueue_Dynamic(que) + +/** + \brief 创建静态队列 + \param[in] que 队列名称 + \param[in] mode 传输模式
+ 0:FIFO(先入先出)
+ 1:LIFO(后入先出) + \param[in] len 队列长度 + \return 无 + */ +#define uCreateQueue_Static(que, mode, len) sCSV_CreateQueue_Static(que, mode, len) + +/** + \brief 创建动态队列 + \param[in] que 队列名称 + \param[in] mode 传输模式
+ 0:FIFO(先入先出)
+ 1:LIFO(后入先出) + \param[in] len 队列长度 + \return 无 + */ +#define uCreateQueue_Dynamic(que, mode, len) sCSV_CreateQueue_Dynamic(que, mode, len) + +/** + \brief 接收消息 + \param[in] que 队列名称 + \param[in] tc 滴答周期(超时时间)
+ +0:立即返回
+ ~0:无限等待 + \return 消息指针(void *) + \retval NULL 无消息 + \note 同型服务:
+ tRecvMsg(que)。
+ iRecvMsg(que)。 + \warning 任务中接收,不支持在临界区中,包括任务临界区、服务层临界区、全局临界区,或关闭总中断时调用。 + \warning 中断中接收,队列只能是静态队列,消息缓存只能是静态缓存。 + */ +#define uRecvMsg(que, tc) sUSV_RecvMsg(que, tc) + +/** + \brief 发送消息 + \param[in] que 队列名称 + \param[in] msg 消息指针 + \return 错误码(s_ecode_t) + \retval OS_ECODE_NOERROR 无错误 + \retval ECODE_OVERFLOW_MSGQUEUE 消息队列溢出 + \retval ECODE_MALLOCFAIL_MSGNODE 消息节点内存分配失败 + \note 同型服务:
+ tSendMsg(que, msg),同返回。
+ iSendMsg(que, msg),无返回。 + \warning 中断中发送,消息缓存只能是静态缓存。 + */ +#define uSendMsg(que, msg) sUSV_SendMsg(que, msg) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 全局变量访问 + \brief 由CosyOS内核提供服务支持,可实现在任务、滴答、中断中,对非原子型 + 全局变量的线程安全访问,同时不会破坏零中断延迟。 + \note 全局的结构体、数组、字符串等,都可视为非原子型全局变量。 + \note 原子型访问:
+ 滴答中:直接->读访问、写访问、自运算。
+ 任务中:直接->读访问、写访问,内核上锁后->自运算。
+ 中断中:直接->读访问,调用服务->写访问、自运算。 + \note 非原子型访问:
+ 滴答中:直接->读访问、写访问、自运算。
+ 任务中:内核上锁后->读访问、写访问、自运算。
+ 中断中:不可以读访问,调用服务->写访问、自运算。 + \note 不可以读访问:
+ 建议挂起到PendSV中,或同步至某任务中处理事件。
+ 挂起到PendSV中:iPendSVC(fp) 或 pendsv_hook(),均可直接->读访问;
+ 同步至某任务中:内核上锁后->读访问。 + @{ + */ + +/** + \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 无 + \note 适用于全局变量自运算、事件处理等。 + */ +#define iPendSVC(fp) sPSV_PendSVC(fp) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 软件RTC + \brief 适用于没有硬件RTC的物联网终端设备。 + \note 实际应用中,可每间隔一段时间(如一小时)同步一次网络时间,以校正误差。 + @{ + */ + +/** + \brief 获取时间 + \param[in] t 本地时间的指针(s_rtc_ts *) + \return t(void *) + \note 同型服务:
+ tGetTime(t)。 + */ +#define uGetTime(t) sUSV_GetTime(t) + +/** + \brief 设置时间 + \param[in] t 本地时间的指针(s_rtc_ts *) + \return 无 + \note 同型服务:
+ tSetTime(t)。
+ iSetTime(t)。 + */ +#define uSetTime(t) sUSV_SetTime(t) + +/** @} */ + +/**************************************************************************//** + \ingroup CosyOS_用户API + \defgroup 动态内存 + @{ + */ + +/** + \ingroup 动态内存 + \defgroup 进程内存 + \brief 以进程为单位初始化内存池,各进程独享自己的内存池。 + @{ + */ + +/** + \brief malloc + \details 在进程内存池或堆中分配一块内存。 + \param[in] size 内存块的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uMalloc(size) sUSV_Malloc(size) + +/** + \brief calloc + \details 在进程内存池或堆中连续分配多块内存。 + \param[in] nmemb 内存块的数量 + \param[in] size 内存块的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uCalloc(nmemb, size) sUSV_Calloc(nmemb, size) + +/** + \brief realloc + \details 重新分配内存。 + \param[in] p 预重分配的指针 + \param[in] size 预重分配的大小(字节数) + \return 分配的指针(void _MALLOC_MEM_ *) + \retval NULL 内存分配失败 + */ +#define uRealloc(p, size) sUSV_Realloc(p, size) + +/** + \brief free + \param[in] p 释放的指针 + \return 无 + */ +#define uFree(p) sUSV_Free(p) + +/** @} */ + +/** + \ingroup 动态内存 + \defgroup 线程内存 + \brief 以线程为单位初始化内存池,各线程独享自己的内存池。 + \note 线程内存的分配效率远高于进程内存,因为每一次调用uTalloc都是在自己的线程内存池中直接按序分配内存。 + \note 在某线程中,如果需要多次动态内存分配,可考虑采用线程内存以提高性能。 + \note 线程内存的应用法则:当所有uTalloc的内存都可以释放时,再一次性释放所有内存(线程内存池)。 + @{ + */ + +/** + \brief 创建线程内存池 + \details 实为定义变量(线程内存控制块),C89模式时可考虑在线程的开始处创建。 + \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的临界区包括任务临界区、服务层临界区、全局临界区,均支持嵌套使用。
+ 各临界区之间也可随意互相嵌套,但通常推荐在任务临界区中嵌套服务层临界区,
+ 在服务层临界区中嵌套全局临界区,以逐步扩大保护范围。 + @{ + */ + +/** + \ingroup 临界区 + \defgroup 调度锁(任务临界区) + \brief 通过上锁任务调度器的方式,来实现任务级的临界区保护,仅支持在任务中调用。 + \note 仅是上锁任务调度器,不关闭系统中断(SysTick、PendSV),所以即使是长时间的、
+ 对大段的任务级公共资源的独占访问,也不会影响系统节拍和内核服务的执行。 + \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、内核锁,共同组成大的服务层临界区,当处理得当时,可实现全局的临界区保护。
+ 实现过程:
+ 滴答中:直接访问即可。
+ 任务中:内核上锁后访问。
+ 中断中:采用中断挂起服务。 + \note 内核锁支持嵌套使用,最大嵌套深度255,内核上锁与内核解锁必须配对使用。 + \note 内核锁不会破坏零中断延迟,当需要全局的临界区保护时,应首先予以考虑。 + \note 内核锁应遵循快进快出的原则,临界段代码的执行时间应远小于系统滴答周期,
+ 否则可能会导致丢失系统节拍、延误其它内核服务的执行,对系统实时性造成不利影响。 + \note 当在任务中访问非原子全局变量时,可采用内核锁实现全局的临界区保护。 + @{ + */ + +/** + \brief 内核上锁(进入服务层临界区) + \param 无 + \return 无 + */ +#define uKernelLock() su_kernel_locks() + +/** + \brief 内核解锁(退出服务层临界区) + \param 无 + \return 无 + */ +#define uKernelUnlock() su_kernel_unlocks() + +/** @} */ + +/** + \ingroup 临界区 + \defgroup 中断锁(全局临界区) + \brief 全局的临界区保护,通常会关闭总中断,支持在任意处调用。 + \note CosyOS内核中从来不会关闭总中断,提供此项服务只是为了便于用户
+ 对全局公共资源和程序过程的保护。 + \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 使用条件:
+ 1、MCU必须有 BASEPRI 寄存器;
+ 2、MCU配置中,系统中断配置必须选择 TIMn_IRQHandler + XXX_IRQHandler。 + \note 使用说明:
+ 1、关于npri,例如中断优先级分组选择 NVIC_PriorityGoup_4,那么中断优先级从高到低为 0~15。
+ 如果需要掩蔽(3~15)的中断,npri应输入3。
+ 2、支持嵌套使用,进入临界区与退出临界区必须配对使用。
+ 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接口,串口发送与接收的实现。 + @{ + */ + +/** + \brief DEBUG发送完成 + \param 无 + \return 无 + */ +#define xDebugSend_Complete() s_sign_debugsend = 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队列执行服务时,用户在设置标志位后,
+ 需手动触发PendSV,而后在 pendsv_hook() 中执行服务。 + \param 无 + \return 无 + */ +#define iPendSV_Set() mPendSV_Set() + +/** @} */ + + +/** @} */ +#endif