Fixed LN de-init and re-init, added testing REPL.
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
d4f9291ad1
commit
af888fb6dd
|
@ -2,7 +2,7 @@ BasedOnStyle: Google
|
|||
IndentWidth: 4
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AlignConsecutiveDeclarations: Consecutive
|
||||
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
|
|
|
@ -62,6 +62,7 @@ set(TARGET_SOURCES
|
|||
"board/peripherals.c"
|
||||
"board/pin_mux.c"
|
||||
"lib/linenoise/linenoise.c"
|
||||
"src/app_mrb_repl.c"
|
||||
"src/app_syscalls.c"
|
||||
"src/main.c"
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ set(TARGET_TOOLCHAIN_SIZE arm-none-eabi-size)
|
|||
|
||||
set(CMAKE_C_FLAGS_INIT "-mcpu=cortex-m33 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16")
|
||||
set(CMAKE_CXX_FLAGS_INIT "-mcpu=cortex-m33 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -u _printf_float -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments")
|
||||
|
||||
# Make CMake happy about those compilers
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
|
|
@ -103,7 +103,7 @@
|
|||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef APP_MRB_REPL_H
|
||||
#define APP_MRB_REPL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
int app_mrb_repl_init(void);
|
||||
int app_mrb_repl_deinit(void);
|
||||
int app_mrb_repl_exec(bool *exit);
|
||||
|
||||
#endif // APP_MRB_REPL_H
|
|
@ -124,7 +124,6 @@ static linenoiseFreeHintsCallback *freeHintsCallback = NULL;
|
|||
|
||||
static int maskmode = 0; /* Show "***" instead of input. For passwords. */
|
||||
static int mlmode = 0; /* Multi line mode. Default is single line. */
|
||||
static int atexit_registered = 0; /* Register atexit just 1 time. */
|
||||
static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
|
||||
static int history_len = 0;
|
||||
static char **history = NULL;
|
||||
|
@ -169,8 +168,6 @@ enum KEY_ACTION{
|
|||
BACKSPACE = 127 /* Backspace */
|
||||
};
|
||||
|
||||
static void linenoiseAtExit(void);
|
||||
int linenoiseHistoryAdd(const char *line);
|
||||
static void refreshLine(struct linenoiseState *l);
|
||||
|
||||
/* Debugging macro. */
|
||||
|
@ -1051,11 +1048,13 @@ static void freeHistory(void) {
|
|||
for (j = 0; j < history_len; j++)
|
||||
free(history[j]);
|
||||
free(history);
|
||||
|
||||
history = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* At exit we'll try to fix the terminal to the initial conditions. */
|
||||
static void linenoiseAtExit(void) {
|
||||
void linenoiseAtExit(void) {
|
||||
freeHistory();
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ void linenoiseSetMultiLine(int ml);
|
|||
void linenoisePrintKeyCodes(void);
|
||||
void linenoiseMaskModeEnable(void);
|
||||
void linenoiseMaskModeDisable(void);
|
||||
void linenoiseAtExit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#include <malloc.h>
|
||||
|
||||
/* FreeRTOS */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* LN */
|
||||
#include "linenoise.h"
|
||||
|
||||
/* mruby */
|
||||
#include "mruby.h"
|
||||
#include "mruby/compile.h"
|
||||
|
||||
/* Private */
|
||||
#include "app_mrb_repl.h"
|
||||
|
||||
static mrb_state *mrb;
|
||||
static mrbc_context *cxt;
|
||||
static struct mrb_parser_state *parser_state;
|
||||
|
||||
static char *prompt_str;
|
||||
|
||||
#define APP_B_TO_KF(x) ((float)x / 1024.0f)
|
||||
|
||||
static void app_mrb_repl_heap_usage(uint32_t *used, uint32_t *total) {
|
||||
struct mallinfo m_info = mallinfo();
|
||||
|
||||
*used = m_info.uordblks;
|
||||
*total = m_info.fordblks + m_info.uordblks;
|
||||
}
|
||||
|
||||
int app_mrb_repl_init(void) {
|
||||
prompt_str = malloc(64);
|
||||
if (prompt_str == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mrb = mrb_open();
|
||||
cxt = mrbc_context_new(mrb);
|
||||
|
||||
mrb_show_version(mrb);
|
||||
mrb_show_copyright(mrb);
|
||||
|
||||
char mrb_code[] = "name = 'LPCXpresso55S69'\nputs \"Greetings #{name}, from MRuby #{RUBY_VERSION}.\"";
|
||||
|
||||
parser_state = mrb_parse_string(mrb, mrb_code, cxt);
|
||||
|
||||
mrb_load_exec(mrb, parser_state, cxt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_mrb_repl_deinit(void) {
|
||||
linenoiseAtExit();
|
||||
|
||||
free(prompt_str);
|
||||
|
||||
mrbc_cleanup_local_variables(mrb, cxt);
|
||||
mrbc_context_free(mrb, cxt);
|
||||
mrb_close(mrb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int app_mrb_repl_exec(bool *exit) {
|
||||
char *line;
|
||||
uint32_t heap_used, heap_total;
|
||||
|
||||
app_mrb_repl_heap_usage(&heap_used, &heap_total);
|
||||
snprintf(prompt_str, 64, "[%4.02lfkiB/%4.02lfkiB](irb)> ", APP_B_TO_KF(heap_used), APP_B_TO_KF(heap_total));
|
||||
|
||||
line = linenoise(prompt_str);
|
||||
|
||||
if(line == NULL) {
|
||||
*exit = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
linenoiseHistoryAdd(line);
|
||||
printf("You entered: %s\n", line);
|
||||
free(line);
|
||||
|
||||
*exit = false;
|
||||
return 0;
|
||||
}
|
|
@ -170,7 +170,7 @@ int _read(int file, char *ptr, int len) {
|
|||
}
|
||||
|
||||
int _write(int file, char *buf, int len) {
|
||||
if (file != STDOUT_FILENO) {
|
||||
if (file != STDOUT_FILENO && file != STDERR_FILENO) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
92
src/main.c
92
src/main.c
|
@ -1,22 +1,18 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/* Board */
|
||||
#include "board.h"
|
||||
#include "clock_config.h"
|
||||
#include "peripherals.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
/* mRuby */
|
||||
#include "mruby.h"
|
||||
#include "mruby/compile.h"
|
||||
|
||||
/* FreeRTOS */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* LineNoise */
|
||||
#include "linenoise.h"
|
||||
|
||||
/* App */
|
||||
#include "app_syscalls.h"
|
||||
#include "app_mrb_repl.h"
|
||||
|
||||
#ifndef APP_LOG_SUCCESSFUL_ALLOC
|
||||
#define APP_LOG_SUCCESSFUL_ALLOC false
|
||||
|
@ -33,7 +29,7 @@ int main(void) {
|
|||
goto dead_loop;
|
||||
}
|
||||
|
||||
if (xTaskCreate(app_mrb_runtime_task, "MRB_RT", 1536, NULL, 2, NULL) != pdPASS) {
|
||||
if (xTaskCreate(app_mrb_runtime_task, "MRB_RT", 3072, NULL, 2, NULL) != pdPASS) {
|
||||
goto dead_loop;
|
||||
}
|
||||
|
||||
|
@ -45,72 +41,32 @@ dead_loop:
|
|||
}
|
||||
}
|
||||
|
||||
static void app_mrb_alloc_fail_hook(void) {
|
||||
static void app_mrb_runtime_task(void *parameters) {
|
||||
bool exit_repl = false;
|
||||
|
||||
for (;;) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
static void *app_mrb_allocf(mrb_state *mrb, void *ptr, size_t len, void *user) {
|
||||
void *res = realloc(ptr, len);
|
||||
|
||||
if (ptr == NULL) {
|
||||
if (res == NULL) {
|
||||
printf("[ALLOC] malloc() failed, size: %d\n", len);
|
||||
app_mrb_alloc_fail_hook();
|
||||
} else {
|
||||
#if APP_LOG_SUCCESSFUL_ALLOC
|
||||
printf("[ALLOC] malloced %d bytes to ptr %p\n", len, res);
|
||||
#endif
|
||||
if(app_mrb_repl_init() != 0){
|
||||
printf("Failed to initialize mruby REPL engine.\n");
|
||||
goto task_fail;
|
||||
}
|
||||
} else {
|
||||
if (len == 0) {
|
||||
#if APP_LOG_SUCCESSFUL_ALLOC
|
||||
printf("[ALLOC] freed ptr %p\n", ptr);
|
||||
#endif
|
||||
} else {
|
||||
if (res == NULL) {
|
||||
printf("[ALLOC] malloc-copy-free failed, orig ptr: %p, new size: %d\n", ptr, len);
|
||||
app_mrb_alloc_fail_hook();
|
||||
} else {
|
||||
#if APP_LOG_SUCCESSFUL_ALLOC
|
||||
printf("[ALLOC] malloc-copy-free done, orig ptr: %p, new size: %d, new ptr: %p\n", ptr, len, res);
|
||||
#endif
|
||||
|
||||
while(!exit_repl) {
|
||||
if(app_mrb_repl_exec(&exit_repl) != 0) {
|
||||
printf("REPL execution failed.\n");
|
||||
|
||||
goto deinit_fail;
|
||||
}
|
||||
}
|
||||
|
||||
if(app_mrb_repl_deinit() != 0) {
|
||||
printf("Failed to deinitialize murby REPL engine.\n");
|
||||
goto task_fail;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void app_mrb_runtime_task(void *parameters) {
|
||||
mrb_state *mrb = mrb_open_allocf(app_mrb_allocf, NULL);
|
||||
mrbc_context *cxt = mrbc_context_new(mrb);
|
||||
|
||||
mrb_show_version(mrb);
|
||||
mrb_show_copyright(mrb);
|
||||
|
||||
char mrb_code[] = "name = 'LPCXpresso55S69'\nputs \"Greetings #{name}, from MRuby #{RUBY_VERSION}.\"";
|
||||
|
||||
struct mrb_parser_state *parser_state = mrb_parse_string(mrb, mrb_code, cxt);
|
||||
|
||||
mrb_load_exec(mrb, parser_state, cxt);
|
||||
|
||||
char *line;
|
||||
|
||||
while ((line = linenoise("hello> ")) != NULL) {
|
||||
linenoiseHistoryAdd(line);
|
||||
printf("You entered: %s\n", line);
|
||||
free(line);
|
||||
}
|
||||
|
||||
printf("REPL thread received ^D, cleaning up...\n");
|
||||
|
||||
/* User pressed ^D */
|
||||
|
||||
mrbc_cleanup_local_variables(mrb, cxt);
|
||||
mrbc_context_free(mrb, cxt);
|
||||
mrb_close(mrb);
|
||||
deinit_fail:
|
||||
app_mrb_repl_deinit();
|
||||
|
||||
task_fail:
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue