rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions | Variables
lua.cpp File Reference

Functions

static Heap userHeap (luaUserHeap)
 
static void printLuaMemoryInfo ()
 
static void * myAlloc (void *, void *ptr, size_t osize, size_t nsize)
 
static int lua_setTickRate (lua_State *l)
 
static void loadLibraries (LuaHandle &ls)
 
static LuaHandle setupLuaState (lua_Alloc alloc)
 
static bool loadScript (LuaHandle &ls, const char *scriptStr)
 
static void doInteractive (LuaHandle &ls)
 
static void invokeTick (LuaHandle &ls)
 
static void resetLua ()
 
static bool runOneLua (lua_Alloc alloc, const char *script)
 
void startLua ()
 
static LuaHandle runScript (const char *script)
 
expected< floattestLuaReturnsNumberOrNil (const char *script)
 
float testLuaReturnsNumber (const char *script)
 
int testLuaReturnsInteger (const char *script)
 
void testLuaExecString (const char *script)
 
float strtof_rusefi (const char *str, char **endPtr)
 

Variables

static bool withErrorLoading = false
 
static char luaUserHeap[LUA_USER_HEAP] SDRAM_OPTIONAL LUA_HEAD_RAM_SECTION
 
static int recentRxCount = 0
 
static int totalRxCount = 0
 
static int rxTime
 
static int luaTickPeriodUs
 
static bool interactivePending = false
 
static char interactiveCmd [100]
 
static bool needsReset = false
 
static LuaThread luaThread
 

Function Documentation

◆ doInteractive()

static void doInteractive ( LuaHandle ls)
static

Definition at line 236 of file lua.cpp.

236 {
237 if (!interactivePending) {
238 // no cmd pending, return
239 return;
240 }
241
242 auto status = luaL_dostring(ls, interactiveCmd);
243
244 if (0 == status) {
245 // Function call was OK, resolve return value and print it
246 if (lua_isinteger(ls, -1)) {
247 efiPrintf(TAG "interactive returned integer: %d", lua_tointeger(ls, -1));
248 } else if (lua_isnumber(ls, -1)) {
249 efiPrintf(TAG "interactive returned number: %f", lua_tonumber(ls, -1));
250 } else if (lua_isstring(ls, -1)) {
251 efiPrintf(TAG "interactive returned string: '%s'", lua_tostring(ls, -1));
252 } else if (lua_isboolean(ls, -1)) {
253 efiPrintf(TAG "interactive returned bool: %s", lua_toboolean(ls, -1) ? "true" : "false");
254 } else if (lua_isnil(ls, -1)) {
255 efiPrintf(TAG "interactive returned nil.");
256 } else {
257 efiPrintf(TAG "interactive returned nothing.");
258 }
259 } else {
260 // error with interactive command, print it
261 efiPrintf(TAG "interactive error: %s", lua_tostring(ls, -1));
262 }
263
264 interactivePending = false;
265
266 lua_settop(ls, 0);
267}
static char interactiveCmd[100]
Definition lua.cpp:234
static bool interactivePending
Definition lua.cpp:233

Referenced by runOneLua().

Here is the caller graph for this function:

◆ invokeTick()

static void invokeTick ( LuaHandle ls)
static

Definition at line 269 of file lua.cpp.

269 {
271
272 // run the tick function
273 lua_getglobal(ls, "onTick");
274 if (lua_isnil(ls, -1)) {
275 // TODO: handle missing tick function
276 lua_settop(ls, 0);
277 return;
278 }
279
280 int status = lua_pcall(ls, 0, 0, 0);
281
282 if (0 != status) {
283 // error calling hook function
284 auto errMsg = lua_tostring(ls, -1);
285 efiPrintf(TAG "error %s", errMsg);
286 lua_pop(ls, 1);
287 }
288
289 lua_settop(ls, 0);
290}
@ LuaTickFunction

Referenced by runOneLua().

Here is the caller graph for this function:

◆ loadLibraries()

static void loadLibraries ( LuaHandle ls)
static

Definition at line 165 of file lua.cpp.

165 {
166 constexpr luaL_Reg libs[] = {
167 // TODO: do we even need the base lib?
168 //{ LUA_GNAME, luaopen_base },
169 { LUA_MATHLIBNAME, luaopen_math },
170 };
171
172 for (size_t i = 0; i < efi::size(libs); i++) {
173 luaL_requiref(ls, libs[i].name, libs[i].func, 1);
174 lua_pop(ls, 1);
175 }
176}

Referenced by setupLuaState().

Here is the caller graph for this function:

◆ loadScript()

static bool loadScript ( LuaHandle ls,
const char scriptStr 
)
static

