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

📄 os_c.c

📁 ARM 处理器的一个小操作系统内核源码 多任务
💻 C
字号:
#include "def.h"
#include "OS.H"


//********************************************************************************
volatile PointType	CToAsmSP;	//C/ASM传SP用
volatile U8	OS_TaskRunning;   	//当前正在运行的Task
volatile U8	CallTkSwCount=0x0;	//进入任务切换令牌
volatile U32 OSTimerCount=0;	//系统时钟
volatile U32 MUX=0;				//互斥
volatile U8 TmpHpTk=OS_TaskNum-1;	//临时最高优先级任务

U32 FIQLR,SVCLR,FIQSPSR;

//任务控制块
struct{
  PointType	OSTaskStackTop;	//保存任务的堆栈顶
  PointType	OSTaskStackBottom; //堆栈空间底
  U32		OSTaskStackNum;        //堆栈占据的基本块数
  U32		OSWaitTick;             //任务延时时钟
  U32		OSTaskState;            //任务状态
  U32		OSUSRTaskID;            //用户任务ID&系统任务ID
} TCB[OS_TaskNum];

/****************************************************************************
调度
****************************************************************************/
void TkSw(void)
{
	OS_ENTER_CRITICAL();
	if(CallTkSwCount==0x0){AsmTkSw();}
}

/****************************************************************************
功能描述:时间片处理
****************************************************************************/
void OSTimer(void)
{
    U8 i;
  
	OSTimerCount++;
	CallTkSwCount++;
	for(i=0;i<OS_TaskNum;i++){
       	if(TCB[i].OSTaskState!=0 && TCB[i].OSTaskState!=3){			//判断任务是否已经结束或挂起
           	if(TCB[i].OSWaitTick>1) TCB[i].OSWaitTick--;  			//给等待的任务减去1个等待时间片
           	else TCB[i].OSTaskState=1;                    			//如果任务等时间到,设为就绪态
       	}
	}
	
	IsrHook();	//用户中断处理
}
/****************************************************************************
IO调度
****************************************************************************/

/****************************************************************************
MSG调度
****************************************************************************/

/****************************************************************************
CPU调度
功能描述:进行任务调度_C;
因为操作了SP,所以关键在禁止多次进入本函数
****************************************************************************/
void CtrTaskkSw(void)
{
    U8 i;

	CallTkSwCount++;											//任务级切换标记为禁止,本程序未执行完前不会再执行本程序
	TCB[OS_TaskRunning].OSTaskStackTop=CToAsmSP; 				//将正在运行的任务的堆栈底保存


#if OS_CORF>0													//内核形式,>0抢先式,0循环式
    for(i=0;i<OS_TaskNum;i++){if(TCB[i].OSTaskState==1) goto sc;}
#else
    for(i=OS_TaskRunning+1;i<OS_TaskNum;i++){if(TCB[i].OSTaskState==1) goto sc;} //如果新任务不是就绪态,下一任务
    for(i=0;i<OS_TaskRunning;i++){if(TCB[i].OSTaskState==1) goto sc;}
#endif

	i=OS_TaskNum-1;
sc:

	if(TmpHpTk!=OS_TaskNum-1){									//让临时最高优先级任务首先运行,实时任务
		OS_TaskRunning=TmpHpTk;									//主要用来快速响应中断下部
		TmpHpTk=OS_TaskNum-1;
	}
	else {OS_TaskRunning=i;}
	
    CToAsmSP=TCB[OS_TaskRunning].OSTaskStackTop; 				//设置将要运行的任务
	CallTkSwCount=0;
}

/*******************************************************************************
功能描述:建立一个新任务;
IN:	void (*Task)(void) 任务函数名称;USRTaskID 用户定义任务号
OUT:0成功;1 USRTaskID过大;2 任务已存在;3 堆栈溢出,任务太多
********************************************************************************/
extern void GETSP(void);
U8 OSCreateTask(void (*Task)(void),U8 USRTaskID,U32 TaskStackNum)
{
	static PointType StackPTR=0;
    if(StackPTR==0){
	    GETSP();
	    StackPTR=CToAsmSP-0x1000;
    }
    
    if(USRTaskID>=OS_TaskNum){return 1;}
    OS_ENTER_CRITICAL();
    if(TCB[USRTaskID].OSTaskState!=0) {
	    OS_EXIT_CRITICAL();
		return 2;
	}

	if(StackPTR>0){
		TCB[USRTaskID].OSTaskStackTop=StackPTR;
		TCB[USRTaskID].OSTaskStackBottom=StackPTR-TaskStackNum*OS_StackUnit*sizeof(PointType);
		StackPTR-=TaskStackNum*OS_StackUnit*sizeof(PointType);
		
	}
	else {
	    OS_EXIT_CRITICAL();
		return 3;
	}

	//栈初始化
	*(PointType *)(TCB[USRTaskID].OSTaskStackTop)=(PointType)Task;			//ARM R15 将任务的地址(PC)压入堆栈
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=(PointType)Task;       	//ARM R14 LR
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R12
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R11
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R10
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R09
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R08
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R07
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R06
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R05
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R04
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R03
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R02
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R01
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=0x0;       				//ARM R00
	*(--(PointType *)TCB[USRTaskID].OSTaskStackTop)=(SVCMODE|NOINT); //ARM SPSR

	//任务控制块初始化
	TCB[USRTaskID].OSTaskStackNum=TaskStackNum;       						//保存任务堆栈基本块数
    TCB[USRTaskID].OSUSRTaskID=USRTaskID;                     				//保存任务自身ID和用户设定ID
    TCB[USRTaskID].OSTaskState=1;                                           //任务运行=1,等待=2,挂起=3,结束=0,
    TCB[USRTaskID].OSWaitTick=0;                                            //任务等待多少个调度周期,0不等待
    OS_EXIT_CRITICAL();

    return 0;
}
/*******************************************************************************
功能描述:OS初始化;
********************************************************************************/
void OSInit(void)
{
    U8 i;

    OS_ENTER_CRITICAL();
    for(i=0;i<OS_TaskNum;i++){
        TCB[i].OSTaskState=0;
		TCB[i].OSTaskStackTop=0;
		TCB[i].OSTaskStackNum=0;
    }
	OSCreateTask(OSIdle,OS_TaskNum-1,0x2000);
}
/*******************************************************************************
功能描述:第一次开始任务;
注:从最低优先级(Task0)的任务的开始
********************************************************************************/
void OSStartTask(void)        
{
    OS_ENTER_CRITICAL();
    
	OS_TaskRunning=0;
	CToAsmSP=TCB[OS_TaskRunning].OSTaskStackTop;
	StartHT();											//开始第一个任务
 }

