extmod/utime_mphal: Add generic utime.time_ns() function.

It requires mp_hal_time_ns() to be provided by a port.  This function
allows very accurate absolute timestamps.

Enabled on unix, windows, stm32, esp8266 and esp32.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2020-09-24 12:37:02 +10:00
parent 905a18aafe
commit d4b61b0017
9 changed files with 45 additions and 2 deletions

View File

@ -216,8 +216,9 @@ Functions
function returns number of seconds since a port-specific reference point in time (for function returns number of seconds since a port-specific reference point in time (for
embedded boards without a battery-backed RTC, usually since power up or reset). If you embedded boards without a battery-backed RTC, usually since power up or reset). If you
want to develop portable MicroPython application, you should not rely on this function want to develop portable MicroPython application, you should not rely on this function
to provide higher than second precision. If you need higher precision, use to provide higher than second precision. If you need higher precision, absolute
`ticks_ms()` and `ticks_us()` functions, if you need calendar time, timestamps, use `time_ns()`. If relative times are acceptable then use the
`ticks_ms()` and `ticks_us()` functions. If you need calendar time, `gmtime()` or
`localtime()` without an argument is a better choice. `localtime()` without an argument is a better choice.
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
@ -233,3 +234,8 @@ Functions
hardware also lacks battery-powered RTC, so returns number of seconds hardware also lacks battery-powered RTC, so returns number of seconds
since last power-up or from other relative, hardware-specific point since last power-up or from other relative, hardware-specific point
(e.g. reset). (e.g. reset).
.. function:: time_ns()
Similar to `time()` but returns nanoseconds since the Epoch, as an integer (usually
a big integer, so will allocate on the heap).

View File

@ -99,4 +99,10 @@ STATIC mp_obj_t time_ticks_add(mp_obj_t ticks_in, mp_obj_t delta_in) {
} }
MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add); MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj, time_ticks_add);
// Returns the number of nanoseconds since the Epoch, as an integer.
STATIC mp_obj_t time_time_ns(void) {
return mp_obj_new_int_from_ull(mp_hal_time_ns());
}
MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_time_ns_obj, time_time_ns);
#endif // MICROPY_PY_UTIME_MP_HAL #endif // MICROPY_PY_UTIME_MP_HAL

View File

@ -37,5 +37,6 @@ MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj);
MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj);
MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_utime_ticks_add_obj);
MP_DECLARE_CONST_FUN_OBJ_0(mp_utime_time_ns_obj);
#endif // MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #endif // MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H

View File

@ -97,6 +97,7 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);

View File

@ -120,6 +120,7 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) }, { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);

View File

@ -144,6 +144,7 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);

View File

@ -219,6 +219,7 @@ STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
{ MP_ROM_QSTR(MP_QSTR_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
{ MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&mod_time_gmtime_obj) }, { MP_ROM_QSTR(MP_QSTR_gmtime), MP_ROM_PTR(&mod_time_gmtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mod_time_localtime_obj) }, { MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mod_time_localtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) }, { MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) },

View File

@ -0,0 +1,24 @@
# test utime.time_ns()
try:
import utime
utime.sleep_us
utime.time_ns
except (ImportError, AttributeError):
print("SKIP")
raise SystemExit
t0 = utime.time_ns()
utime.sleep_us(1000)
t1 = utime.time_ns()
# Check that time_ns increases.
print(t0 < t1)
# Check that time_ns counts correctly, but be very lenient with the upper bound (50ms).
if 950000 < t1 - t0 < 50000000:
print(True)
else:
print(t0, t1, t1 - t0)

View File

@ -0,0 +1,2 @@
True
True