1.uC/OS-III的时间管理函数的主要工作是改变当前任务的状态,把任务添加到时钟节拍轮中,同时把任务从任务就绪表中删除,最后执行调度程序。
2.OSTimeDly()函数
OSTimeDly()函数的源代码位于os_time.c文件,79行 - 138行
void OSTimeDly (OS_TICK dly, // 延时长度
OS_OPT opt, // 选项:相对模式、周期模式、绝对模式
OS_ERR *p_err) // 函数返回的错误代码
{
CPU_SR_ALLOC(); // 宏定义,声明变量cpu_sr,用来存储CPU的状态寄存器的值
#ifdef OS_SAFETY_CRITICAL // ???
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { // 不允许从ISR中调用该函数
*p_err = OS_ERR_TIME_DLY_ISR;
return;
}
#endif
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { // 在锁定调度器的情况下,不允许延时
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
switch (opt) {
case OS_OPT_TIME_DLY:
case OS_OPT_TIME_TIMEOUT:
case OS_OPT_TIME_PERIODIC:
if (dly == (OS_TICK)0u) { // 0表示不延时
*p_err = OS_ERR_TIME_ZERO_DLY;
return;
}
break;
case OS_OPT_TIME_MATCH:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
OS_CRITICAL_ENTER(); // 进入临界区
OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY; // 更改当前任务的状态
OS_TickListInsert(OSTCBCurPtr, // 把当前任务添加到时钟节拍轮中
dly,
opt,
p_err);
if (*p_err != OS_ERR_NONE) {
OS_CRITICAL_EXIT_NO_SCHED(); // 退出临界区
return;
}
OS_RdyListRemove(OSTCBCurPtr); // 从任务就绪表中删除当前任务
OS_CRITICAL_EXIT_NO_SCHED(); // 退出临界区
OSSched(); // 执行任务调度
*p_err = OS_ERR_NONE;
}
3.OSTimeDlyHMSM()函数
OSTimeDlyHMSM()函数的源代码位于os_time.c文件,198行 - 323行
#if OS_CFG_TIME_DLY_HMSM_EN > 0u // 允许该函数
void OSTimeDlyHMSM (CPU_INT16U hours,
CPU_INT16U minutes,
CPU_INT16U seconds,
CPU_INT32U milli,
OS_OPT opt,
OS_ERR *p_err)
{
#if OS_CFG_ARG_CHK_EN > 0u // 允许检测参数
CPU_BOOLEAN opt_invalid;
CPU_BOOLEAN opt_non_strict;
#endif
OS_OPT opt_time;
OS_RATE_HZ tick_rate;
OS_TICK ticks;
CPU_SR_ALLOC(); // 宏定义,声明变量cpu_sr,用来临时存储CPU状态寄存器的值
#ifdef OS_SAFETY_CRITICAL // ???
if (p_err == (OS_ERR *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
if (OSIntNestingCtr > (OS_NESTING_CTR)0u) { // 不允许在ISR中调用该函数
*p_err = OS_ERR_TIME_DLY_ISR;
return;
}
#endif
if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0u) { // 当调度器锁定的时候不允许延时
*p_err = OS_ERR_SCHED_LOCKED;
return;
}
opt_time = opt & OS_OPT_TIME_MASK; // 这里检索的仅仅是时间
switch (opt_time) {
case OS_OPT_TIME_DLY:
case OS_OPT_TIME_TIMEOUT:
case OS_OPT_TIME_PERIODIC:
if (milli == (CPU_INT32U)0u) { // 确保时间不为0
if (seconds == (CPU_INT16U)0u) {
if (minutes == (CPU_INT16U)0u) {
if (hours == (CPU_INT16U)0u) {
*p_err = OS_ERR_TIME_ZERO_DLY;
return;
}
}
}
}
break;
case OS_OPT_TIME_MATCH:
break;
default:
*p_err = OS_ERR_OPT_INVALID;
return;
}
#if OS_CFG_ARG_CHK_EN > 0u // 允许参数检测
opt_invalid = DEF_BIT_IS_SET_ANY(opt, ~OS_OPT_TIME_OPTS_MASK);
if (opt_invalid == DEF_YES) {
*p_err = OS_ERR_OPT_INVALID;
return;
}
opt_non_strict = DEF_BIT_IS_SET(opt, OS_OPT_TIME_HMSM_NON_STRICT);
if (opt_non_strict != DEF_YES) { // 严格的参数检测
if (milli > (CPU_INT32U)999u) { // 毫秒(milli)不允许超过999
*p_err = OS_ERR_TIME_INVALID_MILLISECONDS;
return;
}
if (seconds > (CPU_INT16U)59u) { // 秒(seconds)不允许超过59
*p_err = OS_ERR_TIME_INVALID_SECONDS;
return;
}
if (minutes > (CPU_INT16U)59u) { // 分钟(minutes)不允许超过59
*p_err = OS_ERR_TIME_INVALID_MINUTES;
return;
}
if (hours > (CPU_INT16U)99u) { // 小时(hours)不允许超过99
*p_err = OS_ERR_TIME_INVALID_HOURS;
return;
}
} else { // 不严格的参数检测
if (minutes > (CPU_INT16U)9999u) { // 分钟(minutes)不允许超过9999
*p_err = OS_ERR_TIME_INVALID_MINUTES;
return;
}
if (hours > (CPU_INT16U)999u) { // 小时(hours)不允许超过999
*p_err = OS_ERR_TIME_INVALID_HOURS;
return;
}
}
#endif
tick_rate = OSCfg_TickRate_Hz; // 计算所需要的延迟长度
ticks = ((OS_TICK)hours * (OS_TICK)3600u + (OS_TICK)minutes * (OS_TICK)60u + (OS_TICK)seconds) * tick_rate
+ (tick_rate * ((OS_TICK)milli + (OS_TICK)500u / tick_rate)) / (OS_TICK)1000u;
if (ticks > (OS_TICK)0u) {
OS_CRITICAL_ENTER(); // 进入临界区
OSTCBCurPtr->TaskState = OS_TASK_STATE_DLY; // 任务的状态改为延时
OS_TickListInsert(OSTCBCurPtr,
ticks,
opt_time,
p_err); // 添加到时钟节拍列表中
if (*p_err != OS_ERR_NONE) { // 检测返错误码
OS_CRITICAL_EXIT_NO_SCHED();
return;
}
OS_RdyListRemove(OSTCBCurPtr); // 从任务就绪表中删除该任务
OS_CRITICAL_EXIT_NO_SCHED(); // 退出临界区
OSSched(); // 执行任务调度
*p_err = OS_ERR_NONE;
} else {
*p_err = OS_ERR_TIME_ZERO_DLY;
}
}
#endif