繁体   English   中英

time() function 总是返回最大值“TIME_MAX”(或)0xFFFFFFFF

[英]time() function is always returning maximum value "TIME_MAX" (or) 0xFFFFFFFF

我正在使用微控制器 TC23X(Infineon),我的“ time() ”function 总是返回最大值 0xFFFFFFFF 我正在使用编译器“Tasking VX Toolset for Tricore V6.3r1”

有人可以帮我解决上述问题吗? 因此 time() 返回自纪元(00:00:00 UTC,1970 年 1 月 1 日)以来的时间,以秒为单位

我试过这些方法“time(NULL), time(0) and time(&Var)”

因为时间/日期的可用性特定于硬件平台,所以time()作为默认实现提供,它只返回“不可用”(-1)。

如果您的平台作为时间/日期源,例如 RTC、GNSS 或 NTP 客户端,那么您可以覆盖默认实现以利用该源,只需定义一个替换 function - 例如:

time_t time( std::time_t *timeptr ) 
{
    time_t epoch_time  = 0 ;
    struct tm time_struct = {0} ;

    // Your code to get RTC data in a tm struct here
    ...
    struct tm timedate = {.tm_mday = ..., 
                          .tm_mon = ...,   // January == 0
                          .tm_year = ...,  // Years since 1900
                          .tm_hour = ...,
                          .tm_min = ...,
                          .tm_sec = ...
                         } ;

    // Convert tm struct to UNIX epoch time     
    epoch_time = std::mktime( &time_struct ) ;

    if( tp != 0 )
    {
        *timeptr = epoch_time ; 
    }

    return epoch_time ; 
}

一种更有效的方法是在首次使用时使用 RTC 源初始化一个 1Hz 周期计数器,然后返回计数器的值:

volatile static time_t epoch_time = TIME_MAX ;
void timer_ISR_1Hz( void )
{
    epoch_time++ ;
}

time_t time( std::time_t *timeptr ) 
{
    if( epoch_time == TIME_MAX )
    {
        struct tm time_struct = {0} ;
        
        // Your code to get RTC data in a tm struct here
        ...
        struct tm timedate = {.tm_mday = ..., 
                              .tm_mon = ...,   // January == 0
                              .tm_year = ...,  // Years since 1900
                              .tm_hour = ...,
                              .tm_min = ...,
                              .tm_sec = ...
                             } ;

        // Convert tm struct to UNIX epoch time     
        epoch_time = std::mktime( &time_struct ) ;

        // Start 1Hz timer here    
        ...
    }

    time_t t = epoch_time ;

    // Convert tm struct to UNIX epoch time     
    if( tp != 0 )
    {
        *timeptr = t ; 
    }

    return t ; 
}

如果您在开机后从用户提供的时间/日期输入初始化为纪元时间,则上述解决方案适用于没有 RTC 源的情况。

在读取 RTC 硬件(或任何其他时间源)时,您需要确保时间一致; 例如,读取 59 秒是可能的,就像它滚动到 00 秒一样,然后读取分钟,所以结束时说 20 分 59 秒,当它应该是 19 分 59 秒,或 20 分 00 秒. 这同样适用于分钟、小时、日、月和年的滚动。

例如,您可能还希望通过 GNSS 1PPS 或 NTP 将第二次更新与 UTC 秒同步。 这取决于您可能需要的精度级别。

即使您设置了“autosar”标签,TC23x 规范似乎也只允许在其上运行 AUTOSAR Classic。 但是,在那个和汽车的情况下,我想知道为什么实际上允许你使用 time() function。

首先,独立环境必须支持的C标准部分肯定不包括time.h。

其次,只有 AUTOSAR Adaptive 只支持 POSIX 的一个非常小的子集,即POSIX profile PSE51 defined by IEEE1003.13

但如上所述,AUTOSAR Adaptive 并不是真正可以在此 TC23x 上运行的东西。

所以,总的来说我会建议你,忘掉所有要使用的 C 标准库函数。 查看 AUTOSAR 组件、它们的功能和接口。

