⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtos.c

📁 嵌入式教程嵌入式教程嵌入式教程嵌入式教程嵌入式教程嵌入式教程嵌入式教程
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	Sem[Index].OSEventType=Type;
	Sem[Index].OSTaskPendTbl=0;				/*初始化时任务等待列表为空*/
	Sem[Index].OSEventState=0;				/*信号量无效*/
}

/************************************************************************************************************************
函数名称:	OSTaskSemPend
函数原型:	Uint_8bit OSTaskSemPend(Uint_8bit Index,Uint_16bit Timeout) 
函数功能:	任务等待信号量,挂起 
入口参数:	Index:信号量序号;Timeout:等待时间
出口参数:	无
有关说明:	当Timeout==0xffff时,为无限等待
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
Uint_8bit OSTaskSemPend(Uint_8bit Index,Uint_16bit Timeout)
{
	if(Sem[Index].OSEventState)							/*信号量有效	*/
	{
		if(Sem[Index].OSEventType == 0)				/*如果为独占型	*/
		{
			Sem[Index].OSEventState = 0x00;				/*信号量被独占,不可用*/
		}
	}
	else
	{                              						/*加入信号的任务等待表*/
		OS_ENTER_CRITICAL();
		Sem[Index].OSTaskPendTbl |= 0x01<<OSPrioCur;
		TCB[OSPrioCur].OSWaitTick = Timeout;			/*定义等待超时			*/
		OSRdyTbl &= ~(0x01<<OSPrioCur);				/*从任务就绪表中去除	*/
		OS_EXIT_CRITICAL();
		OSSched();   									/*重新调度				*/
		if(TCB[OSPrioCur].OSWaitTick==0 )				/*超时,未能拿到资源	*/
		{
			return 0;
		}
	}
	return 1;
}

/************************************************************************************************************************
函数名称:	OSSemPost
函数原型:	void OSSemPost(Uint_8bit Index) 
函数功能:	发送一个信号量,可以从任务或中断发送,
*			发送完了信号量之后不进行任务调度,推荐在中断中调用
入口参数:	Index:信号量的序号
出口参数:	无
有关说明:	如果有任务在等待该信号量则将该任务就绪,没有任务等待则仅仅是把信号量置为有效
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
void OSSemPost(Uint_8bit Index)
{
	if(Sem[Index].OSEventType)							/*当要求的信号量是共享型	*/
	{
		OS_ENTER_CRITICAL();
		Sem[Index].OSEventState=0x01;					/*使信号量有效				*/
		OSRdyTbl |=Sem [Index].OSTaskPendTbl;			/*使在等待该信号的所有任务就绪*/
		Sem[Index].OSTaskPendTbl=0;						/*清空所有等待该信号的等待任务*/
		OS_EXIT_CRITICAL();
	}
	else 												/*当要求的信号量为独占型	*/
	{
		Uint_8bit i;
		i=0;
		while ((i < OS_TASKS) && (!(Sem[Index].OSTaskPendTbl & (0x01<<i))))
		{
			i++;
			/*
				找出信号量等待列表中任务优先级最高的任务
			*/
		}
		if(i < OS_TASKS)								/*如果有任务需要			*/
		{
			OS_ENTER_CRITICAL();
			Sem[Index].OSTaskPendTbl &= ~(0x01<<i);	/*从等待表中去除			*/
			OSRdyTbl |= 0x01<<i;						/*任务就绪					*/
			OS_EXIT_CRITICAL();
		}
		else											/*没有任务等待该信号量		*/
		{
			Sem[Index].OSEventState = 1;				/*使信号量有效				*/
		}
	}
}

/************************************************************************************************************************
函数名称:	OSTaskSemPost
函数原型:	void OSTaskSemPost(Uint_8bit Index)
函数功能:	从任务发送一个信号量,并进行调度 
入口参数:	Index:信号量的序号
出口参数:	无
有关说明:	在任务中调用
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
void OSTaskSemPost(Uint_8bit Index)
{
	OSSemPost(Index);
	OSSched();
}

/************************************************************************************************************************
函数名称:	OSSemClean
函数原型:	void OSSemClean(Uint_8bit Index)
函数功能:	清除一个信号量,只对共享型的有用。 对于独占型的信号量,在任务占用后,就变得不可以用了
入口参数:	Index:信号量的序号
出口参数:	无
有关说明:	
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
void OSSemClean(Uint_8bit Index)
{
	Sem[Index].OSEventState = 0;				/*要求的信号量无效*/
}