Definition at line 213 of file lua.cpp.

213 {
214 efiPrintf(TAG "loading script length: %lu...", efiStrlen(scriptStr));
215
216 if (0 != luaL_dostring(ls, scriptStr)) {
217 withErrorLoading = true;
218 efiPrintf(TAG "ERROR loading script: %s", lua_tostring(ls, -1));
219 lua_pop(ls, 1);
220 return false;
221 }
222
223 efiPrintf(TAG "script loaded successfully!");
224
225#if EFI_PROD_CODE
227#endif // EFI_PROD_CODE
228
229 return true;
230}
static bool withErrorLoading
Definition lua.cpp:14
static void printLuaMemoryInfo()
Definition lua.cpp:122

Referenced by runOneLua(), runScript(), and testLuaExecString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lua_setTickRate()

static int lua_setTickRate ( lua_State *  l)
static

Definition at line 154 of file lua.cpp.

154 {
155 float freq = luaL_checknumber(l, 1);
156
157 // For instance BMW does 100 CAN messages per second on some IDs, let's allow at least twice that speed
158 // Limit to 1..200 hz
159 freq = clampF(1, freq, 200);
160
161 luaTickPeriodUs = 1000000.0f / freq;
162 return 0;
163}
static int luaTickPeriodUs
Definition lua.cpp:152

Referenced by setupLuaState().

Here is the caller graph for this function:

◆ myAlloc()

static void * myAlloc ( void *  ,
void *  ptr,
size_t  osize,
size_t  nsize 
)
static

Definition at line 129 of file lua.cpp.

129 {
130 if (engineConfiguration->debugMode == DBG_LUA) {
132 }
133
134 return userHeap.realloc(ptr, osize, nsize);
135}
TunerStudioOutputChannels outputChannels
Definition engine.h:102
static Engine *const engine
Definition engine.h:389
static constexpr engine_configuration_s * engineConfiguration
static Heap userHeap(luaUserHeap)

Referenced by runScript(), and testLuaExecString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ printLuaMemoryInfo()

static void printLuaMemoryInfo ( )
static

Definition at line 122 of file lua.cpp.

122 {
123 auto heapSize = userHeap.size();
124 auto memoryUsed = userHeap.used();
125 float pct = 100.0f * memoryUsed / heapSize;
126 efiPrintf("Lua memory heap usage: %d / %d bytes = %.1f%%", memoryUsed, heapSize, pct);
127}

Referenced by loadScript(), and startLua().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resetLua()

static void resetLua ( )
static

Definition at line 298 of file lua.cpp.

298 {
299 engine->module<AcController>().unmock().isDisabledByLua = false;
300#if EFI_CAN_SUPPORT
302#endif // EFI_CAN_SUPPORT
303
304 // De-init pins, they will reinit next start of the script.
306}
void resetLuaCanRx()
constexpr auto & module()
Definition engine.h:187
void luaDeInitPins()

Referenced by runOneLua().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runOneLua()

static bool runOneLua ( lua_Alloc  alloc,
const char script 
)
static

Definition at line 318 of file lua.cpp.

318 {
319 needsReset = false;
320
321 auto ls = setupLuaState(alloc);
322
323 // couldn't start Lua interpreter, bail out
324 if (!ls) {
325 return false;
326 }
327
328 // Reset default tick rate
329 luaTickPeriodUs = MS2US(100);
330
331 if (!loadScript(ls, script)) {
332 return false;
333 }
334
335 while (!needsReset && !chThdShouldTerminateX()) {
336 efitick_t beforeNt = getTimeNowNt();
337#if EFI_CAN_SUPPORT
338 // First, process any pending can RX messages
341 rxTime = getTimeNowNt() - beforeNt;
342#endif // EFI_CAN_SUPPORT
343
344 // Next, check if there is a pending interactive command entered by the user
345 doInteractive(ls);
346
347 invokeTick(ls);
348
351 chThdSleep(TIME_US2I(luaTickPeriodUs));
352
357 }
358
359 resetLua();
360
361 return true;
362}
EngineState engineState
Definition engine.h:325
efitick_t getTimeNowNt()
Definition efitime.cpp:19
static bool loadScript(LuaHandle &ls, const char *scriptStr)
Definition lua.cpp:213
static int recentRxCount
Definition lua.cpp:35
static void doInteractive(LuaHandle &ls)
Definition lua.cpp:236
static LuaHandle setupLuaState(lua_Alloc alloc)
Definition lua.cpp:178
static int rxTime
Definition lua.cpp:37
static int totalRxCount
Definition lua.cpp:36
static void invokeTick(LuaHandle &ls)
Definition lua.cpp:269
static void resetLua()
Definition lua.cpp:298
static bool needsReset
Definition lua.cpp:309
int doLuaCanRx(LuaHandle &ls)
bool getAuxDigital(int index)
Here is the call graph for this function:

