Files
cosyos/System/sv_com.c
零中断延迟的RTOS beda3ca2f4 update 内核文件.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2026-02-01 19:00:21 +00:00

862 lines
20 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**************************************************************************//**
* @item CosyOS-III Kernel
* @file sv_com.c
* @brief 内核公共服务
* @details 在服务层临界区中调用并执行。
* @author 迟凯峰
* @version V2.3.0
* @date 2026.02.01
******************************************************************************/
#include "os_var.h"
#include "os_api.h"
#include "sv_com.h"
#if (SYSCFG_MCUCORE == 8051)
#pragma NOAREGS /* 相对寄存器访问 for C51 */
#endif
/**
\brief 加入就绪
\details 任务由非就绪状态变为就绪状态的相关调整。
\param[in] htask 任务句柄
\return 无
*/
void sa_add_ready(s_tasknode_tsp htask)
{
s_u8_t pri = htask->pri;
if(pri > s_task_current->pri){
s_sign_schedule.every[1] = false;
}
#if (SYSCFG_SAMEPRISCHEDULE)
#if (SYSCFG_SAMEPRISCHEDULE == __TIMESHARING__)
htask->tc_counter = 0;
#endif
if(s_task_ready_count[pri]++) return;
#endif
if(true){
s_u8_t bit_index = (pri & 7);
#if (SYSCFG_TASKPRIORITY > 64)
s_u8_t table_index = (pri >> 6);
s_u8_t bytes_index = (pri & 63) >> 3;
s_task_table_index |= (1 << table_index);
s_task_bytes_index[table_index] |= (1 << bytes_index);
s_task_ready_table[table_index][bytes_index] |= (1 << bit_index);
#elif (SYSCFG_TASKPRIORITY > 8)
s_u8_t bytes_index = (pri >> 3);
s_task_bytes_index |= (1 << bytes_index);
s_task_ready_table[bytes_index] |= (1 << bit_index);
#else
s_task_ready_table |= (1 << bit_index);
#endif
}
}
/**
\brief 移除就绪
\details 任务由就绪状态变为非就绪状态的相关调整。
\param[in] htask 任务句柄
\return 无
*/
void sa_remove_ready(s_tasknode_tsp htask)
{
s_u8_t pri = htask->pri;
if(htask == s_task_current){
s_sign_schedule.every[1] = false;
}
#if (SYSCFG_SAMEPRISCHEDULE)
if(--s_task_ready_count[pri]) return;
#endif
if(true){
s_u8_t bit_index = (pri & 7);
#if (SYSCFG_TASKPRIORITY > 64)
s_u8_t table_index = (pri >> 6);
s_u8_t bytes_index = (pri & 63) >> 3;
s_task_ready_table[table_index][bytes_index] &= ~(1 << bit_index);
if(!s_task_ready_table[table_index][bytes_index]){
s_task_bytes_index[table_index] &= ~(1 << bytes_index);
if(!s_task_bytes_index[table_index]){
s_task_table_index &= ~(1 << table_index);
}
}
#elif (SYSCFG_TASKPRIORITY > 8)
s_u8_t bytes_index = (pri >> 3);
s_task_ready_table[bytes_index] &= ~(1 << bit_index);
if(!s_task_ready_table[bytes_index]){
s_task_bytes_index &= ~(1 << bytes_index);
}
#else
s_task_ready_table &= ~(1 << bit_index);
#endif
}
}
/**
\brief 插入至任务队列
\details 任务节点插入至任务队列尾。
\param[in] htask 任务句柄
\return 无
*/
void sa_insert_taskque(s_tasknode_tsp htask)
{
s_u8_t pri = htask->pri;
#if (SYSCFG_SAMEPRISCHEDULE)
if(s_task_queue[pri] == OS_NULL){
s_task_queue[pri] = htask->last = htask->next = htask;
}
else{
htask->last = s_task_queue[pri]->last;
htask->next = s_task_queue[pri];
s_task_queue[pri]->last->next = htask;
s_task_queue[pri]->last = htask;
}
#else
s_task_queue[pri] = htask;
#endif
}
/**
\brief 移除从任务队列
\details 从任务队列中移除任务节点。
\param[in] htask 任务句柄
\return 无
*/
void sa_remove_taskque(s_tasknode_tsp htask)
{
s_u8_t pri = htask->pri;
#if (SYSCFG_SAMEPRISCHEDULE)
if(s_task_queue[pri] == s_task_queue[pri]->last){
s_task_queue[pri] = OS_NULL;
}
else{
htask->last->next = htask->next;
htask->next->last = htask->last;
if(htask == s_task_queue[pri]){
s_task_queue[pri] = htask->next;
}
}
#else
s_task_queue[pri] = OS_NULL;
#endif
}
/**
\brief 插入至阻塞链表
\details 当前任务节点插入至阻塞链表尾。
\param[in] h2task 指向链表头的指针
\return 无
*/
void sa_insert_blocklist(s_tasknode_tsp *h2task)
{
s_tasknode_tsp htask = *h2task;
if(htask == OS_NULL){
*h2task = s_task_current->last_b = s_task_current->next_b = s_task_current;
}
else{
s_task_current->last_b = htask->last_b;
s_task_current->next_b = htask;
htask->last_b->next_b = s_task_current;
htask->last_b = s_task_current;
}
}
/**
\brief 移除从阻塞链表
\details 从阻塞链表中移除任务节点。
\param[in] htask 任务句柄
\return 无
*/
void sa_remove_blocklist(s_tasknode_tsp htask)
{
s_tasknode_tsp *h2task = (s_tasknode_tsp *)htask->handle;
if(htask == htask->next_b){
*h2task = OS_NULL;
}
else{
htask->last_b->next_b = htask->next_b;
htask->next_b->last_b = htask->last_b;
if(htask == *h2task){
*h2task = htask->next_b;
}
}
// htask->last_b =
htask->next_b = OS_NULL;
}
/**
\brief 插入至定时器链表
\details 任务节点插入至定时器链表尾。
\param[in] htask 任务句柄
\param[in] tick 滴答周期(阻塞时间)
\return 无
*/
void sa_insert_timerlist(s_tasknode_tsp htask, s_delay_t tick)
{
s_u8_t m = tick & (OS_TIMESLOTNUM - 1UL);
s_u8_t i =
htask->timer.slots = (s_timer_pointer + m) & (OS_TIMESLOTNUM - 1UL);
htask->timer.cycle = (tick >> OS_TIMESLOTBITS) - !m;
if(s_timer_list[i] == OS_NULL){
s_timer_list[i] = htask->last_t = htask->next_t = htask;
}
else{
htask->last_t = s_timer_list[i]->last_t;
htask->next_t = s_timer_list[i];
s_timer_list[i]->last_t->next_t = htask;
s_timer_list[i]->last_t = htask;
}
}
/**
\brief 移除从定时器链表
\details 从定时器链表中移除任务节点。
\param[in] htask 任务句柄
\return 无
*/
void sa_remove_timerlist(s_tasknode_tsp htask)
{
s_u8_t i = htask->timer.slots;
if(htask == htask->next_t){
s_timer_list[i] = OS_NULL;
}
else{
htask->last_t->next_t = htask->next_t;
htask->next_t->last_t = htask->last_t;
if(htask == s_timer_list[i]){
s_timer_list[i] = htask->next_t;
}
}
// htask->last_t =
htask->next_t = OS_NULL;
}
/**
\brief 阻塞变浮动
\details 阻塞链表中的任务全部由阻塞状态变为浮动状态。
\param[in] htask 任务句柄
\return 无
*/
void sa_block_to_float(s_tasknode_tsp htask)
{
s_tasknode_tsp htemp = htask;
while(true){
if(htemp->status == OS_STATUS_BLOCKED){
htemp->status = OS_STATUS_FLOATING;
sa_add_ready(htemp);
}
else if(htemp->status == (OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED)){
htemp->status = OS_STATUS_FLOATING | OS_STATUS_SUSPENDED;
}
#if (SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__)
// if(htemp->blocktype == OS_BLOCKED_MUTEX){
htemp->link = OS_NULL;
// }
#endif
htemp = htemp->next_b;
if(htask == htemp){
break;
}
}
}
/**
\brief 浮动变阻塞
\details 阻塞链表中的任务全部由浮动状态变为阻塞状态。
\param[in] htask 任务句柄
\return 无
*/
void sa_float_to_block(s_tasknode_tsp htask)
{
s_tasknode_tsp htemp = htask;
while(true){
if(htemp->status == OS_STATUS_FLOATING){
htemp->status = OS_STATUS_BLOCKED;
sa_remove_ready(htemp);
}
else if(htemp->status == (OS_STATUS_FLOATING | OS_STATUS_SUSPENDED)){
htemp->status = OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED;
}
#if (SYSCFG_SAMEPRISCHEDULE && SYSCFG_MUTEX == __ENABLED__)
// if(htemp->blocktype == OS_BLOCKED_MUTEX){
htemp->link = s_task_current;
// }
#endif
htemp = htemp->next_b;
if(htask == htemp){
break;
}
}
}
/**
\brief 阻塞变就绪
\details 阻塞链表中的任务由阻塞状态变为就绪状态。
\param[in] htask 任务句柄
\return 无
*/
void sa_block_to_ready(s_tasknode_tsp htask)
{
if(htask->status == OS_STATUS_BLOCKED){
htask->status = OS_STATUS_READY;
sa_add_ready(htask);
}
else if(htask->status == (OS_STATUS_BLOCKED | OS_STATUS_SUSPENDED)){
htask->status = OS_STATUS_READY | OS_STATUS_SUSPENDED;
}
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
}
/**
\brief 恢复任务
\param[in] htask 任务句柄
\return 无
*/
void sa_resume_task(s_tasknode_tsp htask)
{
htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
if(htask->status <= OS_STATUS_FLOATING){
sa_add_ready(htask);
}
}
/**
\brief 挂起任务
\param[in] htask 任务句柄
\return 无
*/
void sa_suspend_task(s_tasknode_tsp htask)
{
if(htask->status <= OS_STATUS_FLOATING){
sa_remove_ready(htask);
}
htask->status |= OS_STATUS_SUSPENDED;
}
/**
\brief 停止任务
\param[in] htask 任务句柄
\return 无
*/
__NOINLINE void sa_stop_task(s_tasknode_tsp htask)
{
if(htask->status <= OS_STATUS_FLOATING){
sa_remove_ready(htask);
}
htask->status = OS_STATUS_STOPPED;
if(htask->next_b != OS_NULL){
sa_remove_blocklist(htask);
}
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
}
/**
\brief 释放任务内存
\details 动态创建的任务被删除,需释放相应的动态内存。
\param[in] htask 任务句柄
\return 无
*/
__NOINLINE void sa_free_task(s_tasknode_tsp htask)
{
s_free(htask->bsp);
*htask->dualhandle = OS_NULL;
s_free(htask);
}
/**
\brief 删除任务
\param[in] htask 任务句柄
\return 无
*/
__NOINLINE void sa_delete_task(s_tasknode_tsp htask)
{
if(htask->status <= OS_STATUS_FLOATING){
sa_remove_ready(htask);
}
htask->status = OS_STATUS_DELETED;
if(htask->next_b != OS_NULL){
sa_remove_blocklist(htask);
}
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
sa_remove_taskque(htask);
s_task_queue_count--;
if(htask->create){
#if (SYSCFG_SAFERUNTIME == __ENABLED__)
if(htask->next_o == OS_NULL)
#endif
sa_free_task(htask);
}
}
/**
\brief 清除阻塞(状态)
\param[in] htask 任务句柄
\return 无
*/
void sa_clear_block(s_tasknode_tsp htask)
{
if(htask->status == OS_STATUS_BLOCKED){
sa_add_ready(htask);
}
htask->status = OS_STATUS_READY;
if(htask->next_b != OS_NULL){
sa_remove_blocklist(htask);
}
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
}
/**
\brief 设置阻塞(时间)
\param[in] htask 任务句柄
\param[in] tick 滴答周期(阻塞时间)<br>
+0清除阻塞<br>
~0无限阻塞
\return 无
*/
void sa_set_block(s_tasknode_tsp htask, s_delay_t tick)
{
if(!tick){
sa_clear_block(htask);
}
else{
if(htask->next_t != OS_NULL){
sa_remove_timerlist(htask);
}
if(~tick){
sa_insert_timerlist(htask, tick);
}
}
}
/**
\brief 设置任务优先级
\param[in] htask 任务句柄
\param[in] npri 新优先级
\return 无
*/
void sa_set_taskpri(s_tasknode_tsp htask, s_u8_t npri)
{
sa_remove_taskque(htask);
if(htask->status <= OS_STATUS_FLOATING){
sa_remove_ready(htask);
htask->pri = npri;
sa_add_ready(htask);
}
else{
htask->pri = npri;
}
sa_insert_taskque(htask);
}
/**
\brief 清除就绪延时
\param 无
\return 无
*/
void sc_clear_delay(void)
{
if(s_sign_delay){
s_sign_delay = false;
if(s_task_current->next_t != OS_NULL){
sa_remove_timerlist(s_task_current);
}
}
}
/**
\brief 恢复任务
\param[in] htask 任务句柄
\return 错误码
*/
s_ecode_t sc_resume_task(s_tasknode_tsp htask)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status & OS_STATUS_SUSPENDED){
sa_resume_task(htask);
return OS_ECODE_NOERROR;
}
if(htask->status < OS_STATUS_STOPPED){
return OS_ECODE_TASKNOTSUSPENDED;
}
if(htask->status == OS_STATUS_STOPPED){
return OS_ECODE_TASKSTOPPED;
}
if(htask->status == OS_STATUS_DELETED){
return OS_ECODE_TASKNOTSTARTED;
}
else{
return OS_ECODE_DONOTKNOW;
}
}
/**
\brief 挂起任务
\param[in] htask 任务句柄
\return 错误码
*/
s_ecode_t sc_suspend_task(s_tasknode_tsp htask)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status < OS_STATUS_SUSPENDED){
sa_suspend_task(htask);
return OS_ECODE_NOERROR;
}
if(htask->status & OS_STATUS_SUSPENDED){
return OS_ECODE_TASKSUSPENDED;
}
if(htask->status == OS_STATUS_STOPPED){
return OS_ECODE_TASKSTOPPED;
}
if(htask->status == OS_STATUS_DELETED){
return OS_ECODE_TASKNOTSTARTED;
}
else{
return OS_ECODE_DONOTKNOW;
}
}
/**
\brief 删除任务
\param[in] htask 任务句柄
\return 错误码
*/
s_ecode_t sc_delete_task(s_tasknode_tsp htask)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status < OS_STATUS_DELETED){
sa_delete_task(htask);
return OS_ECODE_NOERROR;
}
if(htask->status == OS_STATUS_DELETED){
return OS_ECODE_TASKNOTSTARTED;
}
else{
return OS_ECODE_DONOTKNOW;
}
}
/**
\brief 清除阻塞(状态)
\param[in] htask 任务句柄
\return 错误码
*/
s_ecode_t sc_clear_block(s_tasknode_tsp htask)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status == OS_STATUS_FLOATING || htask->status == OS_STATUS_BLOCKED){
sa_clear_block(htask);
return OS_ECODE_NOERROR;
}
else{
return OS_ECODE_TASKNOTBLOCKED;
}
}
/**
\brief 设置阻塞(时间)
\param[in] htask 任务句柄
\param[in] tick 滴答周期(阻塞时间)<br>
+0清除阻塞<br>
~0无限阻塞
\return 错误码
*/
s_ecode_t sc_set_block(s_tasknode_tsp htask, s_delay_t tick)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status == OS_STATUS_FLOATING || htask->status == OS_STATUS_BLOCKED){
sa_set_block(htask, tick);
return OS_ECODE_NOERROR;
}
else{
return OS_ECODE_TASKNOTBLOCKED;
}
}
/**
\brief 设置任务优先级
\param[in] htask 任务句柄
\param[in] npri 新优先级
\return 错误码
*/
s_ecode_t sc_set_taskpri(s_tasknode_tsp htask, s_u8_t npri)
{
if(htask == OS_NULL){
return OS_ECODE_TASKNOTSTARTED;
}
if(htask->status < OS_STATUS_STOPPED){
if(htask->pri != npri){
sa_set_taskpri(htask, npri);
return OS_ECODE_NOERROR;
}
else{
return OS_ECODE_TASKPRIUNCHANGED;
}
}
if(htask->status == OS_STATUS_STOPPED){
return OS_ECODE_TASKSTOPPED;
}
if(htask->status == OS_STATUS_DELETED){
return OS_ECODE_TASKNOTSTARTED;
}
else{
return OS_ECODE_DONOTKNOW;
}
}
#if (SYSCFG_BINARY == __ENABLED__)
/**
\brief 写二值信号量
\param[in] hbin 二值信号量句柄
\param[in] value <br>
0上锁<br>
1给予
\return 无
*/
void sc_write_binary(s_binary_tsp hbin, bool value)
{
hbin->binary = value;
if(!value) return;
if(hbin->htask != OS_NULL){
sa_block_to_float(hbin->htask);
}
}
#endif
#if (SYSCFG_SEMAPHORE == __ENABLED__)
/**
\brief 给予计数信号量
\param[in] hsem 计数信号量句柄
\return 无
*/
void sc_give_semaph(s_semaph_tsp hsem)
{
s_semsize_t counter = hsem->counter;
if(counter < hsem->maximum){
hsem->counter = counter + 1;
}
if(!counter && hsem->htask != OS_NULL){
sa_block_to_float(hsem->htask);
}
}
#endif
#if (SYSCFG_FETION == __ENABLED__)
/**
\brief 发送飞信
\param[in] htbox 信箱句柄
\param[in] tion 飞信
\return 无
*/
void sc_send_fetion(s_tionbox_tsp htbox, m_fetion_t tion)
{
s_tasknode_tsp htask = htbox->htask;
htbox->tion = tion;
if(htask != OS_NULL){
sa_block_to_ready(htask);
htbox->htask =
// htask->last_b =
htask->next_b = OS_NULL;
}
}
#endif
#if (SYSCFG_MAILBOX == __ENABLED__)
/**
\brief 发送邮件
\param[in] hmbox 邮箱句柄
\param[in] mail 邮件指针
\return 无
*/
void sc_send_mail(s_mailbox_tsp hmbox, void *mail)
{
s_tasknode_tsp htask = hmbox->htask;
hmbox->flag = false;
hmbox->mail = mail;
hmbox->flag = true;
if(htask != OS_NULL){
sa_block_to_ready(htask);
hmbox->htask =
// htask->last_b =
htask->next_b = OS_NULL;
}
}
#endif
#if (SYSCFG_MSGQUEUE == __ENABLED__)
/**
\brief 发送消息
\param[in] hque 队列句柄
\param[in] msg 消息指针
\return 错误码
*/
s_ecode_t sc_send_msg(s_msgque_tsp hque, void *msg)
{
s_tasknode_tsp htask;
hque->mutex = false;
if(hque->counter == hque->len){
#if (SYSCFG_DEBUGGING == __ENABLED__)
s_alarm.overflow_msgqueue = true;
#endif
hque->mutex = true;
return OS_ECODE_OVERFLOW_MSGQUEUE;
}
if(hque->type == __DYNAMIC__){
s_msgnode_tsp hmsg = OS_NULL;
hmsg = (s_msgnode_tsp)s_malloc(sizeof(s_msgnode_ts));
if(hmsg == OS_NULL){
#if (SYSCFG_DEBUGGING == __ENABLED__)
s_fault.mallocfailed_msgnode = true;
#endif
hque->mutex = true;
return OS_ECODE_MALLOCFAIL_MSGNODE;
}
hmsg->msg = msg;
hmsg->next = OS_NULL;
hmsg->last = ((s_dynque_tsp)hque)->tail;
if(((s_dynque_tsp)hque)->tail != OS_NULL){
((s_dynque_tsp)hque)->tail->next = hmsg;
}
((s_dynque_tsp)hque)->tail = hmsg;
if(((s_dynque_tsp)hque)->head == OS_NULL){
((s_dynque_tsp)hque)->head = hmsg;
}
}
else{
if(((s_staque_tsp)hque)->tail < ((s_staque_tsp)hque)->base + hque->len - 1){
((s_staque_tsp)hque)->tail++;
}
else{
((s_staque_tsp)hque)->tail = ((s_staque_tsp)hque)->base;
}
*((s_staque_tsp)hque)->tail = msg;
}
hque->counter++;
htask = hque->htask;
if(htask != OS_NULL){
sa_block_to_ready(htask);
hque ->htask =
// htask->last_b =
htask->next_b = OS_NULL;
}
hque->mutex = true;
return OS_ECODE_NOERROR;
}
/**
\brief 接收消息(静态队列)
\param[in] hque 队列句柄
\return 消息指针
\note 本页中唯一一个还有可能被中断本地服务调用的公共函数。
*/
void *sc_recv_msg_staque(s_staque_tsp hque)
{
void *msg;
if(hque->mode == __QUE_LIFO__){
msg = *hque->tail;
if(hque->tail > hque->base){
hque->tail--;
}
else{
hque->tail = hque->base + hque->len - 1;
}
}
else{
msg = *hque->head;
if(hque->head < hque->base + hque->len - 1){
hque->head++;
}
else{
hque->head = hque->base;
}
}
hque->counter--;
return msg;
}
/**
\brief 接收消息(动态队列)
\param[in] hque 队列句柄
\return 消息指针
*/
void *sc_recv_msg_dynque(s_dynque_tsp hque)
{
void *msg;
s_msgnode_tsp hmsg;
if(hque->mode == __QUE_LIFO__){
hmsg = hque->tail;
msg = hmsg->msg;
hmsg = hmsg->last;
s_free(hque->tail);
hque->tail = hmsg;
if(hmsg == OS_NULL){
hque->head = OS_NULL;
}
else{
hmsg->next = OS_NULL;
}
}
else{
hmsg = hque->head;
msg = hmsg->msg;
hmsg = hmsg->next;
s_free(hque->head);
hque->head = hmsg;
if(hmsg == OS_NULL){
hque->tail = OS_NULL;
}
else{
hmsg->last = OS_NULL;
}
}
hque->counter--;
return msg;
}
#endif
#if (OS_TIMINTTOTAL > 0)
/**
\brief 定时中断
\param[in] tmid 定时中断定时器ID
\param[in] tick 滴答周期(定时时间)
\return 无
*/
void sc_timint(s_u8_t tmid, s_timint_t tick)
{
s_timint_handle[tmid]->timer
= s_timint_handle[tmid]->reload
= tick;
}
#endif
#if (OS_TIMQRYTOTAL > 0)
/**
\brief 定时查询
\param[in] tmid 定时查询定时器ID
\param[in] tick 滴答周期(定时时间)
\return 无
*/
void sc_timqry(s_u8_t tmid, s_timqry_t tick)
{
s_timqry_handle[tmid]->timer
= s_timqry_handle[tmid]->reload
= tick;
}
#endif