μC/OS-II---Task管理2(os_task.c)

目录

改变Task优先级

cpp 复制代码
#if OS_TASK_CHANGE_PRIO_EN > 0u
INT8U  OSTaskChangePrio (INT8U  oldprio,
												 INT8U  newprio)
{
#if (OS_EVENT_EN)
	OS_EVENT  *pevent;
#if (OS_EVENT_MULTI_EN > 0u)
	OS_EVENT **pevents;
#endif
#endif
	OS_TCB    *ptcb;
	INT8U      y_new;
	INT8U      x_new;
	INT8U      y_old;
	OS_PRIO    bity_new;
	OS_PRIO    bitx_new;
	OS_PRIO    bity_old;
	OS_PRIO    bitx_old;
#if OS_CRITICAL_METHOD == 3u
	OS_CPU_SR  cpu_sr = 0u;                                 /* Storage for CPU status register         */
#endif
	/*$PAGE*/
#if OS_ARG_CHK_EN > 0u
	
	if (oldprio >= OS_LOWEST_PRIO)
	{
		if (oldprio != OS_PRIO_SELF)
		{
			return (OS_ERR_PRIO_INVALID);
		}
	}
	
	if (newprio >= OS_LOWEST_PRIO)
	{
		return (OS_ERR_PRIO_INVALID);
	}
	
#endif
	OS_ENTER_CRITICAL();
	
	if (OSTCBPrioTbl[newprio] != (OS_TCB *)0)               /* New priority must not already exist     */
	{
		OS_EXIT_CRITICAL();
		return (OS_ERR_PRIO_EXIST);
	}
	
	if (oldprio == OS_PRIO_SELF)                            /* See if changing self                    */
	{
		oldprio = OSTCBCur->OSTCBPrio;                      /* Yes, get priority                       */
	}
	
	ptcb = OSTCBPrioTbl[oldprio];
	
	if (ptcb == (OS_TCB *)0)                                /* Does task to change exist?              */
	{
		OS_EXIT_CRITICAL();                                 /* No, can't change its priority!          */
		return (OS_ERR_PRIO);
	}
	
	if (ptcb == OS_TCB_RESERVED)                            /* Is task assigned to Mutex               */
	{
		OS_EXIT_CRITICAL();                                 /* No, can't change its priority!          */
		return (OS_ERR_TASK_NOT_EXIST);
	}
	
#if OS_LOWEST_PRIO <= 63u
	y_new                 = (INT8U) (newprio >> 3u);        /* Yes, compute new TCB fields             */
	x_new                 = (INT8U) (newprio & 0x07u);
#else
	y_new                 = (INT8U) ((INT8U) (newprio >> 4u) & 0x0Fu);
	x_new                 = (INT8U) (newprio & 0x0Fu);
#endif
	bity_new              = (OS_PRIO) (1uL << y_new);
	bitx_new              = (OS_PRIO) (1uL << x_new);
	OSTCBPrioTbl[oldprio] = (OS_TCB *)0;                    /* Remove TCB from old priority            */
	OSTCBPrioTbl[newprio] =  ptcb;                          /* Place pointer to TCB @ new priority     */
	y_old                 =  ptcb->OSTCBY;
	bity_old              =  ptcb->OSTCBBitY;
	bitx_old              =  ptcb->OSTCBBitX;
	
	if ((OSRdyTbl[y_old] &   bitx_old) != 0u)               /* If task is ready make it not            */
	{
		OSRdyTbl[y_old] &= (OS_PRIO)~bitx_old;
		
		if (OSRdyTbl[y_old] == 0u)
		{
			OSRdyGrp &= (OS_PRIO)~bity_old;
		}
		
		OSRdyGrp        |= bity_new;                       /* Make new priority ready to run          */
		OSRdyTbl[y_new] |= bitx_new;
	}
	
#if (OS_EVENT_EN)
	pevent = ptcb->OSTCBEventPtr;
	
	if (pevent != (OS_EVENT *)0)
	{
		pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old;    /* Remove old task prio from wait list     */
		
		if (pevent->OSEventTbl[y_old] == 0u)
		{
			pevent->OSEventGrp    &= (OS_PRIO)~bity_old;
		}
		
		pevent->OSEventGrp        |= bity_new;              /* Add    new task prio to   wait list     */
		pevent->OSEventTbl[y_new] |= bitx_new;
	}
	
#if (OS_EVENT_MULTI_EN > 0u)
	
	if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0)
	{
		pevents =  ptcb->OSTCBEventMultiPtr;
		pevent  = *pevents;
		
		while (pevent != (OS_EVENT *)0)
		{
			pevent->OSEventTbl[y_old] &= (OS_PRIO)~bitx_old;   /* Remove old task prio from wait lists */
			
			if (pevent->OSEventTbl[y_old] == 0u)
			{
				pevent->OSEventGrp    &= (OS_PRIO)~bity_old;
			}
			
			pevent->OSEventGrp        |= bity_new;          /* Add    new task prio to   wait lists    */
			pevent->OSEventTbl[y_new] |= bitx_new;
			pevents++;
			pevent                     = *pevents;
		}
	}
	
#endif
#endif
	ptcb->OSTCBPrio = newprio;                              /* Set new task priority                   */
	ptcb->OSTCBY    = y_new;
	ptcb->OSTCBX    = x_new;
	ptcb->OSTCBBitY = bity_new;
	ptcb->OSTCBBitX = bitx_new;
	OS_EXIT_CRITICAL();
	
	if (OSRunning == OS_TRUE)
	{
		OS_Sched();                                         /* Find new highest priority task          */
	}
	
	return (OS_ERR_NONE);
}
#endif

Task挂起

cpp 复制代码
#if OS_TASK_SUSPEND_EN > 0u
INT8U  OSTaskSuspend (INT8U prio)
{
	BOOLEAN    self;
	OS_TCB    *ptcb;
	INT8U      y;
	#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
		OS_CPU_SR  cpu_sr = 0u;
	#endif
	#if OS_ARG_CHK_EN > 0u
		
		if (prio == OS_TASK_IDLE_PRIO)                              /* Not allowed to suspend idle task    */
		{
			return (OS_ERR_TASK_SUSPEND_IDLE);
		}
		
		if (prio >= OS_LOWEST_PRIO)                                 /* Task priority valid ?               */
		{
			if (prio != OS_PRIO_SELF)
			{
				return (OS_ERR_PRIO_INVALID);
			}
		}
		
	#endif
		OS_ENTER_CRITICAL();
		
		if (prio == OS_PRIO_SELF)                                   /* See if suspend SELF                 */
		{
			prio = OSTCBCur->OSTCBPrio;
			self = OS_TRUE;
		}
		
		else if (prio == OSTCBCur->OSTCBPrio)                       /* See if suspending self              */
		{
			self = OS_TRUE;
		}
		
		else
		{
			self = OS_FALSE;                                        /* No suspending another task          */
		}
		
		ptcb = OSTCBPrioTbl[prio];
		
		if (ptcb == (OS_TCB *)0)                                    /* Task to suspend must exist          */
		{
			OS_EXIT_CRITICAL();
			return (OS_ERR_TASK_SUSPEND_PRIO);
		}
		
		if (ptcb == OS_TCB_RESERVED)                                /* See if assigned to Mutex            */
		{
			OS_EXIT_CRITICAL();
			return (OS_ERR_TASK_NOT_EXIST);
		}
		
		y            = ptcb->OSTCBY;
		OSRdyTbl[y] &= (OS_PRIO)~ptcb->OSTCBBitX;                   /* Make task not ready                 */
		
		if (OSRdyTbl[y] == 0u)
		{
			OSRdyGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
		}
		
		ptcb->OSTCBStat |= OS_STAT_SUSPEND;                         /* Status of task is 'SUSPENDED'       */
		OS_EXIT_CRITICAL();
		
		if (self == OS_TRUE)                                        /* Context switch only if SELF         */
		{
			OS_Sched();                                             /* Find new highest priority task      */
		}
		
		return (OS_ERR_NONE);
}
#endif

Task恢复

cpp 复制代码
#if OS_TASK_SUSPEND_EN > 0u
INT8U  OSTaskResume (INT8U prio)
{
	OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3u                                  /* Storage for CPU status register       */
	OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (prio >= OS_LOWEST_PRIO)                               /* Make sure task priority is valid      */
	{
		return (OS_ERR_PRIO_INVALID);
	}
	
#endif
	OS_ENTER_CRITICAL();
	ptcb = OSTCBPrioTbl[prio];
	
	if (ptcb == (OS_TCB *)0)                                  /* Task to suspend must exist            */
	{
		OS_EXIT_CRITICAL();
		return (OS_ERR_TASK_RESUME_PRIO);
	}
	
	if (ptcb == OS_TCB_RESERVED)                              /* See if assigned to Mutex              */
	{
		OS_EXIT_CRITICAL();
		return (OS_ERR_TASK_NOT_EXIST);
	}
	
	if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) != OS_STAT_RDY)   /* Task must be suspended                */
	{
		ptcb->OSTCBStat &= (INT8U)~ (INT8U)OS_STAT_SUSPEND;   /* Remove suspension                     */
		
		if (ptcb->OSTCBStat == OS_STAT_RDY)                   /* See if task is now ready              */
		{
			if (ptcb->OSTCBDly == 0u)
			{
				OSRdyGrp               |= ptcb->OSTCBBitY;    /* Yes, Make task ready to run           */
				OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
				OS_EXIT_CRITICAL();
				
				if (OSRunning == OS_TRUE)
				{
					OS_Sched();                               /* Find new highest priority task        */
				}
			}
			
			else
			{
				OS_EXIT_CRITICAL();
			}
		}
		
		else                                                  /* Must be pending on event              */
		{
			OS_EXIT_CRITICAL();
		}
		
		return (OS_ERR_NONE);
	}
	
	OS_EXIT_CRITICAL();
	return (OS_ERR_TASK_NOT_SUSPENDED);
}
#endif

