/**************************************************************************//** * @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 滴答周期(阻塞时间)
+0:清除阻塞
~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 滴答周期(阻塞时间)
+0:清除阻塞
~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
0:上锁
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