📄 arm_00_ostaskmanager.c
字号:
/**********************************************************************************************
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/4095;
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/4095;
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 + -