Task信息获取

cpp 复制代码
#if OS_TASK_QUERY_EN > 0u
INT8U  OSTaskQuery (INT8U    prio,
										OS_TCB  *p_task_data)
{
	OS_TCB    *ptcb;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
	OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0u
	
	if (prio > OS_LOWEST_PRIO)                   /* Task priority valid ?                              */
	{
		if (prio != OS_PRIO_SELF)
		{
			return (OS_ERR_PRIO_INVALID);
		}
	}
	
	if (p_task_data == (OS_TCB *)0)              /* Validate 'p_task_data'                             */
	{
		return (OS_ERR_PDATA_NULL);
	}
	
#endif
	OS_ENTER_CRITICAL();
	
	if (prio == OS_PRIO_SELF)                    /* See if suspend SELF                                */
	{
		prio = OSTCBCur->OSTCBPrio;
	}
	
	ptcb = OSTCBPrioTbl[prio];
	
	if (ptcb == (OS_TCB *)0)                     /* Task to query must exist                           */
	{
		OS_EXIT_CRITICAL();
		return (OS_ERR_PRIO);
	}
	
	if (ptcb == OS_TCB_RESERVED)                 /* Task to query must not be assigned to a Mutex      */
	{
		OS_EXIT_CRITICAL();
		return (OS_ERR_TASK_NOT_EXIST);
	}
	
	/* Copy TCB into user storage area                    */
	OS_MemCopy ((INT8U *)p_task_data, (INT8U *)ptcb, sizeof (OS_TCB));
	OS_EXIT_CRITICAL();
	return (OS_ERR_NONE);
}
#endif

Task调度器上锁(os_core.c)

cpp 复制代码
#if OS_SCHED_LOCK_EN > 0u
void  OSSchedLock (void)
{
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */
	OS_CPU_SR  cpu_sr = 0u;
#endif
	
	if (OSRunning == OS_TRUE)                    /* Make sure multitasking is running                  */
	{
		OS_ENTER_CRITICAL();
		
		if (OSIntNesting == 0u)                  /* Can't call from an ISR                             */
		{
			if (OSLockNesting < 255u)            /* Prevent OSLockNesting from wrapping back to 0      */
			{
				OSLockNesting++;                 /* Increment lock nesting level                       */
			}
		}
		
		OS_EXIT_CRITICAL();
	}
}
#endif

Task调度器开锁(os_core.c)

cpp 复制代码
#if OS_SCHED_LOCK_EN > 0u
void  OSSchedUnlock (void)
{
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */
	OS_CPU_SR  cpu_sr = 0u;
#endif
	
	if (OSRunning == OS_TRUE)                              /* Make sure multitasking is running        */
	{
		OS_ENTER_CRITICAL();
		
		if (OSIntNesting == 0u)                            /* Can't call from an ISR                   */
		{
			if (OSLockNesting > 0u)                        /* Do not decrement if already 0            */
			{
				OSLockNesting--;                           /* Decrement lock nesting level             */
				
				if (OSLockNesting == 0u)                   /* See if scheduler is enabled              */
				{
					OS_EXIT_CRITICAL();
					OS_Sched();                            /* See if a HPT is ready                    */
				}
				
				else
				{
					OS_EXIT_CRITICAL();
				}
			}
			
			else
			{
				OS_EXIT_CRITICAL();
			}
		}
		
		else
		{
			OS_EXIT_CRITICAL();
		}
	}
}
#endif
相关推荐
第七序章3 小时前
【C++STL】list的详细用法和底层实现
c语言·c++·自然语言处理·list
l1t5 小时前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
l1t6 小时前
利用美团龙猫用libxml2编写XML转CSV文件C程序
xml·c语言·libxml2·解析器
Gu_shiwww12 小时前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
你怎么知道我是队长13 小时前
C语言---循环结构
c语言·开发语言·算法
程序猿编码14 小时前
基于 Linux 内核模块的字符设备 FIFO 驱动设计与实现解析(C/C++代码实现)
linux·c语言·c++·内核模块·fifo·字符设备
mark-puls16 小时前
C语言打印爱心
c语言·开发语言·算法
西阳未落16 小时前
C语言柔性数组详解与应用
c语言·开发语言·柔性数组
小莞尔18 小时前
【51单片机】【protues仿真】基于51单片机数控直流稳压电源系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔18 小时前
【51单片机】【protues仿真】基于51单片机密码锁系统
c语言·stm32·单片机·嵌入式硬件·51单片机