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

Functions

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 int luaTickPeriodUs
 
static int recentRxCount = 0
 
static int totalRxCount = 0
 
static int rxTime
 
static bool interactivePending = false
 
static char interactiveCmd [100]
 
static uint32_t maxLuaDuration {}
 
static bool needsReset = false
 
static LuaThread luaThread
 

Function Documentation

◆ doInteractive()

static void doInteractive ( LuaHandle ls)
static

Definition at line 113 of file lua.cpp.

113 {
114 if (!interactivePending) {
115 // no cmd pending, return
116 return;
117 }
118
119 auto status = luaL_dostring(ls, interactiveCmd);
120
121 if (0 == status) {
122 // Function call was OK, resolve return value and print it
123 if (lua_isinteger(ls, -1)) {
124 efiPrintf(TAG "interactive returned integer: %d", lua_tointeger(ls, -1));
125 } else if (lua_isnumber(ls, -1)) {
126 efiPrintf(TAG "interactive returned number: %f", lua_tonumber(ls, -1));
127 } else if (lua_isstring(ls, -1)) {
128 efiPrintf(TAG "interactive returned string: '%s'", lua_tostring(ls, -1));
129 } else if (lua_isboolean(ls, -1)) {
130 efiPrintf(TAG "interactive returned bool: %s", lua_toboolean(ls, -1) ? "true" : "false");
131 } else if (lua_isnil(ls, -1)) {
132 efiPrintf(TAG "interactive returned nil.");
133 } else {
134 efiPrintf(TAG "interactive returned nothing.");
135 }
136 } else {
137 // error with interactive command, print it
138 efiPrintf(TAG "interactive error: %s", lua_tostring(ls, -1));
139 }
140
141 interactivePending = false;
142
143 lua_settop(ls, 0);
144}
static char interactiveCmd[100]
Definition lua.cpp:111
static bool interactivePending
Definition lua.cpp:110

Referenced by runOneLua().

Here is the caller graph for this function:

◆ invokeTick()

static void invokeTick ( LuaHandle ls)
static

Definition at line 148 of file lua.cpp.

148 {
150
151 // run the tick function
152 lua_getglobal(ls, "onTick");
153 if (lua_isnil(ls, -1)) {
154 // TODO: handle missing tick function
155 lua_settop(ls, 0);
156 return;
157 }
158#if EFI_PROD_CODE
159 uint32_t before = port_rt_get_counter_value();
160#endif // EFI_PROD_CODE
161
162 int status = lua_pcall(ls, 0, 0, 0);
163
164#if EFI_PROD_CODE
165 uint32_t duration = port_rt_get_counter_value() - before;
166 maxLuaDuration = std::max(maxLuaDuration, duration);
167#endif // EFI_PROD_CODE
168
169 if (0 != status) {
170 // error calling hook function
171 auto errMsg = lua_tostring(ls, -1);
172 efiPrintf(TAG "error %s", errMsg);
173 lua_pop(ls, 1);
174 }
175
176 lua_settop(ls, 0);
177}
static uint32_t maxLuaDuration
Definition lua.cpp:146
@ LuaTickFunction

Referenced by runOneLua().

Here is the caller graph for this function:

◆ loadLibraries()

static void loadLibraries ( LuaHandle ls)
static

Definition at line 42 of file lua.cpp.

42 {
43 constexpr luaL_Reg libs[] = {
44 // TODO: do we even need the base lib?
45 //{ LUA_GNAME, luaopen_base },
46 { LUA_MATHLIBNAME, luaopen_math },
47 };
48
49 for (size_t i = 0; i < efi::size(libs); i++) {
50 luaL_requiref(ls, libs[i].name, libs[i].func, 1);
51 lua_pop(ls, 1);
52 }
53}

Referenced by setupLuaState().

Here is the caller graph for this function:

◆ loadScript()

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

Definition at line 90 of file lua.cpp.

90 {
91 efiPrintf(TAG "loading script length: %u...", std::strlen(scriptStr));
92
93 if (0 != luaL_dostring(ls, scriptStr)) {
94 withErrorLoading = true;
95 efiPrintf(TAG "ERROR loading script: %s", lua_tostring(ls, -1));
96 lua_pop(ls, 1);
97 return false;
98 }
99
100 efiPrintf(TAG "script loaded successfully!");
101
102#if EFI_PROD_CODE
104#endif // EFI_PROD_CODE
105
106 return true;
107}
static bool withErrorLoading
Definition lua.cpp:15
void luaHeapPrintInfo()
Definition lua_heap.cpp:213

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 24 of file lua.cpp.

24 {
25 float userFreq = luaL_checknumber(l, 1);
26
27 // For instance BMW does 100 CAN messages per second on some IDs, let's allow at least twice that speed
28 // Limit to 1..200 hz
29 float freq = clampF(1, userFreq, 2000);
30 if (freq != userFreq) {
31 efiPrintf(TAG "clamping tickrate %f", freq);
32 }
33
34 if (freq > 150 && !engineConfiguration->luaCanRxWorkaround) {
35 efiPrintf(TAG "luaCanRxWorkaround recommended at high tick rate!");
36 }
37
38 luaTickPeriodUs = 1000000.0f / freq;
39 return 0;
40}
static constexpr engine_configuration_s * engineConfiguration
static int luaTickPeriodUs
Definition lua.cpp:16

