?? arm_00_os_core.c
字號:
return CAN_NOT_BE_SUSPENDED; //則返回 該任務不能被掛起
}
OSEnterCritical(); //進入臨界段
TempPcb=OSReadyList; //從就緒表表頭開始查找
while(TempPcb->Next) //直到結束
{
if(TempPcb==pcb) //如果找到,
{
DeleteFromReadyList(pcb); //將其從就緒表中刪除
InsertToSuspendList(pcb); //插入掛起列表
OSExitCritical(); //退出臨界段
if(pcb==OSCurrentPcb) //如果要掛起的是自己
{
OSTaskSwitch(); //則需要運行任務切換
}
return 0; //返回0,表示成功
}
TempPcb=TempPcb->Next;
}
return NO_SUCH_A_TASK; //如果沒找到,則返回錯誤
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:發送一則消息
入口參數1:pcb。消息的接收者。指向任務的pcb的指針。
入口參數2:pMsg。消息指針。指向消息結構體的指針。
返回:消息是否發送成功。0:發送成功;錯誤代碼 NO_SUCH_A_TASK:沒有這個任務;
**********************************************************************************************/
uint32 OSSendMsg(OSpcb * pcb,OSMsg * pMsg)
{
OSpcb * TempPcb;
OSEnterCritical(); //進入臨界段
pMsg->Sender=OSCurrentPcb; //消息的發送者
switch(pcb->Status) //判斷任務所處的狀態
{
case OSInReadyStatus: //如果任務處于就緒態
{
TempPcb=OSReadyList; //在就緒表中查找
while(TempPcb->Next) //搜索整個就緒表
{
if(pcb==TempPcb) //如果找到
{
pcb->Msg=pMsg; //將消息放入任務的消息指針中
OSExitCritical(); //退出臨界段
return 0; //返回0,發送消息成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在就緒表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回錯誤代號:沒有這樣的任務。
}
case OSInDelayStatus: //如果任務處于延時態
{
TempPcb=OSDelayList; //在延時態表中查找
while(TempPcb->Next) //搜索整個延時表
{
if(pcb==TempPcb) //如果找到
{
pcb->Msg=pMsg; //將消息放入任務的消息指針中
pcb->Delay=0; //取消任務的延時
DeleteFromDelayList(pcb); //將任務從延時列表中刪除
InsertToReadyList(pcb); //將任務插入到就緒表中
OSExitCritical(); //退出臨界段
OSTaskSwitch(); //有任務被喚醒,需要任務切換
return 0; //返回0,表示發送消息成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在延時表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回錯誤代號:沒有這樣的任務。
}
case OSInSuspendStatus: //如果任務處于掛起態
{
TempPcb=OSSuspendList; //在掛起態表中查找
while(TempPcb->Next) //搜索整個掛起態表
{
if(pcb==TempPcb) //如果找到
{
pcb->Msg=pMsg; //將消息放入任務的消息指針中
DeleteFromSuspendList(pcb); //將任務從掛起態列表中刪除
InsertToReadyList(pcb); //將任務插入到就緒表中
OSExitCritical(); //退出臨界段
OSTaskSwitch(); //有任務被喚醒,需要任務切換
return 0; //返回0,表示消息發送成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在掛起態表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回錯誤代號:沒有這樣的任務。
}
default: //如果任務處于其它狀態
{
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回錯誤代號:沒有這樣的任務。
}
}
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:定時器0初始化。用來產生10mS的時鐘節拍。并將其分配為FIQ中斷
入口參數:無。
返回:無。
備注:無。
**********************************************************************************************/
void Timer0Init(void)
{
T0LD=MaxOfTimer0; // 1/100秒中斷一次
T0CON=0xC8; // Enable Timer0; Periodic mode; FCoreClock/256=163200Hz
CopyOfFIQEN |=TIMER0; //TIMER0中斷分配為FIQ
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:系統時鐘節拍初始化。用來產生10mS的時鐘節拍。
入口參數:無。
返回:無。
備注:無。
**********************************************************************************************/
void OSTickInit(void)
{
Timer0Init(); //調用函數Timer0Init()設置時鐘節拍
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
顯示ARM_00_OS的數組
**********************************************************************************************/
const uint8 ARM_00_OS_LOGO[7][78]={
" __ _____ __ __ _____ _____ ____ __ ",
" //\\\\ ||~~~\\\\ ||\\\\ //|| //~~~\\\\ //~~~\\\\ //~~~~\\\\ //~~\\\\ ",
" // \\\\ || || || \\\\ // || || /|| || /|| || || || ",
"||____|| ||===// || \\\\// || || / || || / || || || \\\\___ ",
"||====|| || \\\\ || ~~ || || / || || / || || || ~~~\\\\",
"|| || || \\\\ || || ___ \\\\/__// \\\\/__// ___ \\\\____// \\\\___//",
"~~ ~~ ~~ ~~ ~~ ~~ ~~~ ~~~ ~~~ ~~~ ~~~~ ~~~ "
};
///////////////////////////////////////////////////////////////////////////////////////////////
/**********************************************************************************************
功能:操作系統初始化。
入口參數:無。
返回:無。
備注:任務調度前,必須調用該函數初始化好一些參數
**********************************************************************************************/
void OSInit(void)
{
uint32 i;
const uint8 Title1[]={"SystemIdle"}; //系統空閑任務的標題
CopyOfFIQEN=0; //FIQEN備份被設置為0
CopyOfIRQEN=0; //IRQEN備份被設置為0
OSEnCrCount=0; //進入臨界段次數為0
OSMemoryInit(); //內存初始化
OSMemoryTest(); //內存測試
OSDeviceBottom.Next=0; //設備列表表底初始化
OSDeviceBottom.User=0;
OSDeviceBottom.RequestCount=0;
OSDeviceBottom.DeviceID=0;
OSDeviceList=&OSDeviceBottom; //設備列表初始化指向低部
//系統空閑任務(即就緒列表底部)初始化
//系統空閑任務的優先級最低,無其它任務運行時,就運行系統空閑任務
//注意,永遠不要掛起系統空閑任務,否則會出錯
OSSystemIdlePcb.Prior=&OSSystemIdlePcb; //系統初始化,現在只有系統空閑任務
OSSystemIdlePcb.Next=0; //系統空閑任務沒有后一個任務
OSSystemIdlePcb.Priority=~0; //系統空閑任務的優先級最低(即0xFFFFFFFF)
OSSystemIdlePcb.Status=OSInReadyStatus; //系統空閑任務永遠處于就緒態
OSSystemIdlePcb.Delay=0; //系統空閑任務永遠不得延時
OSSystemIdlePcb.PID=(uint32)&OSSystemIdlePcb; //系統空閑任務的PID
OSSystemIdlePcb.StackLength=0; //系統空閑任務的堆棧長度設置為0字節,因為空閑任務并未使用緩沖池
OSSystemIdlePcb.TotalRunTime=0; //系統空閑任務的總運行時間初始化為0
OSSystemIdlePcb.RunTimeInThisRefreshPeriod=0; //系統空閑任務的當前運行時間初始化為0
OSSystemIdlePcb.Msg=0; //初始化無接收消息
OSSystemIdlePcb.WaitFor=0; //初始化無等待資源
for(i=0;i<15;i++) //設置標題
{
OSSystemIdlePcb.Title[i]=Title1[i];
if(Title1[i]==0)break;
}
for(;i<15;i++) //不足的補空格
{
OSSystemIdlePcb.Title[i]=' ';
}
OSSystemIdlePcb.Title[15]=0;
TaskAmount=1; //任務總數為1,即只有一個系統空閑任務
OSReadyList=&OSReadyListBottom; //就緒任務表的起始設置為OSSReadyListBottom,現在只有一個任務
//掛起態任務列表底部初始化
//該底部是一個短的Pcb,即只有Prior,Next,Delay,Priority,PID這幾個參數
//該底部沒有實際的任務對應,只是一個空表,方便任務喚醒時查找任務使用
//永遠不要將掛起態列表底部投入到就緒表中,否則會出錯
OSSuspendListBottom.Prior=(OSpcb *)&OSSuspendListBottom; //現在只有一個掛起任務,所以前趨指向自己
OSSuspendListBottom.Next=(OSpcb *)0; //掛起態任務列表底部沒有下一個任務
OSSuspendListBottom.PID=0; //PID為0
OSSuspendListBottom.Priority=~0; //優先級最低
OSSuspendListBottom.Delay=0; //不得延時
OSSuspendList=(OSpcb *)&OSSuspendListBottom; //掛起列表的起始為列表低部,因為現在只有底部一個
//延時態任務列表底部初始化
//該底部是一個短的Pcb,即只有Prior,Next,Delay,Priority,PID這幾個參數
//該底部沒有實際的任務對應,只是一個空表,方便任務喚醒時查找任務使用
//永遠不要將延時態列表底部投入到就緒表中,否則會出錯
OSDelayListBottom.Prior=(OSpcb *)&OSSuspendListBottom; //現在只有一個延時態任務,所以前趨指向自己
OSDelayListBottom.Next=(OSpcb *)0; //延時態任務列表底部沒有下一個任務
OSDelayListBottom.PID=0; //PID為0
OSDelayListBottom.Priority=~0; //優先級最低
OSDelayListBottom.Delay=0; //不得延時
OSDelayList=(OSpcb *)&OSDelayListBottom; //掛起列表的起始為列表低部,因為現在只有底部一個
prints("",1);
prints("Welcome to",1);
for(i=0;i<7;i++) //顯示LOGO
{
prints(ARM_00_OS_LOGO[i],1);
}
prints("",1);
prints("Date created: ",0); //顯示創建日期
prints(__DATE__,1);
prints("Time created: ",0); //顯示創建時間
prints(__TIME__,1);
prints(" Designer: Computer00",1);
prints(" My Blog: Http://computer00.21ic.org",1);
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:釋放所占用的資源。
入口參數:pcb。任務的進程控制塊地址。
返回:無。
**********************************************************************************************/
void OSFreeResource(OSpcb * pcb)
{
OSdevice * pDevice;
pDevice=OSDeviceList; //從設備列表頭部開始
while(pDevice->Next) //直到設備列表的表尾
{
if(pDevice->User==pcb) //如果該設備被該任務使用,
{
OSFreeDevice((uint32)pDevice); //則釋放它
}
}
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:刪除一個任務。
入口參數1:pcb。要刪除的任務的pcb。
返回:32位無符號整型。0表示刪除成功。非零表示刪除失敗,返回錯誤代號。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -