⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arm_00_ostaskmanager.bak

📁 一个基于arm的
💻 BAK
字号:
/**********************************************************************************************
  ARM_00_OSTaskManager.c file
   
  作者:Computer-lov
  建立日期:2006-5-13
  修改日期:2006-5-15
  版本:V1.0
  版权所有,盗版必究。
  任何技术问题可到我的博客上留言:    http://computer00.21ic.org
  Copyright(C) Computer-lov 2006-2016
  All rights reserved
**********************************************************************************************/


#include <ADuC7026.H>
#include "my_type.h"

#include "ARM_00_OS_TaskSwitch.H"
#include "ARM_00_OS_Core.H"
#include "UART.H"
#include "KEYS.H"
#include "Task.h"
#include "ADC.H"

/**********************************************************************************************
功能:显示任务的PID号。
入口参数1:pcb。要显示的任务的进程控制块地址。
返回:无。
**********************************************************************************************/
void DisplayPID(OSpcb * pcb)
{
 print_uint32(pcb->PID);  //显示任务ID号(PID)
 send_a_byte(' ');
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:显示任务的CPU使用率。
入口参数1:pcb。要显示的任务的进程控制块地址。
返回:无。
**********************************************************************************************/
void DisplayCPU(OSpcb * pcb)
{
 uint32 CpuUsedRatio;

 CpuUsedRatio=((pcb->RunTimeInThisRefreshPeriod)*100+TotalTime/2)/TotalTime;  //计算CPU使用率。加TotalTime/2是为了四舍无入
 pcb->TotalRunTime+=pcb->RunTimeInThisRefreshPeriod;  //累加任务的CPU使用总时间
 pcb->RunTimeInThisRefreshPeriod=0;   //清本次统计的时间
 if(CpuUsedRatio>=100)  //如果统计的结果大于100
  {
   CpuUsedRatio=99;  //结果为99
  }
 send_a_byte((CpuUsedRatio/10)+'0');  //显示结果
 send_a_byte((CpuUsedRatio%10)+'0');
 send_a_byte('%');
 send_a_byte(' ');
 send_a_byte(' ');
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:显示任务使用CPU的总时间。
入口参数1:pcb。要显示的任务的进程控制块地址。
返回:无。
**********************************************************************************************/
void DisplayCPUTime(OSpcb * pcb)
{
 uint32 Time;   //用来保存时间
 uint8 H,M,S;   //用来保存时,分,秒
 
 Time=(uint32)((pcb->TotalRunTime)/((MaxOfTimer0+1)*100));  //计算总时间。结果为多少秒。
 S=Time%60;   //计算秒
 Time/=60;
 M=Time%(60);  //计算分
 Time/=60;
 H=Time%(24);  //计算时
 
 send_a_byte((H/10)+'0'); //显示时
 send_a_byte((H%10)+'0');
 send_a_byte(':');
 send_a_byte((M/10)+'0'); //显示分
 send_a_byte((M%10)+'0');
 send_a_byte(':');
 send_a_byte((S/10)+'0'); //显示秒
 send_a_byte((S%10)+'0');
 send_a_byte(' ');
 send_a_byte(' ');
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:显示内存使用量
入口参数1:pcb。要显示的任务的进程控制块地址。
返回:无。
**********************************************************************************************/
void DispalyMemroyUsed(OSpcb * pcb)
{
 print_uint32(pcb->StackLength);   //显示内存使用量
 send_a_byte('B');               //显示单位
 send_a_byte(' ');
 send_a_byte(' ');
}
//////////////////////////////////End of function//////////////////////////////////////////////


/**********************************************************************************************
功能:显示任务所处的状态。
入口参数1:pcb。要显示的任务的进程控制块地址。
返回:无。
**********************************************************************************************/
void DispalyStatus(OSpcb * pcb)
{
 switch(pcb->Status)    //根据状态来显示
  {
   case OSInReadyStatus:      prints("Ready  ",0);break;  //就绪态
   case OSInDelayStatus:      prints("Delay  ",0);break;  //延时态
   case OSInSuspendStatus:    prints("Suspend",0);break;  //挂起态
   default:break;
  }
}
//////////////////////////////////End of function//////////////////////////////////////////////



#define REF_VOL  2.5

//////////////////////////////显示内核电压////////////////////////////////////
void DisplayCoreVoltage(void)
{
 uint16 value;
 uint32 result;
 uint8 s_result[10];

 prints("Core voltage: ",0);
 value=2*read_ADC(0x13);	  //通道号为0x13的电压为1/2电源电压
 result=REF_VOL*10000;		  //换算成电压,结果为多少mV的10倍
 result=result*value/4096;
 s_result[9]=0;				  //将结果转换成字符串
 s_result[8]=' ';
 s_result[7]='V';
 s_result[6]='m';
 s_result[5]='0'+result%10;
 result/=10;
 s_result[4]='.';
 s_result[3]='0'+result%10;
 result/=10;
 s_result[2]='0'+result%10;
 result/=10;
 s_result[1]='0'+result%10;
 result/=10;
 s_result[0]='0'+result%10;
 prints("    ",0);
 prints(s_result,0);		 //显示电压
 prints("  ",0);
}
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////显示内核温度////////////////////////////////
void DisplayCoreTemperature(void)
{
 uint16 value;
 sint32 result;
 uint8 s_result[10];

 prints("Core temperature: ",0);
 value=read_ADC(0x10);		   //通道号为0x10的是温度传感器电压
 result=REF_VOL*10000;		   //换算成电压,结果为多少mV的10倍
 result=result*value/4096;
 result=((7800-result)*10/13)+250;	 //温度是25℃时,输出电压为780mV,每升高1℃,输出电压降低1.3mV
                                     //计算结果为多少度的10倍
 if(result<0)				   //如果温度小于0度
  {
   s_result[0]='-';			//显示负号
   result*=-1;				//将结果换成正的
  }
 else
  {
   s_result[0]=' ';		   //不显示负号
  }
 s_result[6]=0;			   //将温度值转换成字符串,供显示用
 s_result[5]='0'+result%10;
 result/=10;
 s_result[4]='.';
 s_result[3]='0'+result%10;
 result/=10;
 s_result[2]='0'+result%10;
 result/=10;
 s_result[1]='0'+result%10;
 prints(s_result,0);		//显示温度结果
 prints("℃",1);
}
//////////////////////////////////////////////////////////////////////////////


/**********************************************************************************************
功能:任务管理器。
入口参数:无。
返回:无。
备注:优先级被设置为1,处于高的优先级。
**********************************************************************************************/
void OSTaskManager(void)
{
 OSpcb * pcb;    //
 uint32 TempTime;    //TempTime用来保存 在显示任务管理器信息所花费的时间
 uint32 DelayCount=RefreshPeriod;   //延时多少个时钟节拍刷新一次任务管理器
 uint32 * p;     //
 uint32 i;       //
 uint32 CpuUsedRatio;   //保存CPU使用率
 uint32 nBytes;         //保存申请内存的字节数
 
 uint32 PrinterDeviceAddr;   //打印机设备的入口地址
 
 PrinterDeviceAddr=OSGetDeviceAddr(OS_PRINTER_DEVICE_ID);  //获取打印机设备的入口地址
 OSRequestDevice(PrinterDeviceAddr,0);   //申请使用打印机
 
 prints("",1);                   //显示任务启动
 prints(OSCurrentPcb->Title,0);
 prints(" Start.",1);
 
 OSFreeDevice(PrinterDeviceAddr);   //释放打印机
 
 ADC_init();   //ADC初始化。用来检测内核电压以及温度

 while(1)
  {
   OSTaskDelay(DelayCount);    //延时DelayCount个时钟节拍
   
   pcb=OSCurrentPcb;       //当前运行的任务。即任务管理器本身
   TempTime=pcb->RunTimeInThisRefreshPeriod;   //保存这时的时间
   
   OSRequestDevice(PrinterDeviceAddr,0);   //申请使用打印机
   
   prints("",1);       //换行
   prints("",1);
   prints("TaskName              PID  CPU   CPUTime    MemoryUsed   Status",1);   //显示表头
   prints("---------------------------------------------------------------",1);
   
   nBytes=OSSizePerBlock*(((TaskAmount+1)*sizeof(p)+OSSizePerBlock-1)/OSSizePerBlock);  //计算需要申请多少字节内存
   
   p=(uint32 *)OSMalloc(nBytes);  //申请一块内存,用来保存所有任务的pcb指针。供下面显示用
   OSCurrentPcb->StackLength+=nBytes;   //申请内存后,调节任务管理器的内存使用长度

   i=0;
   
   prints(pcb->Title,0);   //显示任务名字
   DisplayPID(pcb);         //显示任务的的PID
   TempTime=pcb->RunTimeInThisRefreshPeriod-TempTime;  //计算出前面显示花费的时间
   DisplayCPU(pcb);        //显示任务管理器所使用的CPU使用率
   DisplayCPUTime(pcb);    //显示任务管理器所使用的CPU总时间
   DispalyMemroyUsed(pcb);  //显示任务管理器所使用的内存
   prints("Running",0);     //显示任务管理器的状态为运行状态
   prints("",1);           //换行
   
   OSEnterCritical();   //进入临界段
   
   pcb=OSReadyList->Next;   //pcb保存就绪表的下一个。就绪表的第一个为当前运行的任务,即任务管理器
   while((pcb->Next)!=(OSpcb *)0)   //遍历整个就绪表
    {
	 p[i++]=(uint32)pcb;    //保存就绪表的pcb
	 pcb=pcb->Next;         //移向就绪表的下一个
	}
   p[i++]=(uint32)pcb;     //最后一个为空闲任务的pcb。
   
   
   //计算CPU使用率并保存至CpuUsedRatio。CPU使用率是100%减掉空闲任务的使用率
   CpuUsedRatio=100-((pcb->RunTimeInThisRefreshPeriod)*100+TotalTime/2)/TotalTime;
   pcb=OSDelayList;   //延时态表
   while((pcb->Next)!=(OSpcb *)0)  //遍历整个延时态表
    {
	 p[i++]=(uint32)pcb;  //保存延时态表的pcb
	 pcb=pcb->Next;      // 移向下一个
	}
   pcb=OSSuspendList;  //挂起态表
   while((pcb->Next)!=(OSpcb *)0)   //遍历整个挂起态表
    {
	 p[i++]=(uint32)pcb;   //保存挂起态pcb
	 pcb=pcb->Next;       //移向下一个
	}
   p[i]=0;        //结束
   OSExitCritical();   //退出临界段
   i=0;   //准备显示任务信息
   while(p[i]!=0)   //直到结束为止
    {
	 prints(((OSpcb *)(p[i]))->Title,0);   //显示任务名
	 DisplayPID((OSpcb *)(p[i]));          //显示任务ID
	 DisplayCPU((OSpcb *)(p[i]));          //显示任务CPU使用率
	 DisplayCPUTime((OSpcb *)(p[i]));      //显示任务使用CPU的总时间
	 DispalyMemroyUsed((OSpcb *)(p[i]));   //显示任务使用的内存量
	 DispalyStatus((OSpcb *)(p[i]));       //显示任务当前所处的状态
	 prints("",1);                         //换行
     i++;                                  //移到下一个
	}
   
   prints("",1);                  //显示CPU使用率
   prints("CPU used ratio: ",0);
   if(CpuUsedRatio>=100)   //如果CPU使用率为100%,
    {
	 prints("100%",1);  //则显示100%
	}
   else
    {
     send_a_byte(CpuUsedRatio/10+'0');  //显示十位
     send_a_byte(CpuUsedRatio%10+'0');  //显示个位
     prints("%",1);
    }
   prints("Total memory: ",0);   //显示总内存量
   print_uint32(OSGetMemoryPoolSize());
   prints("B   Memory used: ",0);   //显示内存使用量
   i=OSMemoryStatistic();    //获取内存使用量
   print_uint32(i);
   prints("B   Memory used ratio: ",0);  //显示内存使用率
   i=i*100/OSGetMemoryPoolSize();    //计算内存使用率
   send_a_byte(i/10+'0');
   send_a_byte(i%10+'0');
   prints("%",1);
   
   DisplayCoreVoltage();   //显示内核电压
   DisplayCoreTemperature();   //显示内核温度
   prints("",1);
   
   
   OSFreeDevice(PrinterDeviceAddr);  //释放打印机使用权
   
   OSFree((uint32)p,nBytes);   //释放p的内存
   OSCurrentPcb->StackLength-=nBytes;   //调整任务管理器的内存使用数量
  
   TempTime+=OSCurrentPcb->RunTimeInThisRefreshPeriod;  //计算上面显示所花费的时间
   DelayCount=RefreshPeriod-(TempTime)/(MaxOfTimer0+1);  //计算下一次统计资源,应该需要多少个时钟节拍                                                            //因为显示信息时要花费时间,应该将其减去
  }
}
//////////////////////////////////End of function//////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -