В настоящее время я разрабатываю приложение для моего ESP32, для которого мне нужно использовать Lua-C-API.
Моя цель - вызвать функцию Lua с именем «add» из C и прошить программу на ESP32.
Итак, в коде Lua («add.lua») я определяю функцию «add»:
-- add two numbers
function add ( x, y )
return x + y
end
Мой код C для вызова интерфейса следующий:
/* Function luaadd */
int luaadd (lua_State* L, int x, int y ) {
int sum;
/* the function name */
lua_getglobal(L, "add");
/* the first argument */
lua_pushnumber(L, x);
/* the second argument */
lua_pushnumber(L, y);
/* call the function with 2 arguments, return 1 result */
lua_call(L, 2, 1);
/* get the result */
sum = (int)lua_tointeger(L, -1);
lua_pop(L, 1);
return sum;
}
/* Main function */
void app_main()
{
initialize_nvs();
#if CONFIG_STORE_HISTORY
initialize_filesystem();
#endif
initialize_console();
/* initialize Lua */
lua_State* L = luaL_newstate();
luaL_openlibs(L);
openlibs(L);
luaopen_base(L); /* opens the basic library */
luaopen_table(L); /* opens the table library */
luaopen_io(L); /* opens the I/O library */
luaopen_string(L); /* opens the string lib. */
luaopen_math(L); /* opens the math lib. */
/* load Lua file */
if (luaL_loadfile(L, "add.lua")){
printf("Error loading file: %s", lua_tostring(L, -1));
}
/* call the add function */
int sum;
sum = luaadd(L, 10, 15 );
/* print the result */
printf( "The sum is %d\n", sum );
/* cleanup Lua */
lua_close(L);
/* print 'Finished' to console */
printf("Finished");
}
И это весь файл C:
#include <modules.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "esp_system.h"
#include "esp_log.h"
#include "esp_console.h"
#include "esp_vfs_dev.h"
#include "driver/uart.h"
#include "linenoise/linenoise.h"
#include "argtable3/argtable3.h"
#include "esp_vfs_fat.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "sb.h"
#include <unistd.h>
#include <errno.h>
#include <unistd.h>
static const char* TAG = "Console";
/* Console command history can be stored to and loaded from a file.
* The easiest way to do this is to use FATFS filesystem on top of
* wear_levelling library.
*/
#if CONFIG_STORE_HISTORY
#define MOUNT_PATH "/data"
#define HISTORY_PATH MOUNT_PATH "/history.txt"
static void initialize_filesystem()
{
static wl_handle_t wl_handle;
const esp_vfs_fat_mount_config_t mount_config = {
.max_files = 4,
.format_if_mount_failed = true
};
esp_err_t err = esp_vfs_fat_spiflash_mount(MOUNT_PATH, "storage", &mount_config, &wl_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount FATFS (0x%x)", err);
return;
}
}
#endif // CONFIG_STORE_HISTORY
static void initialize_nvs()
{
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
ESP_ERROR_CHECK( nvs_flash_erase() );
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
}
static void initialize_console()
{
/* Disable buffering on stdin and stdout */
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
esp_vfs_dev_uart_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
/* Move the caret to the beginning of the next line on '\n' */
esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
/* Install UART driver for interrupt-driven reads and writes */
ESP_ERROR_CHECK( uart_driver_install(CONFIG_CONSOLE_UART_NUM,
256, 0, 0, NULL, 0) );
/* Tell VFS to use UART driver */
esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM);
/* Initialize the console */
esp_console_config_t console_config = {
.max_cmdline_args = 8,
.max_cmdline_length = 256,
#if CONFIG_LOG_COLORS
.hint_color = atoi(LOG_COLOR_CYAN)
#endif
};
ESP_ERROR_CHECK( esp_console_init(&console_config) );
/* Configure linenoise line completion library */
/* Enable multiline editing. If not set, long commands will scroll within
* single line.
*/
linenoiseSetMultiLine(1);
/* Tell linenoise where to get command completions and hints */
linenoiseSetCompletionCallback(&esp_console_get_completion);
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
/* Set command history size */
linenoiseHistorySetMaxLen(100);
#if CONFIG_STORE_HISTORY
/* Load command history from filesystem */
linenoiseHistoryLoad(HISTORY_PATH);
#endif
}
int luaadd (lua_State* L, int x, int y )
{
int sum;
/* the function name */
lua_getglobal(L, "add");
/* the first argument */
lua_pushnumber(L, x);
/* the second argument */
lua_pushnumber(L, y);
/* call the function with 2 arguments, return 1 result */
lua_call(L, 2, 1);
/* get the result */
sum = (int)lua_tointeger(L, -1);
lua_pop(L, 1);
return sum;
}
void app_main()
{
initialize_nvs();
#if CONFIG_STORE_HISTORY
initialize_filesystem();
#endif
initialize_console();
/* initialize Lua */
lua_State* L = luaL_newstate();
luaL_openlibs(L);
openlibs(L);
luaopen_base(L); /* opens the basic library */
luaopen_table(L); /* opens the table library */
luaopen_io(L); /* opens the I/O library */
luaopen_string(L); /* opens the string lib. */
luaopen_math(L); /* opens the math lib. */
/* load Lua file */
if (luaL_loadfile(L, "add.lua")){
printf("Error loading file: %s", lua_tostring(L, -1));
}
/* call the add function */
int sum;
sum = luaadd(L, 10, 15 );
/* print the result */
printf( "The sum is %d\n", sum );
/* cleanup Lua */
lua_close(L);
/* print 'Finished' to console */
printf("Finished");
}
Когда я сейчас прошил это на моем ESP32, я получаю следующее сообщение:
Ошибка загрузки файла: невозможно открыть add.lua: такого файла нет или
directoryPANIC: незащищенная ошибка при вызове Lua API (попытка вызова
нулевое значение) abort () был вызван на ПК 0x4016b808 на ядре 0
Вы знаете, как решить проблему? Мой файл "add.lua" находится в том же каталоге, что и файл C.