[英]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.