mirror of
https://gitee.com/cosyos/cosyos.git
synced 2026-08-17 16:52:27 +08:00
950 lines
20 KiB
C
950 lines
20 KiB
C
/**************************************************************************//**
|
|
* @item CosyOS-III Kernel
|
|
* @file sv_task.c
|
|
* @brief 任务服务
|
|
* @details 仅在任务中调用并执行。
|
|
* @author 迟凯峰
|
|
* @version V1.0.4
|
|
* @date 2025.02.26
|
|
******************************************************************************/
|
|
|
|
#include "os_var.h"
|
|
#include "os_api.h"
|
|
#include "sv_com.h"
|
|
#include "sv_task.h"
|
|
|
|
/**
|
|
@addtogroup CosyOS_内核服务
|
|
@{
|
|
*//**
|
|
\defgroup 任务服务
|
|
\brief 仅在任务中调用并执行。
|
|
@{
|
|
*/
|
|
#if MCUCFG_ISA != __ARM__
|
|
/** 调度上锁(进入嵌套任务临界区)*/
|
|
void su_schedule_locks(void)
|
|
{
|
|
s_sign_schedule_forbid = true;
|
|
s_schedulelock_counter++;
|
|
}
|
|
|
|
/** 内核上锁(进入嵌套服务层临界区)*/
|
|
void su_kernel_locks(void)
|
|
{
|
|
mSysIRQ_Disable;
|
|
#if SYSCFG_KERNELLOCKNESTING == __ENABLED__
|
|
s_kernellock_counter++;
|
|
#endif
|
|
}
|
|
|
|
/** 内核上锁(进入非嵌套服务层临界区)*/
|
|
void su_kernel_lock0(void)
|
|
{
|
|
mSysIRQ_Disable;
|
|
}
|
|
|
|
static
|
|
#else
|
|
__STATIC_FORCEINLINE
|
|
#endif
|
|
/** 内核解锁(退出非嵌套服务层临界区)并返回(void *),邮箱、队列专用 */
|
|
void *su_kernel_unlock0_ret(void *p)
|
|
{
|
|
mSysIRQ_Enable;
|
|
return p;
|
|
}
|
|
|
|
/** 调度解锁(退出嵌套任务临界区)*/
|
|
void su_schedule_unlocks(void)
|
|
{
|
|
s_schedulelock_counter--;
|
|
if(!s_schedulelock_counter){
|
|
#if SYSCFG_KERNELLOCKNESTING == __ENABLED__
|
|
if(s_sign_schedule && !s_kernellock_counter){
|
|
#else
|
|
if(s_sign_schedule){
|
|
#endif
|
|
s_sign_schedule_forbid = false;
|
|
mPendSV_Set;
|
|
while(s_sign_schedule);
|
|
}
|
|
else{
|
|
s_sign_schedule_forbid = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** 内核解锁(退出嵌套服务层临界区)*/
|
|
void su_kernel_unlocks(void)
|
|
{
|
|
#if SYSCFG_KERNELLOCKNESTING == __ENABLED__
|
|
s_kernellock_counter--;
|
|
if(s_kernellock_counter) return;
|
|
#endif
|
|
if(s_sign_schedule && !s_sign_schedule_forbid){
|
|
mPendSV_Set;
|
|
mSysIRQ_Enable;
|
|
#if MCUCFG_ISA == __ARM__
|
|
OS_NOPx1;
|
|
#endif
|
|
while(s_sign_schedule);
|
|
}
|
|
else{
|
|
mSysIRQ_Enable;
|
|
}
|
|
}
|
|
|
|
/** 内核解锁(退出嵌套服务层临界区)并返回(void *) */
|
|
void *su_kernel_unlocks_ret(void *p)
|
|
{
|
|
su_kernel_unlocks();
|
|
return p;
|
|
}
|
|
|
|
/** 内核解锁(退出非嵌套服务层临界区)并触发任务调度 */
|
|
void su_kernel_unlock0_psv(void)
|
|
{
|
|
s_sign_schedule = true;
|
|
mPendSV_Set;
|
|
mSysIRQ_Enable;
|
|
#if MCUCFG_ISA == __ARM__
|
|
OS_NOPx1;
|
|
#endif
|
|
while(s_sign_schedule);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* 操作任务
|
|
*/
|
|
|
|
/**
|
|
\brief 启动任务
|
|
\param[in] hhand 任务HAND句柄
|
|
\param[in] status 任务初始状态
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_startup_task(s_taskhand_tsp hhand, s_u8_t status)
|
|
{
|
|
s_task_status0 = status;
|
|
s_task_starter = hhand;
|
|
su_kernel_unlock0_psv();
|
|
return s_startup_code;
|
|
}
|
|
|
|
/**
|
|
\brief 恢复任务
|
|
\param[in] htask 任务句柄
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_resume_task(s_tasknode_tsp htask)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status & OS_STATUS_SUSPENDED){
|
|
sv_resume_task(htask);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
if(htask->status < OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSUSPENDED;
|
|
}
|
|
if(htask->status == OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKSTOPPED;
|
|
}
|
|
if(htask->status == OS_STATUS_DELETED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_DONOTKNOW;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 恢复指定任务并挂起自身任务
|
|
\param[in] htask 任务句柄
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_resume_suspend(s_tasknode_tsp htask)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status & OS_STATUS_SUSPENDED){
|
|
sv_resume_task(htask);
|
|
}
|
|
if(htask->status == OS_STATUS_READY){
|
|
sv_suspend_task(s_task_current);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
if(htask->status < OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTREADY;
|
|
}
|
|
if(htask->status == OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKSTOPPED;
|
|
}
|
|
if(htask->status == OS_STATUS_DELETED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_DONOTKNOW;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 挂起任务
|
|
\param[in] htask 任务句柄
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_suspend_task(s_tasknode_tsp htask)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status < OS_STATUS_SUSPENDED){
|
|
sv_suspend_task(htask);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
if(htask->status & OS_STATUS_SUSPENDED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKSUSPENDED;
|
|
}
|
|
if(htask->status == OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKSTOPPED;
|
|
}
|
|
if(htask->status == OS_STATUS_DELETED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_DONOTKNOW;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 删除任务
|
|
\param[in] htask 任务句柄
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_delete_task(s_tasknode_tsp htask)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status < OS_STATUS_DELETED){
|
|
sv_delete_task(htask);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
if(htask->status == OS_STATUS_DELETED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_DONOTKNOW;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 清除阻塞(状态)
|
|
\param[in] htask 任务句柄
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_clear_block(s_tasknode_tsp htask)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status == OS_STATUS_BLOCKED){
|
|
sv_clear_block(htask);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTBLOCKED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 设置阻塞(时间)
|
|
\param[in] htask 任务句柄
|
|
\param[in] tick 滴答周期(阻塞时间)<br>
|
|
+0:清除阻塞<br>
|
|
~0:无限阻塞
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_set_block(s_tasknode_tsp htask, s_delay_t tick)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status == OS_STATUS_BLOCKED){
|
|
sv_set_block(htask, tick);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTBLOCKED;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 设置任务优先级
|
|
\param[in] htask 任务句柄
|
|
\param[in] npri 新优先级
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_set_taskpri(s_tasknode_tsp htask, s_u8_t npri)
|
|
{
|
|
if(htask == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
if(htask->status < OS_STATUS_STOPPED){
|
|
if(htask->pri != npri){
|
|
sv_set_taskpri(htask, npri);
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_NOERROR;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKPRIUNCHANGED;
|
|
}
|
|
}
|
|
if(htask->status == OS_STATUS_STOPPED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKSTOPPED;
|
|
}
|
|
if(htask->status == OS_STATUS_DELETED){
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_TASKNOTSTARTED;
|
|
}
|
|
else{
|
|
su_kernel_unlocks();
|
|
return OS_ECODE_DONOTKNOW;
|
|
}
|
|
}
|
|
|
|
#if SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__
|
|
/**
|
|
\brief 禅让任务
|
|
\param 无
|
|
\return 无
|
|
*/
|
|
void su_yield_tasking(void)
|
|
{
|
|
su_kernel_locks();
|
|
s_task_current->tc_counter = ~0;
|
|
s_sign_schedule = true;
|
|
su_kernel_unlocks();
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
\brief 自身任务延时
|
|
\param[in] tick 滴答周期(延时时间)<br>
|
|
+0:非法<br>
|
|
~0:无限延时
|
|
\return 无
|
|
*/
|
|
void su_delay(s_delay_t tick)
|
|
{
|
|
s_task_current->timer = tick;
|
|
if(!s_sign_schedule_forbid){ /* 阻塞延时 */
|
|
sv_insert_timer_list();
|
|
su_kernel_unlock0_psv();
|
|
}
|
|
else{ /* 就绪延时 */
|
|
s_sign_ready_delay = true;
|
|
mSysIRQ_Enable;
|
|
while(s_sign_ready_delay);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* 互斥信号量
|
|
*/
|
|
#if SYSCFG_MUTEX == __ENABLED__
|
|
/**
|
|
\brief 获取互斥信号量
|
|
\param[in] hmut 互斥信号量句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_take_mutex(s_mutex_tsp hmut, s_delay_t tick)
|
|
{
|
|
if(!hmut->mutex) goto __RET_TRUE1;
|
|
if(s_task_current == hmut->otask) goto __RET_TRUE2;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_block_list(&hmut->htask);
|
|
if(s_task_current->pri > hmut->otask->pri){
|
|
#if SYSCFG_SAMEPRISCHEDULE
|
|
sv_set_taskpri(hmut->otask, s_task_current->pri);
|
|
#else
|
|
sv_set_taskpri(hmut->otask, SYSCFG_TASKPRIORITY - 1);
|
|
#endif
|
|
}
|
|
s_task_current->blocktype = OS_BLOCKED_MUTEX;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hmut;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hmut = (s_mutex_tsp)s_task_current->handle;
|
|
#endif
|
|
if(!hmut->mutex) goto __RET_TRUE1;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE1:
|
|
hmut->otask = s_task_current;
|
|
hmut->opri = s_task_current->pri;
|
|
|
|
__RET_TRUE2:
|
|
hmut->mutex++;
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
\brief 归还互斥信号量
|
|
\param[in] hmut 互斥信号量句柄
|
|
\return 无
|
|
*/
|
|
void su_back_mutex(s_mutex_tsp hmut)
|
|
{
|
|
if(!hmut->mutex);
|
|
else if(s_task_current == hmut->otask){
|
|
hmut->mutex--;
|
|
if(!hmut->mutex){
|
|
if(s_task_current->pri > hmut->opri){
|
|
sv_set_taskpri(s_task_current, hmut->opri);
|
|
}
|
|
sv_remove_block_list(&hmut->htask);
|
|
}
|
|
}
|
|
su_kernel_unlocks();
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 二值信号量
|
|
*/
|
|
#if SYSCFG_BINARY == __ENABLED__
|
|
/**
|
|
\brief 等待二值信号量
|
|
\param[in] hbin 二值信号量句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_wait_binary(s_binary_tsp hbin, s_delay_t tick)
|
|
{
|
|
if(hbin->binary) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_block_list(&hbin->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_BINARY;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hbin;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hbin = (s_binary_tsp)s_task_current->handle;
|
|
#endif
|
|
if(hbin->binary) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
\brief 获取二值信号量
|
|
\param[in] hbin 二值信号量句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_take_binary(s_binary_tsp hbin, s_delay_t tick)
|
|
{
|
|
if(hbin->binary) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_block_list(&hbin->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_BINARY;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hbin;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hbin = (s_binary_tsp)s_task_current->handle;
|
|
#endif
|
|
if(hbin->binary) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
hbin->binary = false;
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 计数信号量
|
|
*/
|
|
#if SYSCFG_SEMAPHORE == __ENABLED__
|
|
/**
|
|
\brief 获取计数信号量
|
|
\param[in] hsem 计数信号量句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_take_semaphore(s_semaph_tsp hsem, s_delay_t tick)
|
|
{
|
|
if(hsem->counter) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_block_list(&hsem->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_SEMAPHORE;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hsem;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hsem = (s_semaph_tsp)s_task_current->handle;
|
|
#endif
|
|
if(hsem->counter) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
(hsem->counter)--;
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 飞信
|
|
*/
|
|
#if SYSCFG_FETION == __ENABLED__
|
|
/**
|
|
\brief 接收飞信
|
|
\param[in] htbox 信箱句柄
|
|
\return 飞信
|
|
*/
|
|
static m_fetion_t _recv_fetion_(s_tionbox_tsp htbox)
|
|
{
|
|
m_fetion_t tion = htbox->tion;
|
|
htbox->tion = false;
|
|
mSysIRQ_Enable;
|
|
return tion;
|
|
}
|
|
|
|
/**
|
|
\brief 接收飞信
|
|
\param[in] htbox 信箱句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 飞信
|
|
\retval false 失败
|
|
*/
|
|
m_fetion_t su_recv_fetion(s_tionbox_tsp htbox, s_delay_t tick)
|
|
{
|
|
if(htbox->tion) goto __RET_TION;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_block_list(&htbox->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_FETION;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = htbox;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
htbox = (s_tionbox_tsp)s_task_current->handle;
|
|
#endif
|
|
|
|
__RET_TION:
|
|
return _recv_fetion_(htbox);
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 邮箱
|
|
*/
|
|
#if SYSCFG_MAILBOX == __ENABLED__
|
|
/**
|
|
\brief 接收邮件
|
|
\param[in] hmbox 邮箱句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 邮件指针
|
|
\retval NULL 失败
|
|
*/
|
|
void *su_recv_mail(s_mailbox_tsp hmbox, s_delay_t tick)
|
|
{
|
|
if(hmbox->flag) goto __RET_MAIL;
|
|
if(!tick) goto __RET_NULL;
|
|
|
|
sv_insert_block_list(&hmbox->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_MAIL;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hmbox;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hmbox = (s_mailbox_tsp)s_task_current->handle;
|
|
#endif
|
|
if(hmbox->flag) goto __RET_MAIL;
|
|
|
|
__RET_NULL:
|
|
mSysIRQ_Enable;
|
|
return OS_NULL;
|
|
|
|
__RET_MAIL:
|
|
hmbox->flag = false;
|
|
return su_kernel_unlock0_ret(hmbox->mail);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 消息队列
|
|
*/
|
|
#if SYSCFG_MSGQUEUE == __ENABLED__
|
|
/**
|
|
\brief 接收消息
|
|
\param[in] hque 队列句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 消息指针
|
|
\retval NULL 失败
|
|
*/
|
|
void *su_recv_msg(s_queue_tsp hque, s_delay_t tick)
|
|
{
|
|
void *msg;
|
|
hque->mutex = false;
|
|
|
|
if(hque->counter) goto __RECV_MSG;
|
|
if(!tick) goto __RET_NULL;
|
|
|
|
hque->mutex = true;
|
|
sv_insert_block_list(&hque->htask);
|
|
s_task_current->blocktype = OS_BLOCKED_MSG;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hque;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hque = (s_queue_tsp)s_task_current->handle;
|
|
#endif
|
|
hque->mutex = false;
|
|
if(!hque->counter) goto __RET_NULL;
|
|
|
|
__RECV_MSG:
|
|
if(hque->type == __DYNAMIC__){
|
|
msg = sv_recv_msg_dynamic((sd_queue_tsp)hque);
|
|
}
|
|
else{
|
|
msg = sv_recv_msg_static((ss_queue_tsp)hque);
|
|
}
|
|
hque->mutex = true;
|
|
return su_kernel_unlock0_ret(msg);
|
|
|
|
__RET_NULL:
|
|
hque->mutex = true;
|
|
mSysIRQ_Enable;
|
|
return OS_NULL;
|
|
}
|
|
|
|
/**
|
|
\brief 发送消息
|
|
\param[in] hque 队列句柄
|
|
\param[in] msg 消息指针
|
|
\return 错误码
|
|
*/
|
|
s_ecode_t su_send_msg(s_queue_tsp hque, void *msg)
|
|
{
|
|
s_ecode_t _ecode = sv_send_msg(hque, msg);
|
|
su_kernel_unlocks();
|
|
return _ecode;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 事件标志组
|
|
*/
|
|
#if SYSCFG_FLAGGROUP == __ENABLED__
|
|
/**
|
|
\brief 查询标志组
|
|
\param[in] hgrp 标志组句柄
|
|
\param[in] size sizeof(group)
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_query_group(void _STATIC_MEM_ *hgrp, s_u8_t size)
|
|
{
|
|
switch(size){
|
|
case 1: if(*(s_u8_t *)hgrp) goto __RET_TRUE; break;
|
|
case 2: if(*(s_u16_t *)hgrp) goto __RET_TRUE; break;
|
|
case 4: if(*(s_u32_t *)hgrp) goto __RET_TRUE; break;
|
|
}
|
|
su_kernel_unlocks();
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
su_kernel_unlocks();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
\brief 等待标志组_1
|
|
\param[in] hgrp 标志组句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_wait_group_1(s_u8_t _STATIC_MEM_ *hgrp, s_delay_t tick)
|
|
{
|
|
if(*hgrp) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_timer_list();
|
|
s_task_current->blocktype = 1;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hgrp;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hgrp = s_task_current->handle;
|
|
#endif
|
|
if(*hgrp) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
\brief 等待标志组_2
|
|
\param[in] hgrp 标志组句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_wait_group_2(s_u16_t _STATIC_MEM_ *hgrp, s_delay_t tick)
|
|
{
|
|
if(*hgrp) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_timer_list();
|
|
s_task_current->blocktype = 2;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hgrp;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hgrp = s_task_current->handle;
|
|
#endif
|
|
if(*hgrp) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
\brief 等待标志组_4
|
|
\param[in] hgrp 标志组句柄
|
|
\param[in] tick 滴答周期(超时时间)<br>
|
|
+0:立即返回<br>
|
|
~0:无限等待
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_wait_group_4(s_u32_t _STATIC_MEM_ *hgrp, s_delay_t tick)
|
|
{
|
|
if(*hgrp) goto __RET_TRUE;
|
|
if(!tick) goto __RET_FALSE;
|
|
|
|
sv_insert_timer_list();
|
|
s_task_current->blocktype = 4;
|
|
s_task_current->timer = tick;
|
|
#if SYSCFG_MCUCORE == 8051
|
|
s_task_current->handle = hgrp;
|
|
#endif
|
|
su_kernel_unlock0_psv();
|
|
#if SYSCFG_MCUCORE == 8051
|
|
hgrp = s_task_current->handle;
|
|
#endif
|
|
if(*hgrp) goto __RET_TRUE;
|
|
|
|
__RET_FALSE:
|
|
mSysIRQ_Enable;
|
|
return false;
|
|
|
|
__RET_TRUE:
|
|
mSysIRQ_Enable;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
* 动态内存
|
|
*/
|
|
#if SYSCFG_DYNMEMMGE == __ENABLED__
|
|
/**
|
|
\brief uxalloc
|
|
\param[in] p
|
|
\return 指针
|
|
\retval NULL 失败
|
|
*/
|
|
void _MALLOC_MEM_ *su_xalloc(void _MALLOC_MEM_ *p)
|
|
{
|
|
su_kernel_unlocks();
|
|
return p;
|
|
}
|
|
|
|
/**
|
|
\brief 初始化线程内存池
|
|
\param[in] hmem 线程内存句柄
|
|
\param[in] size 内存池大小
|
|
\return 结果
|
|
\retval false 失败
|
|
\retval true 成功
|
|
*/
|
|
bool su_init_mempool(s_thrmem_tsp hmem, size_t size)
|
|
{
|
|
hmem->head = hmem->move = (void _MALLOC_MEM_ *)s_malloc(size);
|
|
if(hmem->head == OS_NULL){
|
|
su_kernel_unlocks();
|
|
return false;
|
|
}
|
|
else{
|
|
hmem->size = size;
|
|
su_kernel_unlocks();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
\brief 线程内存分配
|
|
\param[in] hmem 线程内存句柄
|
|
\param[in] size 内存块大小
|
|
\return 指针
|
|
\retval NULL 失败
|
|
*/
|
|
void _MALLOC_MEM_ *su_talloc(s_thrmem_tsp hmem, size_t size)
|
|
{
|
|
if(hmem->head == OS_NULL || (size_t)hmem->move - (size_t)hmem->head + size > hmem->size){
|
|
return OS_NULL;
|
|
}
|
|
else{
|
|
void _MALLOC_MEM_ *r = hmem->move;
|
|
hmem->move = (s_u8_t _MALLOC_MEM_ *)hmem->move + size;
|
|
return r;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/** @} */
|
|
/** @} */
|