首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数总是返回最大值"TIME_MAX“(或)0xFFFFFFF

函数总是返回最大值"TIME_MAX“(或)0xFFFFFFF
EN

Stack Overflow用户
提问于 2022-02-25 15:55:22
回答 2查看 193关注 0票数 0

我正在开发微控制器TC23X (Infineon),我的"time()“函数总是返回最大值0xFFFFFFF,我使用编译器”为TriCoreV6.3r1任务VX工具集“。

有谁能帮我解决上面的问题吗?所以time()返回自时代以来的时间(00:00:00 UTC,1970年1月1日),以秒为单位

我尝试过这些方法"time(NULL)、time(0)和time(&Var)“。

EN

回答 2

Stack Overflow用户

发布于 2022-02-25 22:15:27

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

如果您的平台作为时间/日期源(如RTC、GNSS或NTP客户端),则可以通过定义替换函数(例如:

代码语言:javascript
复制
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周期计数器,然后返回计数器的值:

代码语言:javascript
复制
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 1 1PPS或NTP将第二次更新与UTC秒同步。这取决于您可能需要的精度级别。

票数 2
EN

Stack Overflow用户

发布于 2022-02-26 14:39:14

尽管您有" AUTOSAR“标记集,但TC23x规范似乎只允许在它们上运行AUTOSAR。但是,在这个和汽车的例子中,我想知道为什么允许您使用time()函数。

首先,一个独立的环境必须支持的C标准的一部分,当然不包括时间。

其次,只有AUTOSAR自适应只支持非常小的POSIX子集,即POSIX profile PSE51 defined by IEEE1003.13

但是如上所述,Adaptive并不是真正适合在这个TC23x上运行的东西。

因此,总的来说,我建议您,忘记所有C标准库函数的使用。查看AUTOSAR组件、它们的特性和接口。

也许您应该实际寻找AUTOSAR特性,比如StbM,以便首先支持同步的全局时基,然后通过车辆将其分发给您的ECU。

例如,必须配置StbM,就像SystemDescription中的AUTOSAR堆栈的其余部分一样(GlobalTimeDomains和TimeMaster/TimeSlave/TimeGateway),以及对纯本地定时器(例如MCAL定时器)的引用,作为实际的本地时间库,即使还没有同步。

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

代码语言:javascript
复制
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

就像这样:

代码语言:javascript
复制
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在任何时候都是开放的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71268442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档