vxWorks RTP中获取微秒级时间戳异常问题求助
问题描述
我们编写了一段获取微秒级当前时间戳的代码,在搭配Clang16的Ubuntu系统C++环境下运行正常,但在采用CMake构建系统的vxWorks RTP中测试时得到错误值,需要实现与Ubuntu一致的预期输出。
输出对比
- Ubuntu终端输出:正常的微秒级时间戳与格式化时间
- VxWorks终端输出:错误的时间数值(与实际时间严重不符)
原代码
#include <iostream> #include <chrono> #include <string> namespace bhavik{ typedef char CHAR; std::string epochToTime(void){ try{ const std::uint64_t epochTimeInMicroseconds = (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count()); std::cout << epochTimeInMicroseconds << std::endl; std::string timeT; const std::uint64_t microsecond = epochTimeInMicroseconds % 1000000U; const time_t epochTimeInSec = (epochTimeInMicroseconds - microsecond) / 1000000U; CHAR charTimeT[21]; (void)strftime(charTimeT, 20, "%d-%m-%Y %H:%M:%S", localtime(&epochTimeInSec)); timeT = charTimeT; timeT = timeT + ":" + std::to_string(microsecond); return timeT; } catch(const std::exception& ex){ std::cout << ex.what() << std::endl; return ""; } } } int main() { std::string str=bhavik::epochToTime(); std::cout << str<< std::endl; return 0; }
问题分析与解决方案
核心问题
vxWorks的std::chrono::system_clock实现与Linux存在差异:
- 纪元(epoch)不同:vxWorks默认纪元为1980-01-01,而非Unix标准的1970-01-01,直接使用会导致时间戳偏移。
- RTP环境限制:部分C++标准库的时间接口在vxWorks RTP中可能未完全实现或需要特殊配置。
- 数据类型兼容:vxWorks的
time_t可能为32位,处理大时间戳时易溢出。
方案1:使用vxWorks原生高精度时间API替代std::chrono
直接调用vxWorks原生的clock_gettime接口获取符合Unix纪元的时间,兼容性更可靠:
#include <iostream> #include <string> #include <time.h> #include <stdexcept> namespace bhavik{ typedef char CHAR; std::string epochToTime(void){ try{ struct timespec ts; // 获取Unix纪元的实时时钟(秒+纳秒) if (clock_gettime(CLOCK_REALTIME, &ts) != 0) { throw std::runtime_error("Failed to retrieve realtime clock"); } // 转换为微秒级时间戳 std::uint64_t epochTimeInMicroseconds = static_cast<std::uint64_t>(ts.tv_sec) * 1000000 + ts.tv_nsec / 1000; std::cout << epochTimeInMicroseconds << std::endl; std::string timeT; const std::uint64_t microsecond = epochTimeInMicroseconds % 1000000U; const time_t epochTimeInSec = static_cast<time_t>(ts.tv_sec); CHAR charTimeT[21]; // 确保时区配置正确,提前调用tzset()可修正localtime输出 tzset(); (void)strftime(charTimeT, 20, "%d-%m-%Y %H:%M:%S", localtime(&epochTimeInSec)); timeT = charTimeT; timeT = timeT + ":" + std::to_string(microsecond); return timeT; } catch(const std::exception& ex){ std::cout << ex.what() << std::endl; return ""; } } } int main() { std::string str=bhavik::epochToTime(); std::cout << str<< std::endl; return 0; }
方案2:修正std::chrono的纪元偏移
若必须保留C++标准库接口,需手动添加vxWorks与Unix纪元的偏移量(1970到1980的秒数为315532800):
// 在原代码的时间戳计算处添加偏移 const std::uint64_t VXWORKS_EPOCH_OFFSET = 315532800ULL * 1000000ULL; const std::uint64_t epochTimeInMicroseconds = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count() + VXWORKS_EPOCH_OFFSET;
额外注意事项
- RTP权限:确保vxWorks RTP程序拥有访问系统时钟的权限,可在CMake配置中添加对应编译选项。
- 时区配置:通过
tzset()或系统环境变量设置正确时区,避免localtime输出错误时区时间。 - 数据类型:涉及时间戳转换时,强制使用64位类型(如
std::uint64_t),避免32位time_t溢出问题。
内容的提问来源于stack exchange,提问作者Akash Sagar
相关产品推荐
相关产品推荐

