Skip to content

Commit

Permalink
extmod/utime_mphal: Add generic utime.time_ns() function.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dpgeorge committed Oct 1, 2020
1 parent 905a18a commit d4b61b0
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 2 deletions.
10 changes: 8 additions & 2 deletions docs/library/utime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,9 @@ Functions
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
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
`ticks_ms()` and `ticks_us()` functions, if you need calendar time,
to provide higher than second precision. If you need higher precision, absolute
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.

.. admonition:: Difference to CPython
Expand All @@ -233,3 +234,8 @@ Functions
hardware also lacks battery-powered RTC, so returns number of seconds
since last power-up or from other relative, hardware-specific point
(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).
6 changes: 6 additions & 0 deletions extmod/utime_mphal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

// 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
1 change: 1 addition & 0 deletions extmod/utime_mphal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_2(mp_utime_ticks_diff_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
1 change: 1 addition & 0 deletions ports/esp32/modutime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
};

STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
Expand Down
1 change: 1 addition & 0 deletions ports/esp8266/modutime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
};

STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
Expand Down
1 change: 1 addition & 0 deletions ports/stm32/modutime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_time_ns), MP_ROM_PTR(&mp_utime_time_ns_obj) },
};

STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
Expand Down
1 change: 1 addition & 0 deletions ports/unix/modtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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_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_localtime), MP_ROM_PTR(&mod_time_localtime_obj) },
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) },
Expand Down
24 changes: 24 additions & 0 deletions tests/extmod/utime_time_ns.py
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 2 additions & 0 deletions tests/extmod/utime_time_ns.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
True
True

0 comments on commit d4b61b0

Please sign in to comment.