◆ runScript()

static LuaHandle runScript ( const char script)
static

Definition at line 452 of file lua.cpp.

452 {
453 auto ls = setupLuaState(myAlloc);
454
455 if (!ls) {
456 throw std::logic_error("Call to setupLuaState failed, returned null");
457 }
458
459 if (!loadScript(ls, script)) {
460 throw std::logic_error("Call to loadScript failed");
461 }
462
463 lua_getglobal(ls, "testFunc");
464 if (lua_isnil(ls, -1)) {
465 throw std::logic_error("Failed to find function testFunc");
466 }
467
468 int status = lua_pcall(ls, 0, 1, 0);
469
470 if (0 != status) {
471 std::string msg = std::string("lua error while running script: ") + lua_tostring(ls, -1);
472 throw std::logic_error(msg);
473 }
474
475 return ls;
476}
static void * myAlloc(void *, void *ptr, size_t osize, size_t nsize)
Definition lua.cpp:129

Referenced by testLuaReturnsInteger(), testLuaReturnsNumber(), and testLuaReturnsNumberOrNil().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setupLuaState()

static LuaHandle setupLuaState ( lua_Alloc  alloc)
static

Definition at line 178 of file lua.cpp.

178 {
179 LuaHandle ls = lua_newstate(alloc, NULL);
180
181 if (!ls) {
182 criticalError("Failed to start Lua interpreter");
183
184 return nullptr;
185 }
186
187 lua_atpanic(ls, [](lua_State* l) {
188 criticalError("Lua panic: %s", lua_tostring(l, -1));
189
190 // hang the lua thread
191 while (true) ;
192
193 return 0;
194 });
195
196 // Load Lua's own libraries
197 loadLibraries(ls);
198
199 // Load rusEFI hooks
200 lua_register(ls, "setTickRate", lua_setTickRate);
202
203 // run a GC cycle
204 lua_gc(ls, LUA_GCCOLLECT, 0);
205
206 // set GC settings
207 // see https://www.lua.org/manual/5.4/manual.html#2.5.1
208 lua_gc(ls, LUA_GCINC, 50, 1000, 9);
209
210 return ls;
211}
static void loadLibraries(LuaHandle &ls)
Definition lua.cpp:165
static int lua_setTickRate(lua_State *l)
Definition lua.cpp:154
void configureRusefiLuaHooks(lua_State *lState)

Referenced by runOneLua(), runScript(), and testLuaExecString().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ startLua()

void startLua ( )

Definition at line 396 of file lua.cpp.

396 {
397#if defined(STM32F4) && !defined(EFI_IS_F42x)
398 // we need this on microRusEFI for sure
399 // definitely should NOT have this on Proteus
400 // on Hellen a bit of open question what's the best track
401 // cute hack: let's check at runtime if you are a lucky owner of microRusEFI with extra RAM and use that extra RAM for extra Lua
402 if (isStm32F42x()) {
403 char *buffer = (char *)0x20020000;
404 userHeap.reinit(buffer, 60000);
405 }
406#endif // STM32F4
407
408#if LUA_USER_HEAP > 1
409#if EFI_CAN_SUPPORT
410 initLuaCanRx();
411#endif // EFI_CAN_SUPPORT
412
413 addConsoleActionII("set_lua_setting", [](int index, int value) {
414 engineConfiguration->scriptSetting[index] = value;
415 });
416
417 luaThread.start();
418
419 addConsoleActionS("lua", [](const char* str){
420 if (interactivePending) {
421 return;
422 }
423
424 strncpy(interactiveCmd, str, sizeof(interactiveCmd) - 1);
425 interactiveCmd[sizeof(interactiveCmd) - 1] = '\0';
426
427 interactivePending = true;
428 });
429
430 addConsoleAction("luareset", [](){
431 needsReset = true;
432 });
433
434 addConsoleAction("luamemory", [](){
435 efiPrintf("rx total/recent %d %d", totalRxCount,
437 efiPrintf("luaCycle %luus including luaRxTime %dus", NT2US(engine->outputChannels.luaLastCycleDuration),
438 NT2US(rxTime));
439
441 });
442#endif
443}
bool isStm32F42x(void)
void addConsoleActionS(const char *token, VoidCharPtr callback)
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
void addConsoleActionII(const char *token, VoidIntInt callback)
Register a console command with two Integer parameters.
static LuaThread luaThread
Definition lua.cpp:393
void initLuaCanRx()
static BigBufferHandle buffer

Referenced by commonEarlyInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ strtof_rusefi()

float strtof_rusefi ( const char str,
char **  endPtr 
)

Definition at line 536 of file lua.cpp.

536 {
537 bool afterDecimalPoint = false;
538 float div = 1; // Divider to place digits after the decimal point
539
540 if (endPtr) {
541 *endPtr = const_cast<char*>(str);
542 }
543
544 float integerPart = 0;
545 float fractionalPart = 0;
546
547 while (*str != '\0') {
548 char c = *str;
549 int digitVal = c - '0';
550
551 if (c >= '0' && c <= '9') {
552 if (!afterDecimalPoint) {
553 // Integer part
554 integerPart = 10 * integerPart + digitVal;
555 } else {
556 // Fractional part
557 fractionalPart = 10 * fractionalPart + digitVal;
558 div *= 10;
559 }
560 } else if (c == '.') {
561 afterDecimalPoint = true;
562 } else {
563 break;
564 }
565
566 str++;
567
568 if (endPtr) {
569 *endPtr = const_cast<char*>(str);
570 }
571 }
572
573 return integerPart + fractionalPart / div;
574}

◆ testLuaExecString()

void testLuaExecString ( const char script)

Definition at line 518 of file lua.cpp.

518 {
519 auto ls = setupLuaState(myAlloc);
520
521 if (!ls) {
522 throw std::logic_error("Call to setupLuaState failed, returned null");
523 }
524
525 if (!loadScript(ls, script)) {
526 throw std::logic_error("Call to loadScript failed");
527 }
528}
Here is the call graph for this function:

◆ testLuaReturnsInteger()

int testLuaReturnsInteger ( const char script)

Definition at line 507 of file lua.cpp.

507 {
508 auto ls = runScript(script);
509
510 // pop the return value;
511 if (!lua_isinteger(ls, -1)) {
512 throw std::logic_error("Returned value is not an integer");
513 }
514
515 return lua_tointeger(ls, -1);
516}
static LuaHandle runScript(const char *script)
Definition lua.cpp:452
Here is the call graph for this function:

◆ testLuaReturnsNumber()

float testLuaReturnsNumber ( const char script)

Definition at line 495 of file lua.cpp.

495 {
496 auto ls = runScript(script);
497
498 // check the return value
499 if (!lua_isnumber(ls, -1)) {
500 throw new std::logic_error("Returned value is not a number");
501 }
502
503 // pop the return value
504 return lua_tonumber(ls, -1);
505}
Here is the call graph for this function:

◆ testLuaReturnsNumberOrNil()

expected< float > testLuaReturnsNumberOrNil ( const char script)

Definition at line 478 of file lua.cpp.

478 {
479 auto ls = runScript(script);
480
481 // check nil return first
482 if (lua_isnil(ls, -1)) {
483 return unexpected;
484 }
485
486 // If not nil, it should be a number
487 if (!lua_isnumber(ls, -1)) {
488 throw std::logic_error("Returned value is not a number");
489 }
490
491 // pop the return value
492 return lua_tonumber(ls, -1);
493}
Here is the call graph for this function:

◆ userHeap()

static Heap userHeap ( luaUserHeap  )
static

Referenced by myAlloc(), printLuaMemoryInfo(), and startLua().

Here is the caller graph for this function:

Variable Documentation

◆ interactiveCmd

char interactiveCmd[100]
static

Definition at line 234 of file lua.cpp.

Referenced by doInteractive(), and startLua().

◆ interactivePending

bool interactivePending = false
static

Definition at line 233 of file lua.cpp.

Referenced by doInteractive(), and startLua().

◆ LUA_HEAD_RAM_SECTION

char luaUserHeap [LUA_USER_HEAP] SDRAM_OPTIONAL LUA_HEAD_RAM_SECTION
static

Definition at line 31 of file lua.cpp.

◆ luaThread

LuaThread luaThread
static

Definition at line 393 of file lua.cpp.

Referenced by startLua().

◆ luaTickPeriodUs

int luaTickPeriodUs
static

Definition at line 152 of file lua.cpp.

Referenced by lua_setTickRate(), and runOneLua().

◆ needsReset

bool needsReset = false
static

Definition at line 309 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ recentRxCount

int recentRxCount = 0
static

Definition at line 35 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ rxTime

int rxTime
static

Definition at line 37 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ totalRxCount

int totalRxCount = 0
static

Definition at line 36 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ withErrorLoading

bool withErrorLoading = false
static

Definition at line 14 of file lua.cpp.

Referenced by loadScript().

Go to the source code of this file.