Referenced by setupLuaState().

Here is the caller graph for this function:

◆ resetLua()

static void resetLua ( )
static

Definition at line 185 of file lua.cpp.

185 {
186 engine->module<AcController>().unmock().isDisabledByLua = false;
187#if EFI_CAN_SUPPORT
189#endif // EFI_CAN_SUPPORT
190
191 // De-init pins, they will reinit next start of the script.
193}
void resetLuaCanRx()
constexpr auto & module()
Definition engine.h:200
static EngineAccessor engine
Definition engine.h:413
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 205 of file lua.cpp.

205 {
206 needsReset = false;
207
208 auto ls = setupLuaState(alloc);
209
210 // couldn't start Lua interpreter, bail out
211 if (!ls) {
212 return false;
213 }
214
215 // Reset default tick rate
216 luaTickPeriodUs = MS2US(5);
217
218 if (!loadScript(ls, script)) {
219 return false;
220 }
221
222 while (!needsReset && !chThdShouldTerminateX()) {
223 efitick_t beforeNt = getTimeNowNt();
224#if EFI_CAN_SUPPORT
225 // First, process any pending can RX messages
228 rxTime = getTimeNowNt() - beforeNt;
229#endif // EFI_CAN_SUPPORT
230
231 // Next, check if there is a pending interactive command entered by the user
232 doInteractive(ls);
233
234 invokeTick(ls);
235
238 chThdSleep(TIME_US2I(luaTickPeriodUs));
239
244 }
245
246 resetLua();
247
248 return true;
249}
EngineState engineState
Definition engine.h:344
TunerStudioOutputChannels outputChannels
Definition engine.h:109
efitick_t getTimeNowNt()
Definition efitime.cpp:19
static bool loadScript(LuaHandle &ls, const char *scriptStr)
Definition lua.cpp:90
static int recentRxCount
Definition lua.cpp:19
static void doInteractive(LuaHandle &ls)
Definition lua.cpp:113
static LuaHandle setupLuaState(lua_Alloc alloc)
Definition lua.cpp:55
static int rxTime
Definition lua.cpp:21
static int totalRxCount
Definition lua.cpp:20
static void invokeTick(LuaHandle &ls)
Definition lua.cpp:148
static void resetLua()
Definition lua.cpp:185
static bool needsReset
Definition lua.cpp:196
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 328 of file lua.cpp.

328 {
329 auto ls = setupLuaState(luaHeapAlloc);
330
331 if (!ls) {
332 throw std::logic_error("Call to setupLuaState failed, returned null");
333 }
334
335 if (!loadScript(ls, script)) {
336 throw std::logic_error("Call to loadScript failed");
337 }
338
339 lua_getglobal(ls, "testFunc");
340 if (lua_isnil(ls, -1)) {
341 throw std::logic_error("Failed to find function testFunc");
342 }
343
344 int status = lua_pcall(ls, 0, 1, 0);
345
346 if (0 != status) {
347 std::string msg = std::string("lua error while running script: ") + lua_tostring(ls, -1);
348 throw std::logic_error(msg);
349 }
350
351 return ls;
352}
void * luaHeapAlloc(void *, void *optr, size_t osize, size_t nsize)
Definition lua_heap.cpp:138

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 55 of file lua.cpp.

55 {
56 LuaHandle ls = lua_newstate(alloc, NULL);
57
58 if (!ls) {
59 criticalError("Failed to start Lua interpreter");
60
61 return nullptr;
62 }
63
64 lua_atpanic(ls, [](lua_State* l) {
65 criticalError("Lua panic: %s", lua_tostring(l, -1));
66
67 // hang the lua thread
68 while (true) ;
69
70 return 0;
71 });
72
73 // Load Lua's own libraries
74 loadLibraries(ls);
75
76 // Load rusEFI hooks
77 lua_register(ls, "setTickRate", lua_setTickRate);
79
80 // run a GC cycle
81 lua_gc(ls, LUA_GCCOLLECT, 0);
82
83 // set GC settings
84 // see https://www.lua.org/manual/5.4/manual.html#2.5.1
85 lua_gc(ls, LUA_GCINC, 50, 1000, 9);
86
87 return ls;
88}
static void loadLibraries(LuaHandle &ls)
Definition lua.cpp:42
static int lua_setTickRate(lua_State *l)
Definition lua.cpp:24
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 281 of file lua.cpp.

