Browse Source

Expose CPU CCOUNT register as tmr function (#2906)

Nikolay Fiykov 4 years ago
parent
commit
2ae9af58fc
3 changed files with 47 additions and 0 deletions
  1. 8 0
      app/modules/tmr.c
  2. 3 0
      app/platform/platform.h
  3. 36 0
      docs/modules/tmr.md

+ 8 - 0
app/modules/tmr.c

@@ -142,6 +142,13 @@ static int tmr_now(lua_State* L){
 	return 1;
 }
 
+// Lua: tmr.ccount() , returns CCOUNT register
+static int tmr_ccount( lua_State* L )
+{
+	lua_pushinteger(L, CCOUNT_REG);
+	return 1;
+}
+
 static tmr_t tmr_get( lua_State *L, int stack ) {
 	tmr_t t = (tmr_t)luaL_checkudata(L, stack, "tmr.timer");
 	if (t == NULL)
@@ -392,6 +399,7 @@ LROT_BEGIN(tmr)
   LROT_FUNCENTRY( wdclr, tmr_wdclr )
   LROT_FUNCENTRY( softwd, tmr_softwd )
   LROT_FUNCENTRY( time, tmr_time )
+  LROT_FUNCENTRY( ccount, tmr_ccount )
 #ifdef TIMER_SUSPEND_ENABLE
   LROT_FUNCENTRY( suspend_all, tmr_suspend_all )
   LROT_FUNCENTRY( resume_all, tmr_resume_all )

+ 3 - 0
app/platform/platform.h

@@ -372,4 +372,7 @@ platform_task_handle_t platform_task_get_id(platform_task_callback_t t);
 
 bool platform_post(uint8 prio, platform_task_handle_t h, platform_task_param_t par);
 
+// Get current value of CCOUNt register
+#define CCOUNT_REG ({ int32_t r; asm volatile("rsr %0, ccount" : "=r"(r)); r;})
+
 #endif

+ 36 - 0
docs/modules/tmr.md

@@ -145,6 +145,42 @@ none
 #### Returns
 `nil`
 
+## tmr.ccount()
+
+Get value of CPU CCOUNT register which contains CPU ticks. The register is 32-bit and rolls over.
+
+Converting the register's CPU ticks to us is done by dividing it to 80 or 160 (CPU80/CPU160) i.e. `tmr.ccount() / node.getcpufreq()`.
+
+Register arithmetic works without need to account for roll over, unlike `tmr.now()`. Because of same reason when CCOUNT is having its 32nd bit set, it appears in Lua as negative number.
+
+#### Syntax
+`tmr.ccount()`
+
+#### Returns
+The current value of CCOUNT register.
+
+#### Example
+```lua
+function timeIt(fnc, cnt)
+   local function loopIt(f2)
+     local t0 = tmr.ccount()
+     for i=1,cnt do
+       f2()
+     end
+     local t1 = tmr.ccount()
+     return math.ceil((t1-t0)/cnt)
+   end
+   assert(type(fnc) == "function", "function to test missing")
+   cnt = cnt or 1000
+   local emptyTime = loopIt(function()end)
+   local deltaCPUTicks = math.abs(loopIt(fnc) - emptyTime)
+   local deltaUS = math.ceil(deltaCPUTicks/node.getcpufreq())
+   return deltaCPUTicks, deltaUS
+end
+
+print( timeIt(function() tmr.ccount() end) )
+```
+
 ## Timer Object Methods
 
 ### tobj:alarm()