/************************************************************************************************************************
函数名称:	TCN0Init
函数原型:	void TCN0Init(void)
函数功能:	初始化定时器0
入口参数:	无
出口参数:	无
有关说明:	定时器T0是任务时钟
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
void TCN0Init(void)
{
	TCCR0 = 0;
	TCCR0 |= (1<<CS02);			/* 256预分频		*/
	TIMSK |= (1<<TOIE0);		/* T0溢出中断允许	*/
	TCNT0 = 100;				/* 置计数起始值		*/
}

/************************************************************************************************************************
函数名称:	OSFindPrioHighRdy
函数原型:	void OSFindPrioHighRdy (void)
函数功能:	找出任务就绪表中的最高优先级的任务
入口参数:	无
出口参数:	无
有关说明:	
创建时间:	2007年3月7日
修改时间:	
************************************************************************************************************************/
void OSFindPrioHighRdy (void)
{
	Uint_8bit OSNextTaskPrio;
	OSNextTaskPrio = 0;
	while ((OSNextTaskPrio < OS_TASKS) && (!(OSRdyTbl & (0x01<<OSNextTaskPrio))))
	{
		OSNextTaskPrio++;
		/*
			找出信号量等待列表中任务优先级最高的任务
		*/
	}
	
	OSPrioHighRdy = OSNextTaskPrio;
}
/************************************************************************************************************************
函数名称:	OSIntEnter
函数原型:	void OSIntEnter(void)
函数功能:	进入中断时调用此函数
入口参数:	无
出口参数:	无
有关说明:	
创建时间:	2007年3月7日
修改时间:	
************************************************************************************************************************/
void OSIntEnter(void)
{
	OS_ENTER_CRITICAL();
	if(OSIntNesting<255)
	{
		OSIntNesting++;     				/*中断嵌套加1			*/
	}
	OS_EXIT_CRITICAL();
}
/************************************************************************************************************************
函数名称:	OSIntExit
函数原型:	void OSIntExit(void)
函数功能:	从中断中退出时调用此函数,如果中断让更高优先级的任务就绪就进行任务调度
入口参数:	无
出口参数:	无
有关说明:	OSIntEnter()和OSIntExit()要成对出现使用
创建时间:	2007年3月7日
修改时间:	
************************************************************************************************************************/
void OSIntExit(void)
{
	OS_ENTER_CRITICAL();
	if(OSIntNesting>0)
	{
		OSIntNesting--;     				/*中断嵌套减1			*/
	}
	if(OSIntNesting == 0)
	{
		OSFindPrioHighRdy();				/*找出就绪表中优先级最高的任务*/
		if(OSPrioHighRdy != OSPrioCur)
		{
			OS_EXIT_CRITICAL();
			IntSwitch();					/*进行任务调度	*/
			return;
		}
	}
	OS_EXIT_CRITICAL();
}

/************************************************************************************************************************
函数名称:	SIGNAL(SIG_OVERFLOW0)
函数原型:	SIGNAL(SIG_OVERFLOW0)
函数功能:	定时器0溢出中断处理
入口参数:	无
出口参数:	无
有关说明:	用来为需要延时的任务进行任务延时
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
SIGNAL(SIG_OVERFLOW0)
{
	OSIntEnter();
	
	Uint_8bit i;
	for(i=0;i < OS_TASKS;i++)				/*刷新各任务时钟		*/
	{
		if(TCB[i].OSWaitTick && (TCB[i].OSWaitTick != 0xffff))
		{
			TCB[i].OSWaitTick--;
			if(TCB[i].OSWaitTick == 0)		/*当任务时钟到时,必须是由定时器减时的才行*/
			{
				OSRdyTbl |= (0x01<<i);		/*使任务可以重新运行	*/
				OSIntSchedReq();			/*中断中要求切换任务	*/
			}
		}
	}
	TCNT0=100;
	OSIntExit();
}

/************************************************************************************************************************
函数名称:	void IdleTask(void)
函数原型:	void IdleTask(void)
函数功能:	空闲任务,当其他任务没有就绪的时候运行
入口参数:	无
出口参数:	无
有关说明:	系统开始运行的时候是从运行空闲任务开始的。该任务不能删除
创建时间:	2007年3月3日
修改时间:	
************************************************************************************************************************/
void IdleTask(void)
{
	OSSched();
	while(1)
	{
		
	}
}

/************************************************************************************************************************
函数名称:	OInit
函数原型:	void OInit (void)
函数功能:	初始化任务时钟和一些系统全局变量,建立空闲任务
入口参数:	无
出口参数:	无
有关说明:	
创建时间:	2007年3月5日
修改时间:	
************************************************************************************************************************/
void OSInit (void)
{
	OSRdyTbl=0;
	OSIntNesting=0;
	
	TCN0Init();
	OSTaskCreate(IdleTask,&Stack[Total_Stack_Size-1],OS_TASKS);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -