我正在开发微控制器TC23X (Infineon),我的"time()“函数总是返回最大值0xFFFFFFF,我使用编译器”为TriCoreV6.3r1任务VX工具集“。
有谁能帮我解决上面的问题吗?所以time()返回自时代以来的时间(00:00:00 UTC,1970年1月1日),以秒为单位
我尝试过这些方法"time(NULL)、time(0)和time(&Var)“。
发布于 2022-02-25 22:15:27
由于时间/日期的可用性是特定于硬件平台的,所以time()作为一个默认实现提供,它只是返回“不可用”(-1)。
如果您的平台作为时间/日期源(如RTC、GNSS或NTP客户端),则可以通过定义替换函数(例如:
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 1 1PPS或NTP将第二次更新与UTC秒同步。这取决于您可能需要的精度级别。
发布于 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接口:
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在任何时候都是开放的。
https://stackoverflow.com/questions/71268442
复制相似问题