281 {
282 luaHeapInit();
283
284#if EFI_CAN_SUPPORT
285 initLuaCanRx();
286#endif // EFI_CAN_SUPPORT
287
288 addConsoleActionII("set_lua_setting", [](int index, int value) {
289 engineConfiguration->scriptSetting[index] = value;
290 });
291
292 luaThread.start();
293
294 addConsoleActionS("lua", [](const char* str){
295 if (interactivePending) {
296 return;
297 }
298
299 strncpy(interactiveCmd, str, sizeof(interactiveCmd) - 1);
300 interactiveCmd[sizeof(interactiveCmd) - 1] = '\0';
301
302 interactivePending = true;
303 });
304
305 addConsoleAction("luareset", [](){
306 needsReset = true;
307 });
308
309 addConsoleAction("luamemory", [](){
310 efiPrintf("maxLuaDuration %lu", maxLuaDuration);
311 maxLuaDuration = 0;
312 efiPrintf("rx total/recent/dropped %d %d %d", totalRxCount,
314 efiPrintf("luaCycle %luus including luaRxTime %dus", NT2US(engine->outputChannels.luaLastCycleDuration),
315 NT2US(rxTime));
316
318 });
319}
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:279
size_t getLuaCanRxDropped()
void initLuaCanRx()
void luaHeapInit()
Definition lua_heap.cpp:109

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 412 of file lua.cpp.

412 {
413 bool afterDecimalPoint = false;
414 float div = 1; // Divider to place digits after the decimal point
415
416 if (endPtr) {
417 *endPtr = const_cast<char*>(str);
418 }
419
420 float integerPart = 0;
421 float fractionalPart = 0;
422
423 while (*str != '\0') {
424 char c = *str;
425 int digitVal = c - '0';
426
427 if (c >= '0' && c <= '9') {
428 if (!afterDecimalPoint) {
429 // Integer part
430 integerPart = 10 * integerPart + digitVal;
431 } else {
432 // Fractional part
433 fractionalPart = 10 * fractionalPart + digitVal;
434 div *= 10;
435 }
436 } else if (c == '.') {
437 afterDecimalPoint = true;
438 } else {
439 break;
440 }
441
442 str++;
443
444 if (endPtr) {
445 *endPtr = const_cast<char*>(str);
446 }
447 }
448
449 return integerPart + fractionalPart / div;
450}

◆ testLuaExecString()

void testLuaExecString ( const char script)

Definition at line 394 of file lua.cpp.

394 {
395 auto ls = setupLuaState(luaHeapAlloc);
396
397 if (!ls) {
398 throw std::logic_error("Call to setupLuaState failed, returned null");
399 }
400
401 if (!loadScript(ls, script)) {
402 throw std::logic_error("Call to loadScript failed");
403 }
404}
Here is the call graph for this function:

◆ testLuaReturnsInteger()

int testLuaReturnsInteger ( const char script)

Definition at line 383 of file lua.cpp.

383 {
384 auto ls = runScript(script);
385
386 // pop the return value;
387 if (!lua_isinteger(ls, -1)) {
388 throw std::logic_error("Returned value is not an integer");
389 }
390
391 return lua_tointeger(ls, -1);
392}
static LuaHandle runScript(const char *script)
Definition lua.cpp:328
Here is the call graph for this function:

◆ testLuaReturnsNumber()

float testLuaReturnsNumber ( const char script)

Definition at line 371 of file lua.cpp.

371 {
372 auto ls = runScript(script);
373
374 // check the return value
375 if (!lua_isnumber(ls, -1)) {
376 throw new std::logic_error("Returned value is not a number");
377 }
378
379 // pop the return value
380 return lua_tonumber(ls, -1);
381}
Here is the call graph for this function:

◆ testLuaReturnsNumberOrNil()

expected< float > testLuaReturnsNumberOrNil ( const char script)

Definition at line 354 of file lua.cpp.

354 {
355 auto ls = runScript(script);
356
357 // check nil return first
358 if (lua_isnil(ls, -1)) {
359 return unexpected;
360 }
361
362 // If not nil, it should be a number
363 if (!lua_isnumber(ls, -1)) {
364 throw std::logic_error("Returned value is not a number");
365 }
366
367 // pop the return value
368 return lua_tonumber(ls, -1);
369}
Here is the call graph for this function:

Variable Documentation

◆ interactiveCmd

char interactiveCmd[100]
static

Definition at line 111 of file lua.cpp.

Referenced by doInteractive(), and startLua().

◆ interactivePending

bool interactivePending = false
static

Definition at line 110 of file lua.cpp.

Referenced by doInteractive(), and startLua().

◆ luaThread

LuaThread luaThread
static

Definition at line 279 of file lua.cpp.

Referenced by startLua().

◆ luaTickPeriodUs

int luaTickPeriodUs
static

Definition at line 16 of file lua.cpp.

Referenced by lua_setTickRate(), and runOneLua().

◆ maxLuaDuration

uint32_t maxLuaDuration {}
static

Definition at line 146 of file lua.cpp.

146{};

Referenced by invokeTick(), and startLua().

◆ needsReset

bool needsReset = false
static

Definition at line 196 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ recentRxCount

int recentRxCount = 0
static

Definition at line 19 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ rxTime

int rxTime
static

Definition at line 21 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ totalRxCount

int totalRxCount = 0
static

Definition at line 20 of file lua.cpp.

Referenced by runOneLua(), and startLua().

◆ withErrorLoading

bool withErrorLoading = false
static

Definition at line 15 of file lua.cpp.

Referenced by loadScript().

Go to the source code of this file.