也许您实际上应该寻找 AUTOSAR 功能,例如 StbM,以便首先支持同步的全球时基,然后通过车辆通过几个可能的 TimeGateway 将其分发到您的 ECU。

例如,StbM 必须配置为来自 SystemDescription(GlobalTimeDomains 和 TimeMaster/TimeSlave/TimeGateway)的 AUTOSAR 堆栈的 rest,以及对纯本地计时器(例如 MCAL GPT 计时器)的引用作为实际本地时基,甚至如果尚未同步。

然后您可以使用例如这个 StbM 接口:

Std_ReturnType StbM_GetCurrentTime(
                      StbM_SynchronizedTimeBaseType timeBaseId,
                      StbM_TimeStampType* timeStamp,
                      StbM_UserDataType* userData)

/** Variables of this type are used for expressing time stamps including relative time and 
 * absolute calendar time.
 * The absolute time starts from 1970-01-01.   <----
 * 0 to 281474976710655s == 3257812230d [0xFFFF FFFF FFFF]
 * 0 to 999999999ns [0x3B9A C9FF]
 * invalid value in nanoseconds: [0x3B9A CA00] to [0x3FFF FFFF]
 * Bit 30 and 31 reserved, default: 0
 */
typedef struct {
    StbM_TimeBaseStatusType timeBaseStatus;
    uint32                  nanoSeconds;
    uint32                  seconds; // lower 32bit of 48bit seconds
    uint16                  secondsHi; // higher 16bit part of 48bit seconds 
} StbM_TimeStampType;

// There is also an "extended" version of the function and structure available
// using uint64 type instead the split uint32/uint16 for the seconds part

typedef uint8 StbM_TimeBaseStatusType;
// Bit 0 (LSB): 0x00: No Timeout on receiving Synchronisation Messages 
//              0x01: Timeout on receiving Synchronisation Messages
#define TIMEOUT 0x01
// Bit 2 0x00: Local Time Base is synchronous to Global Time Master
//       0x04: Local Time Base updates are based on a Time Gateway below the Global Time Master
#define SYNC_TO_GATEWAY 0x04
// Bit 3 0x00: Local Time Base is based on Local Time Base reference clock only (never synchronized with Global Time Base)
//       0x08: Local Time Base was at least synchronized with Global Time Base one time 
#define GLOBAL_TIME_BASE 0x08
// Bit 4 0x00: No leap into the future within the received time for Time Base
//       0x10: Leap into the future within the received time for Time Base exceeds a configured threshold 
#define TIMELEAP_FUTURE 0x10
// Bit 5 0x00: No leap into the past within the received time for Time Base 
//       0x20: Leap into the past within the received time for Time Base exceeds a configured threshold
#define TIMELEAP_PAST 0x20

像这样:

const StbM_SynchronizedTimeBaseType timeBaseId = YOUR_TIME_DOMAIN_ID; // as configured in the AUTOSAR config tool

StbM_TimeStampType  timeStamp;
StbM_UserDataType   userData; // up to 3 bytes transmitted from TimeMaster (systemdependent)
Std_ReturnType ret;

SchM_Enter_ExclusiveArea_0();

ret = StbM_GetCurrentTimer(timeBaseId, &timeStamp, &userData);

SchM_Exit_ExclusiveArea_0();

if (ret == E_NOT_OK) {
    // Failure Handling and maybe report Error
    // Is StbM and AUTOSAR Stack ok and running?
    // Was this the correct timeBaseId?
} else {
    if (timeStamp.timeBaseStatus & TIMEOUT) {
       // TimeSync messages not received --> running further on local time (time since ECU was turned on)
    }
    if (timeStamp.timeBaseStatus & SYNC_TO_GATEWAY) {
        // Synced to gateway, but not the global time master --> synchronized to the gateways time
       // (possible drift from that gateway itself, or time since gateway was turned on)
    } else {
       // if bit is not set, we are synchronized to the global time master 
    }
    // ..
    // work with timeStamp.seconds and timeStamp.nanoSeconds 
    

如果没有 StbM,或没有同步时基,通常 ECU 只会在 ECU 通电后基于本地时间运行,无论何时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM