SylixOS里的时间【5】--- TOD时间实现

计时变量

SylixOS里用到的大部分时间接口都是针对TOD(time of date)日期时间的,TOD时间通过心跳中断来更新,但并不是用的心跳中断计数变量实现的,而是另外两个全局变量_K_tvTODCurrent和_K_tvTODMono实现。

__KERNEL_EXT struct timespec         _K_tvTODCurrent;                   /*  当前TOD时间 CLOCK_REALTIME  */
__KERNEL_EXT struct timespec         _K_tvTODMono;                      /*  MonoTOD时间 CLOCK_MONOTONIC */

这两个时间变量都是纳秒精度的额,其中_K_tvTODMono是单调递增的,记录的是系统启动后累计运行的纳秒数;而_K_tvTODCurrent才是实际的TOD时间,它在运行中可能会被微调,也可能会配修改。

_K_tvTODCurrent被微调时还用用到下面两个全局变量。

KERNEL_EXT INT32                   _K_iTODDelta;                      /*  系统时钟微调 tick 参数      */
__KERNEL_EXT INT32                 _K_iTODDeltaNs;                    /*  系统时钟微调 ns 参数        */

初始化

这两个时间变量在系统启动时会被_RtcInit 函数初始化,代码位于libsylixos\SylixOS\kernel\core_RtcInit.c。其中_K_tvTODMono会被初始化为0,_K_tvTODCurrent被初始化为2000.1.1 0:0:0,如果系统具备RTC硬件则会同步为RTC 时间。

VOID  _RtcInit (VOID)
{
    /*
     *  初始化为 2000.1.1 0:0:0
     */
    struct tm   tmNow = {
        0, 0, 0, 1, 0, (2000 - 1900), 6, 0, 0
    };
    
    time_t  timeNow = lib_timegm(&tmNow);
    
    timezone = (-(3600 * 8));                    /*  默认为东8区 CST-8:00:00     */
    
    _K_tvTODCurrent.tv_sec  = timeNow;
    _K_tvTODCurrent.tv_nsec = 0;
    
    _K_tvTODMono.tv_sec  = 0;
    _K_tvTODMono.tv_nsec = 0;
}

时间更新

在系统心跳中断中每次这两个时间变量加LW_NSEC_PER_TICK纳秒时间,而不是计数加一。同时根据修正参数还会微调_K_tvTODCurrent时间变量。

#define TOD_UPDATE(tod, step_nsec)                      \
        do {                                            \
            (tod)->tv_nsec += step_nsec;                \
            if ((tod)->tv_nsec >= __TIMEVAL_NSEC_MAX) { \
                (tod)->tv_nsec -= __TIMEVAL_NSEC_MAX;   \
                (tod)->tv_sec++;                        \
            }                                           \
        } while (0)
static LW_INLINE VOID __kernelTODUpdate (VOID)
{
    LONG    lNsec;
    
    TOD_UPDATE(&_K_tvTODMono, LW_NSEC_PER_TICK);                        /*  CLOCK_MONOTONIC             */
    
    if (_K_iTODDelta > 0) {                                             /*  需要加快系统时钟一个 TICK   */
        _K_iTODDelta--;
        lNsec = LW_NSEC_PER_TICK << 1;                                  /*  加快一个 tick               */
    
    } else if (_K_iTODDelta < 0) {
        _K_iTODDelta++;
        return;                                                         /*  系统 tod 时间停止一个 tick  */
    
    } else if (_K_iTODDeltaNs) {
        lNsec = LW_NSEC_PER_TICK + _K_iTODDeltaNs;                      /*  进行微调                    */
        _K_iTODDeltaNs = 0;
    
    } else {
        lNsec = LW_NSEC_PER_TICK;
    }
    
    TOD_UPDATE(&_K_tvTODCurrent, lNsec);                                /*  CLOCK_REALTIME              */
}

获取时间

POSIX标准的时间获取接口,最终都是读取的这两个时间变量。

