212 lines
4.2 KiB
C++
212 lines
4.2 KiB
C++
#include "TTime.h"
|
||
|
||
#include "Core\Environment.h"
|
||
|
||
#if defined(__CC_ARM)
|
||
#include <time.h>
|
||
#else
|
||
#include <ctime>
|
||
#endif
|
||
|
||
#define TIME_DEBUG 0
|
||
|
||
#define UTC true // utc 从1970/1/1 开始计时
|
||
#define UTC_CALIBRATE 946684800UL // 2000/1/1 - 1970/1/1 秒值
|
||
#ifdef UTC
|
||
#define BASE_YEAR_US 62135596800UL // (63082281600UL-UTC_CALIBRATE) // 从0 到 2000-01-01的所有秒数
|
||
#else
|
||
#define BASE_YEAR_US 63082281600UL // 从0 到 2000-01-01的所有秒数
|
||
#endif
|
||
/************************************************ TTime ************************************************/
|
||
|
||
TTime::TTime()
|
||
{
|
||
Seconds = 0;
|
||
//Ticks = 0;
|
||
#if defined(STM32F0) || defined(GD32F150)
|
||
Index = 13;
|
||
#else
|
||
Div = 0;
|
||
if(Sys.FlashSize > 0x80)
|
||
Index = 5;
|
||
else
|
||
Index = 1; // 错开开关的 TIM3 背光
|
||
#endif
|
||
BaseSeconds = 0;
|
||
|
||
OnInit = nullptr;
|
||
OnLoad = nullptr;
|
||
OnSave = nullptr;
|
||
OnSleep = nullptr;
|
||
}
|
||
|
||
void TTime::SetTime(UInt64 sec)
|
||
{
|
||
if(sec >= BASE_YEAR_US) sec -= BASE_YEAR_US;
|
||
|
||
BaseSeconds = sec - Seconds;
|
||
|
||
#if DEBUG
|
||
/*DateTime dt(sec);
|
||
debug_printf("TTime::SetTime 设置时间 ");
|
||
dt.Show(true);*/
|
||
#endif
|
||
|
||
// 保存到RTC
|
||
if(OnSave) OnSave();
|
||
}
|
||
|
||
#if !defined(TINY) && defined(STM32F0)
|
||
#if defined(__CC_ARM)
|
||
#pragma arm section code = "SectionForSys"
|
||
#elif defined(__GNUC__)
|
||
__attribute__((section("SectionForSys")))
|
||
#endif
|
||
#endif
|
||
|
||
void TTime::Sleep(int ms, bool* running) const
|
||
{
|
||
// 睡眠时间太短
|
||
if(ms <= 0) return;
|
||
|
||
// 结束时间
|
||
Int64 end = Current() + ms;
|
||
|
||
// 较大的睡眠时间直接让CPU停下来
|
||
if(OnSleep && ms >= 10)
|
||
{
|
||
while(ms >= 10)
|
||
{
|
||
OnSleep(ms);
|
||
|
||
// 判断是否需要继续
|
||
if(running != nullptr && !*running) break;
|
||
|
||
// 重新计算剩下的时间
|
||
ms = (int)(end - Current());
|
||
}
|
||
}
|
||
// 睡眠时间太短
|
||
if(!ms || (running && !*running)) return;
|
||
|
||
// 空转
|
||
while(true)
|
||
{
|
||
if(Current() >= end) break;
|
||
if(running != nullptr && !*running) break;
|
||
}
|
||
}
|
||
|
||
void TTime::Delay(int us) const
|
||
{
|
||
// 睡眠时间太短
|
||
if(us <= 0) return;
|
||
|
||
// 较大的时间,按毫秒休眠
|
||
if(us >= 1000)
|
||
{
|
||
Sleep(us / 1000);
|
||
us %= 1000;
|
||
}
|
||
// 睡眠时间太短
|
||
if(!us) return;
|
||
|
||
// 无需关闭中断,也能实现延迟
|
||
UInt64 ms = Current();
|
||
uint ticks = CurrentTicks() + UsToTicks(us);
|
||
uint max = UsToTicks(1000 - 1);
|
||
if(ticks >= max)
|
||
{
|
||
ms++;
|
||
ticks -= max;
|
||
}
|
||
|
||
while(true)
|
||
{
|
||
int n = Current() - ms;
|
||
if(n > 0) break;
|
||
if(n == 0 && CurrentTicks() >= ticks) break;
|
||
}
|
||
}
|
||
|
||
#if !defined(TINY) && defined(STM32F0)
|
||
#if defined(__CC_ARM)
|
||
#pragma arm section code
|
||
#elif defined(__GNUC__)
|
||
__attribute__((section("")))
|
||
#endif
|
||
#endif
|
||
|
||
extern "C"
|
||
{
|
||
// 获取系统启动后经过的毫秒数
|
||
clock_t clock(void)
|
||
{
|
||
return Time.Current();
|
||
}
|
||
|
||
// 实现C函数库的time函数
|
||
time_t time(time_t* sec)
|
||
{
|
||
uint s = Time.BaseSeconds + Time.Seconds;
|
||
if(sec) *sec = s;
|
||
|
||
return s;
|
||
}
|
||
}
|
||
|
||
/************************************************ TimeWheel ************************************************/
|
||
|
||
TimeWheel::TimeWheel(uint ms)
|
||
{
|
||
Sleep = 0;
|
||
Reset(ms);
|
||
}
|
||
|
||
void TimeWheel::Reset(uint ms)
|
||
{
|
||
Expire = Time.Current() + + ms;
|
||
}
|
||
|
||
// 是否已过期
|
||
bool TimeWheel::Expired()
|
||
{
|
||
UInt64 now = Time.Current();
|
||
if(now > Expire) return true;
|
||
|
||
// 睡眠,释放CPU
|
||
if(Sleep) Sys.Sleep(Sleep);
|
||
|
||
return false;
|
||
}
|
||
|
||
/************************************************ TimeCost ************************************************/
|
||
|
||
TimeCost::TimeCost()
|
||
{
|
||
Start = Time.Current();
|
||
StartTicks = Time.CurrentTicks();
|
||
}
|
||
|
||
// 逝去的时间,微秒
|
||
int TimeCost::Elapsed()
|
||
{
|
||
int ts = (int)(Time.CurrentTicks() - StartTicks);
|
||
int ms = (int)(Time.Current() - Start);
|
||
|
||
// 有可能滴答部分不是完整的一圈
|
||
if(ts > 0) return ms * 1000 + Time.TicksToUs(ts);
|
||
|
||
// 如果毫秒部分也没有,那么可能是微小错误偏差
|
||
if(ms <= 0) return 0;
|
||
|
||
// 如果滴答是负数,则干脆减去
|
||
return ms * 1000 - Time.TicksToUs(-ts);
|
||
}
|
||
|
||
void TimeCost::Show(cstring format)
|
||
{
|
||
if(!format) format = "执行 %dus\r\n";
|
||
debug_printf(format, Elapsed());
|
||
}
|