?? arm_00_os_core.c
字號:
/**********************************************************************************************
功能:刪除一個任務。
入口參數1:pcb。要刪除的任務的pcb。
返回:32位無符號整型。0表示刪除成功。非零表示刪除失敗,返回錯誤代號。
備注:如果任務自己申請了內存,一定要任務自己先釋放內存,否則任務被刪除后,內存沒有釋放,會導致內存泄漏。
**********************************************************************************************/
uint32 OSTaskKill(OSpcb * pcb)
{
OSpcb * TempPcb;
OSEnterCritical(); //進入臨界段
switch(pcb->Status) //根據狀態不同,做不同的處理
{
case OSInReadyStatus: //如果任務處于就緒態
{
TempPcb=OSReadyList; //從就緒表中查找
while(TempPcb->Next) //搜索整個就緒表
{
if(pcb==TempPcb) //如果搜索到
{
OSFreeResource(pcb); //釋放資源
DeleteFromReadyList(pcb); //將其從就緒態表中刪除
OSFree((uint32)pcb,pcb->StackLength); //釋放任務所占內存
TaskAmount--; //任務數減1
OSExitCritical(); //退出臨界段
if(pcb==OSCurrentPcb) //如果刪除的是正在運行的任務
{
OSTaskSwitch(); //則執行任務切換
}
return 0; //返回0,表示刪除任務成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在就緒表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回出錯代碼,沒有這樣的任務
}
case OSInDelayStatus: //如果任務處于延時態
{
TempPcb=OSDelayList; //從延時態列表中搜索
while(TempPcb->Next) //搜索整個延時列表
{
if(pcb==TempPcb) //如果搜索到
{
OSFreeResource(pcb); //釋放資源
DeleteFromDelayList(pcb); //將其從延時態表中刪除
OSFree((uint32)pcb,pcb->StackLength); //釋放任務所占的內存
TaskAmount--; //任務數減1
OSExitCritical(); //退出臨界段
return 0; //返回刪除成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在延時態表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回出錯代碼,沒有這樣的任務
}
case OSInSuspendStatus: //如果任務處于掛起態
{
TempPcb=OSSuspendList; //從掛起態表中搜索
while(TempPcb->Next) //搜索整個掛起態列表
{
if(pcb==TempPcb) //如果搜索到
{
OSFreeResource(pcb); //釋放資源
DeleteFromSuspendList(pcb); //將起從掛起態列表中刪除
OSFree((uint32)pcb,pcb->StackLength); //釋放任務所占的內存
TaskAmount--; //任務數減1
OSExitCritical(); //退出臨界段
return 0; //返回刪除成功
}
TempPcb=TempPcb->Next; //TempPcb移動到下一個
}
//如果在掛起態表中找不到該任務,則
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回出錯代碼,沒有這樣的任務
}
default: //如果要刪除的任務不在這三種狀態中
{
OSExitCritical(); //退出臨界段
return NO_SUCH_A_TASK; //返回出錯代碼,沒有這樣的任務
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////
/**********************************************************************************************
功能:添加一個設備。
入口參數1:DeviceID。要添加設備的唯一的ID號。根據一個設備的ID號,即可查找到該設備的信息的入口地址。
返回:32位無符號整型。0表示添加失敗。非0為指向設備的指針的值。
/*********************************************************************************************/
uint32 OSAddDevice(uint32 DeviceID)
{
OSdevice * TempDevice;
OSEnterCritical(); //進入臨界段
TempDevice=(OSdevice *)OSMalloc(sizeof(OSdevice)); //申請內存
if(TempDevice==(OSdevice *)0) //如果申請內存失敗
{
OSExitCritical(); //退出臨界段,返回0。表示添加失敗失敗
return 0;
}
//將新建的設備插入到設備列表的頭部
TempDevice->Next=OSDeviceList; //被添加的設備的后趨設為OSDeviceList
TempDevice->User=(OSpcb *)0; //新建的設備初始化為沒有被使用
TempDevice->RequestCount=0; //新建的設備申請使用次數為0
TempDevice->DeviceID=DeviceID; //設置被添加設備的ID號
OSDeviceList=TempDevice; //修改OSDeviceList,使其指向表頭
OSExitCritical(); //退出臨界段
return (uint32)(TempDevice); //返回被添加的設備的地址
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:刪除一個設備。
入口參數1:DeviceID。要刪除的設備的ID號。
返回:32位無符號整型。返回0,刪除成功。非零(錯誤代號),刪除錯誤。
**********************************************************************************************/
uint32 OSDeleteDevice(uint32 DeviceID)
{
OSdevice * TempDevice;
OSEnterCritical(); //進入臨界段
TempDevice=OSDeviceList; //查找設備列表
if(OSDeviceList->DeviceID==DeviceID) //如果要被刪除的設備在表中第一項
{
OSDeviceList=OSDeviceList->Next; //設備列表指向下一個
OSFree((uint32)TempDevice,sizeof(OSdevice)); //釋放內存
OSExitCritical(); //退出臨界段
return 0; //返回0,刪除成功
}
while(TempDevice->Next) //搜索設備列表中其它設備
{
if(TempDevice->Next->DeviceID==DeviceID) //如果找到
{
TempDevice->Next=TempDevice->Next->Next; //將其中設備列表中刪除
OSFree((uint32)(TempDevice->Next),sizeof(OSdevice)); //釋放內存
OSExitCritical(); //退出臨界段
return 0; //返回0,表示刪除成功
}
TempDevice=TempDevice->Next; //移到下一個
}
OSExitCritical(); //如果設備列表搜索完,仍未找到設備,則返回錯誤代號:沒有這個設備
return NO_SUCH_A_DEVICE;
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:根據設備的ID號,獲取設備信息的入口地址。
入口參數1:DeviceID。設備的ID號。
返回:設備信息的入口地址
**********************************************************************************************/
uint32 OSGetDeviceAddr(uint32 DeviceID)
{
OSdevice * TempDevice;
OSEnterCritical(); //進入臨界段
TempDevice=OSDeviceList; //從表頭開始
while(TempDevice->Next) //直至表尾
{
if(TempDevice->DeviceID==DeviceID) //如果找到設備
{
OSExitCritical(); //退出臨界段
return (uint32)TempDevice; //返回設備信息的入口地址
}
TempDevice=TempDevice->Next; //移向下一個
}
OSExitCritical(); //退出臨界段
return 0; //返回0,表示獲取失敗
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:申請使用一個設備。
入口參數1:DeviceAddr。設備信息的入口地址。
入口參數2:DelayTicks。等待的時鐘節拍數。為0時,永久等待。
返回:32位無符號整型。返回0,表示申請失敗,超時。返回1申請成功。
備注:如果一個設備被一個任務使用后,它將一直被占用,直到該設備被釋放為止
**********************************************************************************************/
uint32 OSRequestDevice(uint32 DeviceAddr,uint32 DelayTicks)
{
OSEnterCritical(); //進入臨界段
if(((OSdevice *)DeviceAddr)->User==0) //如果該設備未使用
{
((OSdevice *)DeviceAddr)->User=OSCurrentPcb; //則使用該設備
OSExitCritical(); //退出臨界段
return 1; //返回1,申請成功
}
else //如果設備已被使用,
{
((OSdevice *)DeviceAddr)->RequestCount++; //則將請求的次數加1
OSCurrentPcb->WaitFor=((OSdevice *)DeviceAddr)->DeviceID; //設置任務等待的原因
if(DelayTicks) //如果延時的時鐘節拍數非0,
{
OSExitCritical(); //退出臨界段,
OSTaskDelay(DelayTicks); //延遲DelayTicks個時鐘節拍
if(OSCurrentPcb->Delay) //如果任務延遲時間未到就被喚醒,則說明等待成功
{
OSEnterCritical(); //進入臨界段
OSCurrentPcb->Delay=0; //將剩余的延遲時間設置為0
OSExitCritical(); //退出臨界段
return 1; //返回1,表示成功
}
else
{
return 0; //返回0,表示等待超時
}
}
else //如果DelayTicks為0,表示任務一直等待
{
OSExitCritical(); //退出臨界段
OSTaskSuspend(OSCurrentPcb); //將任務掛起
return 1; //被喚醒后,返回1。等待成功。
}
}
}
//////////////////////////////////End of function//////////////////////////////////////////////
/**********************************************************************************************
功能:釋放一個設備的使用權。
入口參數1:DeviceAddr。設備信息的入口地址。
返回:無。
備注:設備被使用后,要調用該函數釋放設備。否則其它任務不能使用該設備。
**********************************************************************************************/
void OSFreeDevice(uint32 DeviceAddr)
{
OSpcb * TempPcb;
OSEnterCritical(); //進入臨界段
if(((OSdevice *)DeviceAddr)->RequestCount) //如果有任務在等待使用該設備
{
((OSdevice *)DeviceAddr)->RequestCount--; //請求次數減1
TempPcb=OSSuspendList; //查找掛起態表,看是否有請求該設備的任務
while(TempPcb->Next) //直到掛起列表的尾部
{
if(TempPcb->WaitFor==((OSdevice *)DeviceAddr)->DeviceID) //如果找到等待該設備的任務
{
((OSdevice *)DeviceAddr)->User=TempPcb; //將設備的使用權給該任務
TempPcb->WaitFor=0; //清除該任務等待的原因
DeleteFromSuspendList(TempPcb); //將其從掛起態列表中刪除
InsertToReadyList(TempPcb); //插入到就緒表中
OSExitCritical(); //退出臨界段
OSTaskSwitch(); //任務切換
return; //返回
}
TempPcb=TempPcb->Next; //移到下一個
}
TempPcb=OSDelayList; //查找延時表
while(TempPcb->Next) //直到延時表的尾部
{
if(TempPcb->WaitFor==((OSdevice *)DeviceAddr)->DeviceID) //如果找到等待該設備的任務
{
((OSdevice *)DeviceAddr)->User=TempPcb; //將該設備使用權給該任務
TempPcb->WaitFor=0; //清除等待原因
DeleteFromDelayList(TempPcb); //將其從延時表中刪除
InsertToReadyList(TempPcb); //插入到就緒表中
OSExitCritical(); //退出臨界段
OSTaskSwitch(); //任務切換
return; //返回
}
TempPcb=TempPcb->Next; //移到下一個
}
}
//如果沒有其它任務申請使用該設備,則
((OSdevice *)DeviceAddr)->User=(OSpcb *)0; //該設備無任務使用
OSExitCritical(); //退出臨界段
return; //返回
}
//////////////////////////////////End of function//////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -