esp32: Add node.uptime() function using esp_timer_get_time() (#2533)

* esp32: Reinstate tmr.now() function using esp_timer_get_time()

Also added larger limit before wrapping if Lua's number type supports
it.

* Renamed tmr.now() to node.uptime()

Added second return value to indicate timer wrap
This commit is contained in:
tomsci 2018-11-10 13:53:10 +00:00 committed by Arnim Läuger
parent de48203375
commit d2345f2beb
2 changed files with 55 additions and 10 deletions

View File

@ -279,6 +279,23 @@ static int node_osprint (lua_State *L)
}
static int node_uptime(lua_State *L)
{
uint64_t now = esp_timer_get_time();
#ifdef LUA_NUMBER_INTEGRAL
lua_pushinteger(L, (lua_Integer)(now & 0x7FFFFFFF));
lua_pushinteger(L, (lua_Integer)((now >> 31) & 0x7FFFFFFF));
#else
// The largest double that doesn't lose whole-number precision is 2^53, so the
// mask we apply is (2^53)-1 which is 0x1FFFFFFFFFFFFF. In practice this is
// long enough the timer should never wrap, but it interesting nonetheless.
lua_pushnumber(L, (lua_Number)(now & 0x1FFFFFFFFFFFFFull));
lua_pushinteger(L, (lua_Integer)(now >> 53));
#endif
return 2;
}
static const LUA_REG_TYPE node_egc_map[] = {
{ LSTRKEY( "setmode" ), LFUNCVAL( node_egc_setmode ) },
{ LSTRKEY( "NOT_ACTIVE" ), LNUMVAL( EGC_NOT_ACTIVE ) },
@ -310,6 +327,7 @@ static const LUA_REG_TYPE node_map[] =
{ LSTRKEY( "restart" ), LFUNCVAL( node_restart ) },
{ LSTRKEY( "stripdebug"), LFUNCVAL( node_stripdebug ) },
{ LSTRKEY( "task" ), LROVAL( node_task_map ) },
{ LSTRKEY( "uptime" ), LFUNCVAL( node_uptime ) },
{ LNILKEY, LNILVAL }
};

View File

@ -407,6 +407,33 @@ Nothing
node.osprint(true)
```
## node.uptime()
Returns the value of the system counter, which counts in microseconds starting at 0 when the device is booted. Because a 32-bit signed integer can only fit 35 minutes' worth of microseconds before wrapping, when using integer-only 32-bit Lua this API returns 2 results, the first being the bottom 31 bits of the counter, and the second being the next 31 bits (ie bits 31 through 62 of the underlying 64-bit counter).
Therefore the first result will wrap back to 0 after about 35 minutes (2^31 microseconds), at which point the second result will increment by one. It is important to consider both values, or otherwise handle the first result wrapping, when for example using this function to [debounce or throttle GPIO input](https://github.com/hackhitchin/esp8266-co-uk/issues/2).
When using floating-point Lua, hundreds of years of microseconds can fit in a single value with no loss of precision. In such configurations, the first result will be the bottom 53 bits of the system counter as a floating-point number, and the second result will be the top 11 bits, which in practice will always be zero unless the system counter exceeds 285 years.
#### Syntax
`node.uptime()`
#### Parameters
none
#### Returns
Two results `lowbits, highbits`. The first is the time in microseconds since boot or the last time the counter wrapped, and the second is the number of times the counter has wrapped. Depending on whether Lua was compiled with floating-point support or not determines when the counter wraps.
#### Example
```lua
print(node.uptime())
print(node.uptime())
lowbits, highbits = node.uptime()
print(lowbits, "microseconds have elapsed since the uptime last wrapped")
print(string.format("Uptime has wrapped %d times", highbits))
```
# node.egc module
## node.egc.setmode()