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

📄 rtos.c

📁 一个以ARM9为平台小型操作系统的设计源码
💻 C
字号:
//-------------------------------------------------------------------------
// 文件名:RTOS.C
// 功能:  ARM9上运行的微型操作系统
// 备注:  抢占式任务调度,运行时间可预测,提供延时,挂起,恢复任务操作
//		   未加入信号量邮箱等同步通信机制
//
//         By Lisuwei	 
//-------------------------------------------------------------------------

#define   CPP_GLOBALS
#include "Includes.h"


/************************************************************************************************************************
函数名称:	OSTaskCreate
函数原型:	void OSTaskCreate(void (*Task)(void),INT32U *Stack,INT8U TaskID)
函数功能:	建立任务 
入口参数:	*Task:任务函数地址;*Stack:任务栈顶指针;TaskID:任务优先级
出口参数:	无
有关说明:	初始化任务堆栈,任务控制块TCB和在置位表上登记就绪
************************************************************************************************************************/
void OSTaskCreate(void (*Task)(void),INT32U *p_Stack,INT8U TaskID)
{
	if(TaskID <= OS_TASKS)
	{
		*(p_Stack)   = (INT32U)Task;				/* 将任务的地址压入堆栈,满栈减,先减再赋值 !! */	
    	*(--p_Stack) = (INT32U)13;                  /* lr                                                      */
    	*(--p_Stack) = (INT32U)12;                  /* r12                                                     */
    	*(--p_Stack) = (INT32U)11;                  /* r11                                                     */
    	*(--p_Stack) = (INT32U)10;                  /* r10                                                     */
    	*(--p_Stack) = (INT32U)9;                   /* r9                                                      */
    	*(--p_Stack) = (INT32U)8;                   /* r8                                                      */
    	*(--p_Stack) = (INT32U)7;                   /* r7                                                      */
    	*(--p_Stack) = (INT32U)6;                   /* r6                                                      */
    	*(--p_Stack) = (INT32U)5;                   /* r5                                                      */
    	*(--p_Stack) = (INT32U)4;                   /* r4                                                      */
    	*(--p_Stack) = (INT32U)3;                   /* r3                                                      */
    	*(--p_Stack) = (INT32U)2;                   /* r2                                                      */
    	*(--p_Stack) = (INT32U)1;                   /* r1                                                      */
		*(--p_Stack) = (INT32U)0;					/* r0 */
	    *(--p_Stack) = (INT32U)(SVCMODE|0x0);	    /* SREG 保存在任务栈中	*/
		TCB[TaskID].OSTCBStkPtr = (INT32U)p_Stack;  /* 将人工堆栈的栈顶,保存到堆栈的数组中*/
		TCB[TaskID].OSTCBDly = 0;					/* 初始化任务延时    	*/
		OSSetPrioRdy(TaskID);      				    /* 在任务就绪表中登记	*/
	}
	else
	{
		Uart_Printf("TaskID Error\n");
		while(1);
	}
}

/************************************************************************************************************************
函数名称:	OSStart
函数原型:	void OSStart(void)
函数功能:	开始任务调度,从最高优先级任务开始运行 
入口参数:	无
出口参数:	无
有关说明:	找出优先级最高的就绪任务运行
************************************************************************************************************************/
void OSStart(void)
{
	OSGetHighRdy();
	p_OSTCBHighRdy = &TCB[OSPrioHighRdy];	/* 在汇编中需引用任务的TCB地址取得栈顶指针,所以在任务切换前,OSTCBHighRdy必须指向优先级最高的那个任务控制块TCB */
	OSPrioCur = OSPrioHighRdy;				/* 在就绪表中查找最高级的就绪任务 */
	OSStartHighRdy();						/* 系统第一个运行的任务出栈 */
	
}

/************************************************************************************************************************
函数名称:	OSSched
函数原型:	void OSSched(void)
函数功能:	任务调度器,进行任务调度
入口参数:	无
出口参数:	无
有关说明:	只有有更高优先级的任务就绪时才进行一次任务切换,否则不做切换
************************************************************************************************************************/
void OSSched (void)
{
	OS_ENTER_CRITICAL();
	OSGetHighRdy();						    /* 找出就绪表中优先级最高的任务 */	
	if(OSPrioHighRdy != OSPrioCur)			/* 如果不是当前运行的任务,进行任务调度 */
	{
		p_OSTCBCur     = &TCB[OSPrioCur];	/* 目的是在汇编中引用任务的TCB地址取得栈顶指针 */
		p_OSTCBHighRdy = &TCB[OSPrioHighRdy];
		OSPrioCur = OSPrioHighRdy;			/* 更新OSPrioCur */
		OS_TASK_SW();						/* 调度任务 */
	}
	OS_EXIT_CRITICAL();
}


/************************************************************************************************************************
函数名称:	OSTaskSuspend
函数原型:	void OSTaskSuspend(INT8U prio)
函数功能:	挂起任务 
入口参数:	prio:任务的优先级
出口参数:	无
有关说明:	一个任务可以挂起本身也可以挂起其他任务
************************************************************************************************************************/
void OSTaskSuspend(INT8U prio)
{
	OS_ENTER_CRITICAL();
	TCB[prio].OSTCBDly = 0;
	OSDelPrioRdy(prio);				/* 从任务就绪表上去除标志位	*/
	OS_EXIT_CRITICAL();
	
	if(OSPrioCur == prio)			/* 当要挂起的任务为当前任务	*/
	{
		OSSched();					/* 重新调度					*/
	}
	
}

/************************************************************************************************************************
函数名称:	OSTaskResume
函数原型:	void OSTaskResume(INT8U prio)
函数功能:	恢复任务 可以让被OSTaskSuspend 或 OSTimeDly挂起的任务恢复 
入口参数:	prio:任务的优先级
出口参数:	无
有关说明:	
************************************************************************************************************************/
void OSTaskResume(INT8U prio)
{
	OS_ENTER_CRITICAL();
	OSSetPrioRdy(prio);				/* 从任务就绪表上重置标志位	*/
    TCB[prio].OSTCBDly = 0;			/* 将时间计时设为0,延时到	*/
	OS_EXIT_CRITICAL();
	
	if(OSPrioCur > prio)			/* 当前任务的优先级低于重置位的任务的优先级	*/
	{
		OSSched();					/* 重新调度					*/
	}
	
}

/************************************************************************************************************************
函数名称:	OSTimeDly
函数原型:	void OSTimeDly(INT32U ticks)
函数功能:	挂起任务延时 
入口参数:	延时的时间,任务等待时钟节拍的个数
出口参数:	无
有关说明:	延时数不得超出INT32U的范围
************************************************************************************************************************/
void OSTimeDly(INT32U ticks)
{
	if(ticks > 0)                           /* 当延时有效           */
	{
		OS_ENTER_CRITICAL();
		OSDelPrioRdy(OSPrioCur);			/* 把任务从就绪表中删去 */
		TCB[OSPrioCur].OSTCBDly = ticks;	/* 设置任务延时节拍数   */
		OS_EXIT_CRITICAL();
		OSSched();                          /* 重新调度	            */
	}
}

/************************************************************************************************************************
函数名称:	OSIntExit
函数原型:	void OSIntExit(void)
函数功能:	从中断中退出时调用此函数,如果中断让更高优先级的任务就绪就进行任务调度
入口参数:	无
出口参数:	无
有关说明:	若中断后需要切换任务,通过置位OSIntCtxSwFlag变量来标记
************************************************************************************************************************/
void OSIntExit(void)
{
		OSGetHighRdy();							/* 找出就绪表中优先级最高的任务 */
		if(OSPrioHighRdy != OSPrioCur)
		{				
			p_OSTCBCur     = &TCB[OSPrioCur];   /* 目的是在汇编中引用任务的TCB地址取得栈顶指针 */
			p_OSTCBHighRdy = &TCB[OSPrioHighRdy];
			OSPrioCur = OSPrioHighRdy;			/* 更新OSPrioCur */
			OSIntCtxSwFlag = TRUE;  			/* 进行中断级任务调度 */
		}
}

/************************************************************************************************************************
函数名称:	TickInterrupt
函数原型:	void TickInterrupt(void)
函数功能:	T0中断服务程序(时钟节拍中断服务程序)
入口参数:	无
出口参数:	无
有关说明:	用来为需要延时的任务进行计时
************************************************************************************************************************/
 void TickInterrupt(void)
	{
		static INT8U i;
		   
		OSTime ++;
		//Uart_SendByte('I');
		for(i = 0; i < OS_TASKS; i++)			/* 刷新各任务时钟 */
		{
			if(TCB[i].OSTCBDly )
			{
				TCB[i].OSTCBDly --;
				if(TCB[i].OSTCBDly == 0)		/* 当任务时钟到时,必须是由定时器减时的才行*/
				{
					OSSetPrioRdy(i);		    /* 使任务可以重新运行	*/	
				}
			}
		}	
		rSRCPND |= BIT_TIMER0;			
		rINTPND |= BIT_TIMER0;
}

/************************************************************************************************************************
函数名称:  IdleTask
函数原型:	void IdleTask(void)
函数功能:	空闲任务,当其他任务没有就绪的时候运行
入口参数:	无
出口参数:	无
有关说明:	空闲任务必须永远处于就绪状态
************************************************************************************************************************/
void IdleTask(void)
{	
	IdleCount = 0;
	while(1)
	{
		IdleCount++;
		//Uart_Printf("IdleCount %d\n",IdleCount);
	}
}

/************************************************************************************************************************
函数名称:	OSInit
函数原型:	void OSInit (void)
函数功能:	初始化系统全局变量,建立空闲任务
入口参数:	无
出口参数:	无
有关说明:	初始化系统变量,建立空闲任务
************************************************************************************************************************/
void OSInit (void)
{
	OSTime = 0;
	OSRdyTbl = 0;
	OSIntCtxSwFlag = 0;
	OSPrioCur = OSPrioHighRdy = OS_TASKS;
	OSTaskCreate(IdleTask,&StackIdle[StackSizeIdle - 1],OS_TASKS);
}

/************************************************************************************************************************
函数名称:	C_IRQHandler
函数原型:	void C_IRQHandler(void)
函数功能:	C语言中断入口程序
入口参数:	无
出口参数:	无
有关说明:	跳转到相应的中断服务函数
************************************************************************************************************************/
void C_IRQHandler(void)
{

    (* ((void(*)()) (*((U32 *)((int)&pISR_EINT0 + (rINTOFFSET<<2)))))) ();
   
}




⌨️ 快捷键说明

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