较大的Sys.Delay也需要进行时间任务调度,默认以50us作为边界
This commit is contained in:
parent
43cd70a28d
commit
dbd64c0fac
39
Sys.cpp
39
Sys.cpp
|
@ -449,8 +449,8 @@ void TSys::ToHex(byte* buf, byte* src, uint len)
|
|||
// 任务
|
||||
#include "Task.h"
|
||||
|
||||
// 创建任务,返回任务编号。priority优先级,dueTime首次调度时间us,period调度间隔us,-1表示仅处理一次
|
||||
uint TSys::AddTask(Action func, void* param, Int64 dueTime, Int64 period, string name)
|
||||
// 创建任务,返回任务编号。dueTime首次调度时间ms,period调度间隔ms,-1表示仅处理一次
|
||||
uint TSys::AddTask(Action func, void* param, int dueTime, int period, string name)
|
||||
{
|
||||
return Task::Scheduler()->Add(func, param, dueTime, period, name);
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ void TSys::RemoveTask(uint& taskid)
|
|||
taskid = 0;
|
||||
}
|
||||
|
||||
bool TSys::SetTask(uint taskid, bool enable, int usNextTime)
|
||||
bool TSys::SetTask(uint taskid, bool enable, int msNextTime)
|
||||
{
|
||||
if(!taskid) return false;
|
||||
|
||||
|
@ -471,7 +471,7 @@ bool TSys::SetTask(uint taskid, bool enable, int usNextTime)
|
|||
task->Enable = enable;
|
||||
|
||||
// 可以安排最近一次执行的时间,比如0表示马上调度执行
|
||||
if(usNextTime >= 0) task->NextTime = Time.Current() + usNextTime;
|
||||
if(msNextTime >= 0) task->NextTime = Time.Current() + msNextTime;
|
||||
|
||||
// 如果系统调度器处于Sleep,让它立马退出
|
||||
if(enable) Task::Scheduler()->Sleeping = false;
|
||||
|
@ -480,7 +480,7 @@ bool TSys::SetTask(uint taskid, bool enable, int usNextTime)
|
|||
}
|
||||
|
||||
// 改变任务周期
|
||||
bool TSys::SetTaskPeriod(uint taskid, Int64 period)
|
||||
bool TSys::SetTaskPeriod(uint taskid, int period)
|
||||
{
|
||||
if(!taskid) return false;
|
||||
|
||||
|
@ -511,10 +511,10 @@ void TSys::Start()
|
|||
Task::Scheduler()->Start();
|
||||
}
|
||||
|
||||
void TimeSleep(uint ms)
|
||||
void TimeSleep(uint us)
|
||||
{
|
||||
// 在这段时间里面,去处理一下别的任务
|
||||
if(Sys.Started)
|
||||
if(Sys.Started && us != 0 && us >= 50)
|
||||
{
|
||||
TaskScheduler* sc = Task::Scheduler();
|
||||
// 记录当前正在执行任务
|
||||
|
@ -522,32 +522,32 @@ void TimeSleep(uint ms)
|
|||
|
||||
TimeCost tc;
|
||||
// 实际可用时间。100us一般不够调度新任务,留给硬件等待
|
||||
int total = ms;
|
||||
int total = us;
|
||||
// 如果休眠时间足够长,允许多次调度其它任务
|
||||
while(true)
|
||||
{
|
||||
// 统计这次调度的时间,累加作为当前任务的休眠时间
|
||||
TimeCost tc2;
|
||||
|
||||
sc->Execute(total);
|
||||
sc->Execute(total / 1000);
|
||||
|
||||
total -= tc2.Elapsed();
|
||||
|
||||
if(total <= 0) break;
|
||||
}
|
||||
|
||||
int cost = tc.Elapsed();
|
||||
int ct = tc.Elapsed();
|
||||
if(task)
|
||||
{
|
||||
sc->Current = task;
|
||||
task->SleepTime += cost;
|
||||
task->SleepTime += ct;
|
||||
}
|
||||
|
||||
if(cost >= ms) return;
|
||||
if(ct >= us) return;
|
||||
|
||||
ms -= cost;
|
||||
us -= ct;
|
||||
}
|
||||
if(ms) Time.Sleep(ms);
|
||||
if(us) Time.Delay(us);
|
||||
}
|
||||
|
||||
void TSys::Sleep(uint ms)
|
||||
|
@ -558,10 +558,10 @@ void TSys::Sleep(uint ms)
|
|||
else
|
||||
{
|
||||
#if DEBUG
|
||||
if(ms > 1000) debug_printf("Sys::Sleep 设计错误,睡眠%dms太长,超过1000ms建议使用多线程Thread!", ms);
|
||||
if(ms > 1000) debug_printf("Sys::Sleep 设计错误,睡眠%dms太长!", ms);
|
||||
#endif
|
||||
|
||||
TimeSleep(ms);
|
||||
TimeSleep(ms * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -573,10 +573,13 @@ void TSys::Delay(uint us)
|
|||
else
|
||||
{
|
||||
#if DEBUG
|
||||
if(us > 1000000) debug_printf("Sys::Sleep 设计错误,睡眠%dus太长,超过1000ms建议使用多线程Thread!", us);
|
||||
if(us > 1000000) debug_printf("Sys::Sleep 设计错误,睡眠%dus太长!", us);
|
||||
#endif
|
||||
|
||||
Time.Delay(us);
|
||||
if(us < 50)
|
||||
Time.Delay(us);
|
||||
else
|
||||
TimeSleep(us);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
8
Sys.h
8
Sys.h
|
@ -120,13 +120,13 @@ private:
|
|||
int _Index; // MCU在型号表中的索引
|
||||
|
||||
public:
|
||||
// 创建任务,返回任务编号。dueTime首次调度时间us,period调度间隔us,-1表示仅处理一次
|
||||
uint AddTask(Action func, void* param, Int64 dueTime = 0, Int64 period = 0, string name = NULL);
|
||||
// 创建任务,返回任务编号。dueTime首次调度时间ms,period调度间隔ms,-1表示仅处理一次
|
||||
uint AddTask(Action func, void* param, int dueTime = 0, int period = 0, string name = NULL);
|
||||
void RemoveTask(uint& taskid);
|
||||
// 设置任务的开关状态,同时运行指定任务最近一次调度的时间,0表示马上调度
|
||||
bool SetTask(uint taskid, bool enable, int usNextTime = -1);
|
||||
bool SetTask(uint taskid, bool enable, int msNextTime = -1);
|
||||
// 改变任务周期
|
||||
bool SetTaskPeriod(uint taskid, Int64 period);
|
||||
bool SetTaskPeriod(uint taskid, int period);
|
||||
void Start(); // 开始系统大循环
|
||||
Func OnStart;
|
||||
};
|
||||
|
|
38
Task.cpp
38
Task.cpp
|
@ -11,6 +11,7 @@ Task::Task()
|
|||
CpuTime = 0;
|
||||
SleepTime = 0;
|
||||
Cost = 0;
|
||||
CostMs = 0;
|
||||
MaxCost = 0;
|
||||
Enable = true;
|
||||
Event = false;
|
||||
|
@ -45,19 +46,20 @@ bool Task::Execute(ulong now)
|
|||
|
||||
// 累加任务执行次数和时间
|
||||
Times++;
|
||||
int cost = tc.Elapsed();
|
||||
if(cost < 0) debug_printf("cost = %d \r\n", cost);
|
||||
if(cost < 0) cost = -cost;
|
||||
//if(cost > 0)
|
||||
int ct = tc.Elapsed();
|
||||
if(ct < 0) debug_printf("cost = %d \r\n", ct);
|
||||
if(ct < 0) ct = -ct;
|
||||
//if(ct > 0)
|
||||
{
|
||||
cost -= SleepTime;
|
||||
if(cost > MaxCost) MaxCost = cost;
|
||||
CpuTime += cost;
|
||||
ct -= SleepTime;
|
||||
if(ct > MaxCost) MaxCost = ct;
|
||||
CpuTime += ct;
|
||||
Cost = CpuTime / Times;
|
||||
CostMs = Cost / 1000;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if(cost > 500000) debug_printf("Task::Execute 任务 %d [%d] 执行时间过长 %dms 睡眠 %dms\r\n", ID, Times, cost, SleepTime);
|
||||
if(ct > 500000) debug_printf("Task::Execute 任务 %d [%d] 执行时间过长 %dus 睡眠 %dus\r\n", ID, Times, ct, SleepTime);
|
||||
#endif
|
||||
|
||||
// 如果只是一次性任务,在这里清理
|
||||
|
@ -71,17 +73,17 @@ bool Task::Execute(ulong now)
|
|||
// 显示状态
|
||||
void Task::ShowStatus()
|
||||
{
|
||||
debug_printf("Task::%s \t%d [%d] \t平均 %dms ", Name, ID, Times, Cost);
|
||||
debug_printf("Task::%s \t%d [%d] \t平均 %dus ", Name, ID, Times, Cost);
|
||||
if(Cost < 1000) debug_printf("\t");
|
||||
|
||||
debug_printf("\t最大 %dms ", MaxCost);
|
||||
debug_printf("\t最大 %dus ", MaxCost);
|
||||
if(MaxCost < 1000) debug_printf("\t");
|
||||
|
||||
debug_printf("\t周期 ");
|
||||
if(Period >= 1000)
|
||||
debug_printf("%ds", (int)(Period / 1000));
|
||||
debug_printf("%ds", Period / 1000);
|
||||
else
|
||||
debug_printf("%dms", (int)Period);
|
||||
debug_printf("%dms", Period);
|
||||
if(!Enable) debug_printf(" 禁用");
|
||||
debug_printf("\r\n");
|
||||
}
|
||||
|
@ -236,7 +238,7 @@ void TaskScheduler::Execute(uint msMax)
|
|||
|
||||
if((task->NextTime <= now || task->NextTime < 0)
|
||||
// 并且任务的平均耗时要足够调度,才安排执行,避免上层是Sleep时超出预期时间
|
||||
&& Time.Current() + task->Cost <= end)
|
||||
&& Time.Current() + task->CostMs <= end)
|
||||
{
|
||||
task->Execute(now);
|
||||
|
||||
|
@ -255,12 +257,12 @@ void TaskScheduler::Execute(uint msMax)
|
|||
}
|
||||
}
|
||||
|
||||
int cost = tc.Elapsed();
|
||||
int ct = tc.Elapsed();
|
||||
if(Cost > 0)
|
||||
Cost = (Cost + cost) / 2;
|
||||
Cost = (Cost + ct) >> 1;
|
||||
else
|
||||
Cost = cost;
|
||||
if(cost > MaxCost) MaxCost = cost;
|
||||
Cost = ct;
|
||||
if(ct > MaxCost) MaxCost = ct;
|
||||
|
||||
// 如果有最小时间,睡一会吧
|
||||
now = Time.Current(); // 当前时间
|
||||
|
@ -281,7 +283,7 @@ void TaskScheduler::ShowStatus(void* param)
|
|||
{
|
||||
TaskScheduler* host = (TaskScheduler*)param;
|
||||
|
||||
debug_printf("Task::ShowStatus 平均 %dms 最大 %dms 系统启动 ", host->Cost, host->MaxCost);
|
||||
debug_printf("Task::ShowStatus 平均 %dus 最大 %dus 系统启动 ", host->Cost, host->MaxCost);
|
||||
Time.Now().Show(true);
|
||||
|
||||
IArray<Task>& ts = *(host->_Tasks);
|
||||
|
|
13
Task.h
13
Task.h
|
@ -25,10 +25,11 @@ public:
|
|||
Int64 NextTime; // 下一次执行时间ms
|
||||
|
||||
int Times; // 执行次数
|
||||
int CpuTime; // 总耗费时间
|
||||
int SleepTime; // 当前睡眠时间
|
||||
int Cost; // 平均执行时间
|
||||
int MaxCost; // 最大执行时间
|
||||
int CpuTime; // 总耗费时间us
|
||||
int SleepTime; // 当前睡眠时间us
|
||||
int Cost; // 平均执行时间us
|
||||
int CostMs; // 平均执行时间ms
|
||||
int MaxCost; // 最大执行时间us
|
||||
|
||||
bool Enable; // 是否启用
|
||||
bool Event; // 是否只执行一次后暂停的事件型任务
|
||||
|
@ -63,8 +64,8 @@ public:
|
|||
bool Running; // 是否正在运行
|
||||
bool Sleeping; // 如果当前处于Sleep状态,马上停止并退出
|
||||
|
||||
int Cost; // 平均执行时间
|
||||
int MaxCost; // 最大执行时间
|
||||
int Cost; // 平均执行时间us
|
||||
int MaxCost; // 最大执行时间us
|
||||
|
||||
TaskScheduler(string name = NULL);
|
||||
~TaskScheduler();
|
||||
|
|
Loading…
Reference in New Issue