?? os_core.c
字號:
#include <AT89X52.H>
#include "os_core.h"
#include "main.h"
#include "task_switch.h"
#include "sem.h"
#include "q.h"
#include "uart.h"
//程序控制塊
TCB OS_TCB[TASK_NUM];
//當前運行任務的優先級
uint8 OS_Current_ID;
//進入臨界段計數器
uint8 OS_En_Cr_Count;
//任務就緒表
uint8 OS_TaskRdy_List;
//中斷嵌套計數器
uint8 Int_count;
uint8 Task_Int_List;
//置位表
uint8 code OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
////////////////////////////系統初始化//////////////////////////////////////////////////////
void OS_Init(void)
{
uint8 i ;
EA=0; //關中斷
ET2=1; //接受定時器2中斷
T2CON=0x00;
T2MOD=0x00;
RCAP2H=0xB1;
RCAP2L=0xE0; //定時時間為10ms
Int_count=0; //中斷嵌套為0
OS_TaskRdy_List=0; //任務就緒表為0
OS_Task_Q_List=0;
OS_En_Cr_Count=0; //進入臨界段為0次
Task_Int_List=0x00;
OS_TCB[0].Task_SP=SP+2; //初始化各任務的堆棧起始地址
for(i=1;i<TASK_NUM;i++)
OS_TCB[i].Task_SP=OS_TCB[i-1].Task_SP+(255-OS_TCB[0].Task_SP)/TASK_NUM;
}
///////////////////////////創建一個任務////////////////////////////////////////////////////////
void OS_Task_Create(uint8 Task_Prio,uint8 Task_ID, uint16 Task_PC,uint8 Stack_Bottom) reentrant
{
OS_ENTER_CRITICAL();
if(OS_TCB[Task_ID].Status== No_Exist)
{
OS_TCB[Task_ID].Status=Exist; /*任務存在*/
OS_EXIT_CRITICAL();
((uint8 idata *)Stack_Bottom)[0]=Task_PC; /*將任務入口地址保存在堆棧,壓入低8位*/
((uint8 idata *)Stack_Bottom)[1]=Task_PC>>8; /*壓入高8位*/
OS_TCB[Task_ID].Task_SP=Stack_Bottom+1; /*將該任務的堆棧棧頂地址保存*/
OS_TCB[Task_ID].Prio=Task_Prio; /*任務優先級*/
OS_TCB[Task_ID].Delay=0; /*任務初始不延時*/
OS_TaskRdy_List|=OSMapTbl[Task_ID]; /*任務就緒*/
return ;
}
OS_EXIT_CRITICAL();
}
////////////////////////////系統啟動///////////////////////////////////////////////////////////
void OS_Start(void)
{
OS_Current_ID=TASK_NUM-1;
SP=OS_TCB[OS_Current_ID].Task_SP; /*修改堆棧指針;使其指向當前任務的堆棧段*/
TR2=1; /*啟動定時器2*/
EA=1; /*開中斷*/
}
////////////////////////////系統時鐘處理函數//////////////////////////////////////////////////
void OS_TimeTick(void)
{
uint8 i;
for(i=0;i<TASK_NUM;i++) /*處理所有延時*/
{
if(OS_TCB[i].Delay) /*如果任務需要延時*/
{
OS_TCB[i].Delay--; /*延時時間減1*/
if(OS_TCB[i].Delay==0) /*如果延時時間到*/
{
OSSendSignal(i); /*中斷中發信號,任務就緒*/
}
}
}
}
////////////////////////////////查找下一任務//////////////////////////////////////////////////
void OS_Find_Next_Task(void)
{
uint8 tempPrio,i;
tempPrio=OS_TCB[OS_Current_ID].Prio;
for(i=0;i<TASK_NUM-1;i++)
{
if((OS_TaskRdy_List&OSMapTbl[i])&&(OS_TCB[i].Prio<tempPrio))
{
goto bb;
}
}
for(i=OS_Current_ID;i<TASK_NUM-1;i++)
{
if((OS_TaskRdy_List&OSMapTbl[i])&&(OS_TCB[i].Prio==tempPrio)&&i!=OS_Current_ID)
{
goto bb;
}
}
if(i==TASK_NUM-1)
{
for(i=0;i<TASK_NUM-1;i++)
{
if(OS_TaskRdy_List&OSMapTbl[i])
{
break;
}
}
}
bb: OS_Current_ID=i;
}
///////////////////////////定時器2中斷服務函數/////////////////////////////////////////////////
#pragma disable /* 除非最高優先級中斷,否則,必須加上這一句 */
void Timer2ISR(void) interrupt 5
{
TF2=0; /*清中斷標志TF2*/
Enter_Int();
#if EN_TIMER_SHARING > 0
OS_TimeTick(); /* 調用系統時鐘處理函數 */
#else
OSSendSignal(TIME_ISR_TASK_ID); /* 喚醒ID為TIME_ISR_TASK_ID的任務*/
#endif
Exit_Int();
}
///////////////////////////任務中給指定任務發送信號///////////////////////////////////////////
void OSSendSignal(uint8 TaskId)
{
if (TaskId < TASK_NUM)
{
OS_ENTER_CRITICAL();
OS_TaskRdy_List|=OSMapTbl[TaskId ];/*任務就緒*/
OS_EXIT_CRITICAL();
if (Int_count==0) /*不在中斷中*/
{
OSSched(); /*開始任務切換*/
}
}
}
//////////////////////////清除指定任務信號////////////////////////////////////////////////////
void OSClearSignal(uint8 TaskId)
{
if(TaskId <TASK_NUM)
{
OS_ENTER_CRITICAL();
OS_TaskRdy_List &= ~OSMapTbl[TaskId]; /*任務不就緒*/
OS_EXIT_CRITICAL();
if(TaskId==OS_Current_ID && Int_count==0) /*掛起自身并不在中斷中*/
{
OSSched(); /*開始任務切換*/
}
}
}
//////////////////////////掛起指定任務////////////////////////////////////////////////////////
void OSTaskSuspend(uint8 TaskId)
{
if (TaskId <TASK_NUM)
{
OS_TCB[TaskId].Delay = 0; /*沒有超時處理*/
OSClearSignal(TaskId); /*清除指定任務信號*/
}
}
/////////////////////////系統等待函數//////////////////////////////////////////////////////////
uint8 OSWait(uint8 typ, uint8 ticks)
{
OS_TCB[OS_Current_ID].Delay = ticks; /*設置超時時間*/
switch(typ)
{
case K_SIG: /*等待信號,即掛起自身*/
OSTaskSuspend(OS_Current_ID);
return SIG_EVENT;
case K_TMO:
SP++;
*((uint8 data * data *)SP) = ticks;
OSClearSignal(OS_Current_ID); /*等待超時,即延時一段時間*/
SP--;
ticks = (uint8 data *)(*((uint8 data *)SP));
if(ticks&&OS_TCB[OS_Current_ID].Delay==0) /*超時*/
{
return TMO_EVENT;
}
return SIG_EVENT;
default:
OS_TCB[OS_Current_ID].Delay = 0;
return NOT_OK;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -