📄 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 + -