/* * dr_lua.c * * Author : Charles KWON * * This module provides a simple and reusable interface layer * between C firmware code and embedded Lua scripts. * It is designed to make calling Lua functions from C firmware * straightforward and safe. * * Example: * Lua function: add3(x) = x + 3 * C function : dr_lua_add3(int num1) */ #include "lua.h" #include "lauxlib.h" #include "lualib.h" /* ------------------------------------------------- * External output function (UART / RTT, etc.) * This function must be implemented by the project. * ------------------------------------------------- */ extern void board_print(const char *s); /* ------------------------------------------------- * Global Lua state * ------------------------------------------------- */ static lua_State *g_L = NULL; /* ------------------------------------------------- * Initialize Lua VM * ------------------------------------------------- */ void dr_lua_init(void) { g_L = luaL_newstate(); /* Load base library only */ luaL_requiref(g_L, "_G", luaopen_base, 1); lua_pop(g_L, 1); } /* ------------------------------------------------- * Load Lua script * Defines: * function add3(x) * return x + 3 * end * ------------------------------------------------- */ void dr_lua_load_script(void) { const char *lua_code = "function add3(x)\n" " return x + 3\n" "end"; if (luaL_dostring(g_L, lua_code) != LUA_OK) { const char *err = lua_tostring(g_L, -1); board_print(err); lua_pop(g_L, 1); } } /* ------------------------------------------------- * Core interface function * Calls Lua function add3 from C firmware * * @param num1 Input integer value * @return Result of (num1 + 3) * -1 if Lua function is not found * -2 if Lua call fails * ------------------------------------------------- */ int dr_lua_add3(int num1) { int result = 0; /* 1. Get Lua function: add3 */ lua_getglobal(g_L, "add3"); if (!lua_isfunction(g_L, -1)) { lua_pop(g_L, 1); return -1; /* Function not found */ } /* 2. Push argument */ lua_pushinteger(g_L, num1); /* 3. Call Lua function (1 argument, 1 return value) */ if (lua_pcall(g_L, 1, 1, 0) != LUA_OK) { const char *err = lua_tostring(g_L, -1); board_print(err); lua_pop(g_L, 1); return -2; /* Call failed */ } /* 4. Read return value */ if (lua_isinteger(g_L, -1)) { result = (int)lua_tointeger(g_L, -1); } /* 5. Clean up Lua stack */ lua_pop(g_L, 1); return result; /* num1 + 3 */ }