【LuatOS】修改LuatOS源码为PC模拟器添加高精度时间戳库timeplus

news/2024/11/6 5:08:31 标签: luatos, lua, 时间戳

0x00 缘起

LuatOS以及Lua能够提供微秒或者毫秒的时间戳获取工具,但并没有提供获取纳秒的工具。通过编辑LuatOS源码以及相关BSP源码,添加能够获取纳秒的timeplus库并重新编译,以解决在64位Windows操作系统中LuatOS模拟器获取纳秒的问题,其运行效果如下所示:

  • getunixtime:获取时间戳字符串
  • getmillisecond:获取毫秒时间戳字符串
  • getmicrosecond:获取微秒时间戳字符串
  • getnanosecond:获取纳秒时间戳字符串

0x01 方法

参照LuatOS官方文档,对timeplus进行开发,其步骤如下:

  1. Git拉取LuatOS和PC模拟器源代码;
  2. 新增一个通用库的实例;
  3. 注册库函数;
  4. 验证库函数;

1 Git拉取LuatOS和PC模拟器源代码

使用Git命令拉取“LuatOS”项目和“LuatOS跑在PC上”两个项目到本地同级目录下,拉取命令如下:

git clone https://gitee.com/openLuat/LuatOS.git
git clone https://gitee.com/openLuat/luatos>luatos-soc-pc.git

2 新增一个通用库的实例

进入LuatOS源码文件夹lua/src/目录下,添加名为:luat_lib_timeplus.c的文件,文件内容如下:

#include <lauxlib.h>
#include <lua.h>
#include <stdio.h>
#include <windows.h>

#include "luat_base.h"

// 获取当前时间的 Unix 时间戳(秒)
static int l_timeplus_getunixtime(lua_State *L) {
  FILETIME ft;
  ULARGE_INTEGER ull;
  GetSystemTimeAsFileTime(&ft);

  ull.LowPart = ft.dwLowDateTime;
  ull.HighPart = ft.dwHighDateTime;

  // 将 FILETIME 转换为 Unix 时间戳(秒)
  time_t unixTime = (ull.QuadPart / 10000000ULL) - 11644473600ULL;

  lua_pushinteger(L, unixTime);
  return 1;
}

// 获取当前时间的 Unix 时间戳(毫秒)
static int l_timeplus_getmillisecond(lua_State *L) {
  FILETIME ft;
  ULARGE_INTEGER ull;
  GetSystemTimeAsFileTime(&ft);

  ull.LowPart = ft.dwLowDateTime;
  ull.HighPart = ft.dwHighDateTime;

  // 将 FILETIME 转换为 Unix 时间戳(毫秒)
  uint64_t milliseconds = (ull.QuadPart / 10000ULL) - 11644473600000ULL;

  lua_pushinteger(L, milliseconds);
  return 1;
}

// 获取当前时间的 Unix 时间戳(微秒)
static int l_timeplus_getmicrosecond(lua_State *L) {
  FILETIME ft;
  ULARGE_INTEGER ull;
  GetSystemTimeAsFileTime(&ft);

  ull.LowPart = ft.dwLowDateTime;
  ull.HighPart = ft.dwHighDateTime;

  // 将 FILETIME 转换为 Unix 时间戳(微秒)
  uint64_t microseconds = (ull.QuadPart / 10ULL) - 11644473600000000ULL;

  lua_pushinteger(L, microseconds);
  return 1;
}

// 获取当前时间的 Unix 时间戳(纳秒)
static int l_timeplus_getnanosecond(lua_State *L) {
  FILETIME ft;
  ULARGE_INTEGER ull;
  GetSystemTimeAsFileTime(&ft);

  ull.LowPart = ft.dwLowDateTime;
  ull.HighPart = ft.dwHighDateTime;

  // 将 FILETIME 转换为 Unix 时间戳(纳秒)
  // 乘以100将100纳秒单位转换为纳秒
  uint64_t nanoseconds_since_epoch =
      (ull.QuadPart - 116444736000000000ULL) * 100ULL;

  lua_pushinteger(L, nanoseconds_since_epoch);
  return 1;
}

// 库函数注册表
#include "rotable2.h"
static const rotable_Reg_t reg_timeplus[] = {
    {"getunixtime", ROREG_FUNC(l_timeplus_getunixtime)},
    {"getmillisecond", ROREG_FUNC(l_timeplus_getmillisecond)},
    {"getmicrosecond", ROREG_FUNC(l_timeplus_getmicrosecond)},
    {"getnanosecond", ROREG_FUNC(l_timeplus_getnanosecond)},
    {NULL, ROREG_INT(0)}};

// 库的声明
LUAMOD_API int luaopen_timeplus(lua_State *L) {
  luat_newlib2(L, reg_timeplus);
  return 1;
}

3 注册库函数

修改LuatOS代码库的 luat/include/luat_libs.h, 新增一行:

// TimePlus 能够取微秒
LUAMOD_API int luaopen_timeplus(lua_State *L);

修改luatos>luatos-soc-pc代码库的port\luat_base_mini.c, 在static const luaL_Reg loadedlibs[]{NULL, NULL}};之上添加一行代码:

{"timeplus", luaopen_timeplus},

4 验证库函数

luatos>luatos-soc-pc代码库中,运行文件:build_windows_64bit_msvc.bat进行编译,输出文件在build文件夹下,编译之前请确保编译工具已经配置可用。运行所编译的文件luatos>luatos-lua.exe,在命令行中执行以下代码,并验证输出:

lua">timeplus.getunixtime()
timeplus.getmillisecond()
timeplus.getmicrosecond()
timeplus.getnanosecond()

0x02 总结

针对LuatOS Windows模拟器不能提供纳秒时间戳的工具问题,通过添加自定义库timeplus并重新编译以使得模拟器具有输出纳秒时间戳的能力。值得注意的是,当前纳秒的获取方法仅适用与Windows,对于Linux以及其他操作系统,需要修改luat_lib_timeplus.c的实现过程,以提供该功能。

0x03 资源

  • LuatOS 添加自定义库和函数 官方文档

0x04 后记

  • 己欲立而立人,己欲达而达人。

http://www.niftyadmin.cn/n/5740213.html

相关文章

51单片机教程(八)- 数码管的静态显示

1、项目分析 使用数码管显示指定的字符、数字和符号。 2、技术准备 1、显示器及其接口 单片机系统中常用的显示器有&#xff1a; 发光二极管LED&#xff08;Light Emitting Diode&#xff09;显示器、液晶LCD&#xff08;Liquid Crystal Display&#xff09;显示器、CRT显…

网络技术----wireshark抓包出现1500以上的大包原因分析

网络技术----wireshark抓包出现1500以上的大包原因分析 背景描述原因分析TSO&#xff08;TCP segment offload&#xff0c;TSO&#xff09;linux中关闭/开启TSO功能&#xff1a;其他类似TSO的机制 wireshark抓包来源 背景描述 我们在使用抓包工具的过程中&#xff0c;经常发现…

基于MATLAB的农业病虫害识别研究

1 背景介绍 病虫害一直是限制农业生产过程中农业和副产品的高质量和高产量的最重要因素。然而&#xff0c;在识别中国的病虫害时&#xff0c;无论是用肉眼识别的传统方法还是后来专家的系统判断&#xff0c;这些病虫害的特征一般都是主观因素。主观意图非常大&#xff0c;效率…

pdf添加目录标签python(手动配置)

先安装对应的库: pip install pypdf 代码分为两个部分,一部分是config.py,代码如下: offset=10 catgorys=[("第一章",12),("第二章",45), ] 需要自己手动更改offset,和目录列表 下面是主要代码: import pypdf # import sys from config import…

Intellij IDE报错:[Information:java:javacTask:源发行版8需要目标发行版1.8]

Intellij IDE报错:[Information:java:javacTask:源发行版8需要目标发行版1.8] 处理方法 File->Settings->Build,execution,Deployment->Compiler->Java Compiler 进入该目录下&#xff0c;修改Per-module bytecode version&#xff0c;将该项目修改为8 合理的创…

java mapper 的 xml讲解

<?xml version"1.0" encoding"UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace"com.bnc.s12.mapper.GoodaCateDT…

W55RP20芯片介绍

目录 概述 引脚映射 特征 资料 文件 相关 EVB-Pico 概述 我们最新的 ioNIC 将串行接口与以太网连接集成在一起&#xff0c;为您提供量身定制的网络解决方案。通过支持各种网络协议、增强的 SSL 安全功能和云 SDK&#xff0c;体验行业特定应用程序的优化性能&#xff01; …

Android Studio 中关于com.github.barteksc:android-pdf-viewer 无法正确加载的问题

Android Studio 的app 模块下&#xff0c;添加依赖&#xff1a; implementation com.github.barteksc:android-pdf-viewer:3.2.0-beta.1 运行程序报错&#xff1a; Caused by: org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration$ArtifactResolveEx…