Files
cosyos/System/sv_com.c
T
零中断延迟的RTOS b68a588fd9 update System/sv_com.c.
Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
2025-04-11 06:34:49 +00:00

608 lines
14 KiB
C

/**************************************************************************//**
* @item CosyOS-III Kernel
* @file sv_com.c
* @brief 内核服务公共函数
* @details 在服务层临界区中,由内核服务调用。
* @author 迟凯峰
* @version V1.2.1
* @date 2025.04.11
******************************************************************************/
#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 sv_insert_task_queue(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 sv_remove_task_queue(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] htask 任务句柄
\return 无
*/
void sv_task_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 |= s_task_map_mask[table_index];
s_task_bytes_index[table_index] |= s_task_map_mask[bytes_index];
s_task_ready_table[table_index][bytes_index] |= s_task_map_mask[bit_index];
#elif SYSCFG_TASKPRIORITY > 8
s_u8_t bytes_index = (pri >> 3);
s_task_bytes_index |= s_task_map_mask[bytes_index];
s_task_ready_table[bytes_index] |= s_task_map_mask[bit_index];
#else
s_task_ready_table |= s_task_map_mask[bit_index];
#endif
}
}
/**
\brief 移除就绪
\details 任务由就绪状态变为非就绪状态的相关调整。
\param[in] htask 任务句柄
\return 无
*/
void sv_task_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] &= ~s_task_map_mask[bit_index];
if(!s_task_ready_table[table_index][bytes_index]){
s_task_bytes_index[table_index] &= ~s_task_map_mask[bytes_index];
if(!s_task_bytes_index[table_index]){
s_task_table_index &= ~s_task_map_mask[table_index];
}
}
#elif SYSCFG_TASKPRIORITY > 8
s_u8_t bytes_index = (pri >> 3);
s_task_ready_table[bytes_index] &= ~s_task_map_mask[bit_index];
if(!s_task_ready_table[bytes_index]){
s_task_bytes_index &= ~s_task_map_mask[bytes_index];
}
#else
s_task_ready_table &= ~s_task_map_mask[bit_index];
#endif
}
}
/**
\brief 释放任务内存
\details 动态创建的任务被删除,需释放相应的动态内存。
\param[in] htask 任务句柄
\return 无
*/
void sv_free_task(s_tasknode_tsp htask)
{
s_free(htask->bsp);
*htask->dualhandle = OS_NULL;
s_free(htask);
}
/**
\brief 恢复任务
\param[in] htask 任务句柄
\return 无
*/
void sv_resume_task(s_tasknode_tsp htask)
{
htask->status &= (~OS_STATUS_SUSPENDED & 0xFF);
if(htask->status == OS_STATUS_READY){
sv_task_add_ready(htask);
}
}
/**
\brief 挂起任务
\param[in] htask 任务句柄
\return 无
*/
void sv_suspend_task(s_tasknode_tsp htask)
{
if(htask->status == OS_STATUS_READY){
sv_task_remove_ready(htask);
}
htask->status |= OS_STATUS_SUSPENDED;
}
/**
\brief 删除任务
\param[in] htask 任务句柄
\return 无
*/
void sv_delete_task(s_tasknode_tsp htask)
{
if(htask->status == OS_STATUS_READY){
sv_task_remove_ready(htask);
}
htask->status = OS_STATUS_DELETED;
sv_remove_task_queue(htask);
s_task_queue_count--;
if(htask->create && htask->next_b == OS_NULL && htask->next_t == OS_NULL){
sv_free_task(htask);
}
}
/**
\brief 清除阻塞(状态)
\param[in] htask 任务句柄
\return 无
*/
void sv_clear_block(s_tasknode_tsp htask)
{
htask->status = OS_STATUS_READY;
////htask->timer = 0;
sv_task_add_ready(htask);
if(htask->next_b != OS_NULL){
sv_remove_block_list(htask);
}
}
/**
\brief 设置阻塞(时间)
\param[in] htask 任务句柄
\param[in] tick 滴答周期(阻塞时间)<br>
+0:清除阻塞<br>
~0:无限阻塞
\return 无
*/
void sv_set_block(s_tasknode_tsp htask, s_delay_t tick)
{
if(!tick){
sv_clear_block(htask);
}
else{
if(~tick){
if(htask->next_t == OS_NULL){
htask->next_t = s_list_timer;
s_list_timer = htask;
}
}
htask->timer = tick;
}
}
/**
\brief 设置任务优先级
\param[in] htask 任务句柄
\param[in] npri 新优先级
\return 无
*/
void sv_set_taskpri(s_tasknode_tsp htask, s_u8_t npri)
{
sv_remove_task_queue(htask);
if(htask->status == OS_STATUS_READY){
sv_task_remove_ready(htask);
htask->pri = npri;
sv_task_add_ready(htask);
}
else{
htask->pri = npri;
}
sv_insert_task_queue(htask);
}
/**
\brief 移除从阻塞链表
\param[in] htask 任务句柄
\return 无
*/
void sv_remove_block_list(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 当前任务插入至阻塞链表
\param[in] h2task 指向链表头的指针
\return 无
*/
void sv_insert_block_list(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 删除阻塞链表
\param[in] h2task 指向链表头的指针
\return 无
\note 阻塞链表中的任务状态:就绪、阻塞、超时、挂起、停止、删除。
*/
void sv_delete_block_list(s_tasknode_tsp *h2task)
{
s_tasknode_tsp htask = *h2task;
s_tasknode_tsp htemp;
while(true){
if(htask->status == OS_STATUS_BLOCKED){
htask->status = OS_STATUS_READY;
////htask->timer = 0;
sv_task_add_ready(htask);
}
else if(htask->status & OS_STATUS_SUSPENDED){
if((htask->status & (~OS_STATUS_SUSPENDED & 0xFF)) == OS_STATUS_BLOCKED){
htask->status = OS_STATUS_SUSPENDED;
}
}
else if(htask->status == OS_STATUS_DELETED){
if(htask->create && htask->next_t == OS_NULL){
sv_free_task(htask);
}
}
htemp = htask->next_b;
////htask->last_b =
htask->next_b = OS_NULL;
if(*h2task == htemp){
*h2task = OS_NULL;
return;
}
htask = htemp;
}
}
/**
\brief 当前任务插入至定时器链表
\param 无
\return 无
*/
void sv_insert_timer_list(void)
{
if(s_task_current->next_t == OS_NULL){
s_task_current->next_t = s_list_timer;
s_list_timer = s_task_current;
}
}
#if SYSCFG_BINARY == __ENABLED__
/**
\brief 给予二值信号量
\param[in] hbin 二值信号量句柄
\return 无
*/
void sv_give_binary(s_binary_tsp hbin)
{
hbin->binary = true;
if(hbin->htask != OS_NULL){
sv_delete_block_list(&hbin->htask);
}
}
#endif
#if SYSCFG_SEMAPHORE == __ENABLED__
/**
\brief 给予计数信号量
\param[in] hsem 计数信号量句柄
\return 无
*/
void sv_give_semaphore(s_semaph_tsp hsem)
{
if(hsem->counter < hsem->maximum){
hsem->counter++;
}
if(hsem->htask != OS_NULL){
sv_delete_block_list(&hsem->htask);
}
}
#endif
#if SYSCFG_FETION == __ENABLED__
/**
\brief 发送飞信
\param[in] htbox 信箱句柄
\param[in] tion 飞信
\return 无
*/
void sv_send_fetion(s_tionbox_tsp htbox, m_fetion_t tion)
{
htbox->tion = tion;
if(htbox->htask != OS_NULL){
sv_delete_block_list(&htbox->htask);
}
}
#endif
#if SYSCFG_MAILBOX == __ENABLED__
/**
\brief 发送邮件
\param[in] hmbox 邮箱句柄
\param[in] mail 邮件指针
\return 无
*/
void sv_send_mail(s_mailbox_tsp hmbox, void *mail)
{
hmbox->flag = false;
hmbox->mail = mail;
hmbox->flag = true;
if(hmbox->htask != OS_NULL){
sv_delete_block_list(&hmbox->htask);
}
}
#endif
#if SYSCFG_MSGQUEUE == __ENABLED__
/**
\brief 发送消息
\param[in] hque 队列句柄
\param[in] msg 消息指针
\return 错误码
*/
s_ecode_t sv_send_msg(s_queue_tsp hque, void *msg)
{
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 = ((sd_queue_tsp)hque)->tail;
if(((sd_queue_tsp)hque)->tail != OS_NULL){
((sd_queue_tsp)hque)->tail->next = hmsg;
}
((sd_queue_tsp)hque)->tail = hmsg;
if(((sd_queue_tsp)hque)->head == OS_NULL){
((sd_queue_tsp)hque)->head = hmsg;
}
}
else{
if(((ss_queue_tsp)hque)->tail < ((ss_queue_tsp)hque)->base + hque->len - 1){
((ss_queue_tsp)hque)->tail++;
}
else{
((ss_queue_tsp)hque)->tail = ((ss_queue_tsp)hque)->base;
}
*((ss_queue_tsp)hque)->tail = msg;
}
hque->counter++;
if(hque->htask != OS_NULL){
sv_delete_block_list(&hque->htask);
}
hque->mutex = true;
return OS_ECODE_NOERROR;
}
/**
\brief 接收消息(静态队列)
\param[in] hque 队列句柄
\return 消息指针
*/
void *sv_recv_msg_static(ss_queue_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 *sv_recv_msg_dynamic(sd_queue_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
/**
\brief 定时中断
\param[in] tmid 定时中断定时器ID
\param[in] tick 滴答周期(定时时间)
\return 无
*/
void sv_timint(s_u8_t tmid, s_timint_t tick)
{
s_timint_handle[tmid]->timer
= s_timint_handle[tmid]->reload
= tick;
}
#endif
#if OS_TIMQRYTOTAL
/**
\brief 定时查询
\param[in] tmid 定时查询定时器ID
\param[in] tick 滴答周期(定时时间)
\return 无
*/
void sv_timqry(s_u8_t tmid, s_timqry_t tick)
{
s_timqry_handle[tmid]->timer
= s_timqry_handle[tmid]->reload
= tick;
}
#endif
/**
\brief 清除就绪延时
\param 无
\return 无
*/
void sv_clear_delay(void)
{
if(s_sign_ready_delay){
s_sign_ready_delay = false;
s_task_current->timer = 0;
}
}
#if SYSCFG_GETRTC_INT == __ENABLED__
/**
\brief 更新RTC副本
\param 无
\return 无
*/
void sv_update_rtccopy(void)
{
s_sign_updatecopy = true;
#if SYSCFG_MCUCORE == 8051
s_rtc_copy.yeah = s_rtc.yeah;
s_rtc_copy.year = s_rtc.year;
s_rtc_copy.month = s_rtc.month;
s_rtc_copy.date = s_rtc.date;
s_rtc_copy.hour = s_rtc.hour;
s_rtc_copy.minute = s_rtc.minute;
s_rtc_copy.second = s_rtc.second;
s_rtc_copy.day = s_rtc.day;
#else
s_rtc_copy = s_rtc;
#endif
s_sign_updatecopy = false;
}
#endif