📄 arm_00_os_core.c
字号:
备注:如果任务自己申请了内存,一定要任务自己先释放内存,否则任务被删除后,内存没有释放,会导致内存泄漏。
**********************************************************************************************/
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 + -