/*******************************************************************************
功能描述:延时关挂起任务;
IN:ticks 系统时钟片
OUT:无
********************************************************************************/
void OSDelay(U32 ticks)
{
	if(ticks>0){                           				//当延时有效
		OS_ENTER_CRITICAL();
		TCB[OS_TaskRunning].OSTaskState=2;     
		TCB[OS_TaskRunning].OSWaitTick=ticks;
		TkSw();  	                  					//从新调度
	}
}

/*******************************************************************************
功能描述:删除任务;
输入:UsrTaskID 用户定义任务ID号
输出:1设置成功;0失败
*******************************************************************************/
U8 OSDelTask(U8 UsrTaskID)
{
	OS_ENTER_CRITICAL();
	TCB[UsrTaskID].OSTaskState=0;
	if(UsrTaskID==OS_TaskRunning) {TkSw();}	//将自已Del
	else {
		OS_EXIT_CRITICAL();
		return 1;
	}

	return 0;
}
/******************************************************************************
功能描述:任务休眠
输入:UsrTaskID 用户定义任务ID号,TaskSleepTicks 休眠的时间片
输出:1 设置成功;0失败
注:如果TaskSleepTicks设为0,将唤醒Task
*******************************************************************************/
U8 OSSleepTask(U8 UsrTaskID,U32 TaskSleepTicks)
{
	OS_ENTER_CRITICAL();
	if(TaskSleepTicks>0){
		TCB[UsrTaskID].OSTaskState=2;
		TCB[UsrTaskID].OSWaitTick=TaskSleepTicks;
		OS_EXIT_CRITICAL();
		return 1;
	}

	OS_EXIT_CRITICAL();
	return 0;
}

/******************************************************************************
功能描述:挂起任务;
输入:UsrTaskID 用户定义任务ID号
输出:1 设置成功;0 失败
*******************************************************************************/
U8 OSSuspendTask(U8 UsrTaskID)
{
	OS_ENTER_CRITICAL();
	TCB[UsrTaskID].OSTaskState=3;
    if(UsrTaskID==OS_TaskRunning) {TkSw();}				//自已Suspend

	OS_EXIT_CRITICAL();
    return 0;
} 
/******************************************************************************
功能描述:恢复任务;
输入:UsrTaskID 用户定义任务ID号
输出:0 设置成功;1 失败
*******************************************************************************/
U8 OSResumTask(U8 UsrTaskID)
{
    if(TCB[UsrTaskID].OSTaskState!=0){ 					//找出符合条件且还没有删除的任务
		OS_ENTER_CRITICAL();
        TCB[UsrTaskID].OSTaskState=2;    
		OS_EXIT_CRITICAL();
        return 0;
    }

    return 1;
} 
/******************************e********************************************************
功能描述:取得互斥信号量

IN:mux互斥号
   zs:是否阻塞进程,0否, 1是

返回值:0获得资源,1:未取得资源
****************************************************************************************/
U8 GetMux(U8 mux,U8 zs)
{
P1:
	OS_ENTER_CRITICAL();
	if((MUX & (1<<mux))==0){
		MUX |=(1<<mux);					//取得互斥信号
		OS_EXIT_CRITICAL();	
		return 0x0;
	}
	OS_EXIT_CRITICAL();
	if(zs==1){
		OSDelay(1);
		goto P1;
	}

	return 0x1;
}
/******************************e********************************************************
功能描述:释放互斥信号
****************************************************************************************/
void FreeMux(U8 mux)
{
	OS_ENTER_CRITICAL();
	MUX &=~(1<<mux);						//释放互斥信号
	OS_EXIT_CRITICAL();	
}

/**************************OSIdle********************************************************
功能描述:空闲;
****************************************************************************************/
void OSIdle(void)
{
	while(1){
		wdt_reset();
	}
}


⌨️ 快捷键说明

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