time_t  lib_time (time_t *time)
{
    INTREG        iregInterLevel;
    time_t        timetmp;
    
    LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
    timetmp = _K_tvTODCurrent.tv_sec;
    LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);

    if (time) {
        *time = timetmp;
    }
    
    return  (timetmp);
}
time_t  lib_timelocal (time_t *time)
{
    INTREG        iregInterLevel;
    time_t        timetmp;
    
    LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
    timetmp = UTC2LOCAL(_K_tvTODCurrent.tv_sec);
    LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);

    if (time) {
        *time = timetmp;
    }
    
    return  (timetmp);
}

如果是要获取高精度时间,则还会调用底层的bspTickHighResolution接口函数,以获取心跳节拍以内的精度。

#if LW_CFG_TIME_HIGH_RESOLUTION_EN > 0
#define LW_TIME_HIGH_RESOLUTION(tv)     bspTickHighResolution(tv)
#else
#define LW_TIME_HIGH_RESOLUTION(tv)
#endif 
INT  lib_clock_gettime (clockid_t  clockid, struct timespec  *tv)
{
    INTREG          iregInterLevel;
    PLW_CLASS_TCB   ptcbCur;

    if (tv == LW_NULL) {
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }
    
    switch (clockid) {
    
    case CLOCK_REALTIME:
        LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
        *tv = _K_tvTODCurrent;
        LW_TIME_HIGH_RESOLUTION(tv);
        LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
        break;
    
    case CLOCK_MONOTONIC:
        LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
        *tv = _K_tvTODMono;
        LW_TIME_HIGH_RESOLUTION(tv);
        LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
        break;
        
    case CLOCK_PROCESS_CPUTIME_ID:
        {
            LW_LD_VPROC *pvproc = __LW_VP_GET_CUR_PROC();
            if (pvproc == LW_NULL) {
                _ErrorHandle(ESRCH);
                return  (PX_ERROR);
            }
            LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
            __tickToTimespec(pvproc->VP_clockUser + pvproc->VP_clockSystem, tv);
            LW_TIME_HIGH_RESOLUTION(tv);
            LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
        }                                                            /*  LW_CFG_MODULELOADER_EN > 0  */
        break;
        
    case CLOCK_THREAD_CPUTIME_ID:
        LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
        LW_TCB_GET_CUR(ptcbCur);
        __tickToTimespec(ptcbCur->TCB_ulCPUTicks, tv);
        LW_TIME_HIGH_RESOLUTION(tv);
        LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
        break;
        
    default:
        _ErrorHandle(EINVAL);
        return  (PX_ERROR);
    }

    return  (ERROR_NONE);
}

时间微调

/*********************************************************************************************************
** 函数名称: API_TimeTodAdj
** 功能描述: 微调 TOD 时间.
** 输 入  : piDelta           TOD 调整时间 正数表示时间加速多少个对应的 ticks
**                                          负数表示时间减速多少个对应的 ticks
**                                          例如想让 TOD 时间加速一秒, 而且时钟 hz 为 100, 则此参数为  100
**                                              想让 TOD 时间减速一秒, 而且时钟 hz 为 100, 则此参数为 -100
**           piOldDelta        上次没有调整完的剩余调整值
** 输 出  : 
** 注  意  : 为了避免时光倒流, TOD 调回以前的时间系统将自动减速 TOD 的运算.
*********************************************************************************************************/
LW_API
VOID  API_TimeTodAdj (INT32  *piDelta, INT32 *piOldDelta)
{
    INTREG      iregInterLevel;

    LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
    if (piOldDelta) {
        *piOldDelta = _K_iTODDelta;
    }
    if (piDelta) {
        _K_iTODDelta = *piDelta;
    }
    LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
}
/*********************************************************************************************************
** 函数名称: API_TimeTodAdjEx
** 功能描述: 微调 TOD 时间.
** 输 入  : piDelta           TOD 调整时间 正数表示时间加速多少个对应的 ticks
**                                          负数表示时间减速多少个对应的 ticks
**                                          例如想让 TOD 时间加速一秒, 而且时钟 hz 为 100, 则此参数为  100
**                                              想让 TOD 时间减速一秒, 而且时钟 hz 为 100, 则此参数为 -100
**           piDeltaNs         一个 tick 以内 ns 数的调整
**           piOldDelta        上次没有调整完的剩余调整值
**           piOldDeltaNs      一个 tick 以内 ns 数的调整
** 输 出  : 
** 注  意  : 为了避免时光倒流, TOD 调回以前的时间系统将自动减速 TOD 的运算.
*********************************************************************************************************/
LW_API
INT  API_TimeTodAdjEx (INT32  *piDelta, INT32  *piDeltaNs, INT32 *piOldDelta, INT32 *piOldDeltaNs)
{
    INTREG      iregInterLevel;
    
    if (piDeltaNs && (lib_abs(*piDeltaNs) > LW_NSEC_PER_TICK)) {
        _ErrorHandle(E2BIG);
        return  (PX_ERROR);
    }

    LW_SPIN_KERN_LOCK_QUICK(&iregInterLevel);
    if (piOldDelta) {
        *piOldDelta = _K_iTODDelta;
    }
    if (piOldDeltaNs) {
        *piOldDeltaNs = _K_iTODDeltaNs;
    }
    if (piDelta) {
        _K_iTODDelta = *piDelta;
    }
    if (piDeltaNs) {
        _K_iTODDeltaNs = *piDeltaNs;
    }
    LW_SPIN_KERN_UNLOCK_QUICK(iregInterLevel);
    
    return  (ERROR_NONE);
}
<think>好的,我需要帮助用户下载AI-TOD数据集。首先,我应该回顾用户提供的引用内容,看看是否有相关的信息。引用[1]提到AI-TOD和AI-TOD-V2的标签文件可以在GitHub上下载,而引用[4]也提到了AI-TOD数据集的一些细节。用户需要的是官方链接,所以可能需要找到GitHub的仓库地址或者官方网站。 根据引用[1],GitHub上应该有标签文件的下载链接,但用户可能还需要图片数据。引用[4]提到图片在28,036张航拍图像中,所以需要确认图片是否和标签分开下载,或者是否有统一的来源。此外,引用[2]提供了百度AI Studio的数据集链接,但不确定是否包含AI-TOD。可能需要检查该链接是否有相关内容。 用户的问题是关于如何下载AI-TOD数据集,特别是官方链接。根据已知信息,官方数据集的下载可能通过GitHub发布标签,而图片可能需要其他途径。可能需要指导用户到GitHub获取标签,并可能通过其他平台获取图片。但需要确认是否有官方说明。如果没有找到明确的官方链接,可能需要建议用户查阅论文或相关项目页面获取最新信息。 另外,需要注意引用中的AI-TOD和AI-TOD-V2的区别,用户可能只需要原始版本。同时,要确保步骤清晰,分点说明下载方法,可能包括GitHub步骤和百度AI Studio的步骤,如果可用的话。需要验证提供的引用链接是否准确,比如引用[2]的链接是否正确指向相关数据集。可能还需要提醒用户安装aitodpycocotools工具来处理数据,如引用[1]提到的。 最后,生成相关问题时要围绕数据集下载、处理、应用等方面,确保问题相关且有帮助。例如,关于数据集结构、处理工具的使用,或者与其他数据集的比较等。</think>根据官方信息,AI-TOD数据集的下载步骤如下: ### 一、AI-TOD数据集下载方法 1. **标签文件获取**: - 访问GitHub仓库:https://github.com/jwwangchn/AI-TOD - 在"Annotations"文件夹中下载对应版本的标签文件(支持AI-TOD和AI-TOD-V2两种格式)[^1][^4] 2. **图像数据获取**: - 官方未直接提供图像下载链接,但可通过论文作者提供的途径获取 - 替代方案:百度AI Studio平台搜索"AI-TOD"数据集,部分镜像资源包含完整数据[^2] 3. **安装数据处理工具**: ```bash pip install aitodpycocotools # 用于解析AI-TOD专用标注格式 ``` ### 二、数据集特点 $$ \text{平均目标尺寸} = 12.8\ \text{像素} $$ 该数据集包含28,036张航拍图像和700,621个实例标注,主要面向小目标检测研究。与COCO等通用数据集相比,AI-TOD中96.9%的目标小于32×32像素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ScilogyHunter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值