简体   繁体   English

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

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

I am working on microcontroller TC23X (Infineon), and my " time() " function is always returning the maximum value 0xFFFFFFFF I am using the compiler "Tasking VX Toolset for Tricore V6.3r1"我正在使用微控制器 TC23X(Infineon),我的“ time() ”function 总是返回最大值 0xFFFFFFFF 我正在使用编译器“Tasking VX Toolset for Tricore V6.3r1”

Can someone please help me how to resolve above issue.有人可以帮我解决上述问题吗? so that time() returns the time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds因此 time() 返回自纪元(00:00:00 UTC,1970 年 1 月 1 日)以来的时间,以秒为单位

I have tried these methods "time(NULL), time(0) and time(&Var)"我试过这些方法“time(NULL), time(0) and time(&Var)”

Because the availability of time/date is specific to the the hardware platform, time() is provided as a default implementation that simply returns "not available" (-1).因为时间/日期的可用性特定于硬件平台,所以time()作为默认实现提供,它只返回“不可用”(-1)。

If your platform as a time/date source such as an RTC, GNSS or NTP client, then you can override the default implementation to utilise that source, simply by defining a replacement function - for example:如果您的平台作为时间/日期源,例如 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 ; 
}

A more efficient method is to initialise a 1Hz periodic counter with the RTC source on first use, then thereafter return the value of the counter:一种更有效的方法是在首次使用时使用 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 ; 
}

The above solution works where you have no RTC source if you initialise to the epoch time from user supplied time/date input after power-on.如果您在开机后从用户提供的时间/日期输入初始化为纪元时间,则上述解决方案适用于没有 RTC 源的情况。

When reading RTC hardware (or any other time source) you need to make sure the time is consistent;在读取 RTC 硬件(或任何其他时间源)时,您需要确保时间一致; it is possible for example to read the 59 seconds, just as it rolls over to 00 seconds, and then read the minutes and so end up with say 20 minutes 59 seconds, when it should be 19 minutes 59 seconds, or 20 minutes 00 seconds.例如,读取 59 秒是可能的,就像它滚动到 00 秒一样,然后读取分钟,所以结束时说 20 分 59 秒,当它应该是 19 分 59 秒,或 20 分 00 秒. The same applies to the roll-over of minute, hour, day, month and year.这同样适用于分钟、小时、日、月和年的滚动。

You might further wish to synchronise the second update with UTC seconds via a GNSS 1PPS or NTP for example.例如,您可能还希望通过 GNSS 1PPS 或 NTP 将第二次更新与 UTC 秒同步。 It depends on what level of precision you might require.这取决于您可能需要的精度级别。

Even though you have that "autosar" tag set, the TC23x specs seem to only allow AUTOSAR Classic to be run on them.即使您设置了“autosar”标签,TC23x 规范似乎也只允许在其上运行 AUTOSAR Classic。 But, in that and the case of automotive, I wonder, why it is actually for you to be allowed to use time() function at all.但是,在那个和汽车的情况下,我想知道为什么实际上允许你使用 time() function。

First of all, the part of the C-standard, that a freestanding environment has to support, does certainly not include time.h.首先,独立环境必须支持的C标准部分肯定不包括time.h。

Second, only AUTOSAR Adaptive only supports a very small subset of POSIX, the POSIX profile PSE51 defined by IEEE1003.13 .其次,只有 AUTOSAR Adaptive 只支持 POSIX 的一个非常小的子集,即POSIX profile PSE51 defined by IEEE1003.13

But as stated above, AUTOSAR Adaptive is not really something to run on this TC23x.但如上所述,AUTOSAR Adaptive 并不是真正可以在此 TC23x 上运行的东西。

So, in general i would suggest to you, forget about all C-Standard library functions to use.所以,总的来说我会建议你,忘掉所有要使用的 C 标准库函数。 Look into the AUTOSAR components, their features and interfaces.查看 AUTOSAR 组件、它们的功能和接口。

Maybe you should actually look for AUTOSAR features, like the StbM, in order to first of all have support for a synchronized global time base, which then distributed through the vehicle over several possible TimeGateways to your ECU.也许您实际上应该寻找 AUTOSAR 功能,例如 StbM,以便首先支持同步的全球时基,然后通过车辆通过几个可能的 TimeGateway 将其分发到您的 ECU。

The StbM for example has to be configured like the rest of your AUTOSAR stack from your SystemDescription (GlobalTimeDomains and TimeMaster/TimeSlave/TimeGateway), and a reference to a pure local timer (eg a MCAL GPT timer) as the actual local timebase, even if not yet synchronized.例如,StbM 必须配置为来自 SystemDescription(GlobalTimeDomains 和 TimeMaster/TimeSlave/TimeGateway)的 AUTOSAR 堆栈的 rest,以及对纯本地计时器(例如 MCAL GPT 计时器)的引用作为实际本地时基,甚至如果尚未同步。

Then you can use for example this StbM interface:然后您可以使用例如这个 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

like this:像这样:

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 
    

If there is no StbM, or no synchronized timebase, usually the ECUs just run on their local time based since ECU power on, whenever that was.如果没有 StbM,或没有同步时基,通常 ECU 只会在 ECU 通电后基于本地时间运行,无论何时。

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

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