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

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
/** @} */
/** @} */