簡體   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