2022-01-13 05:50:19 -08:00
|
|
|
/*
|
|
|
|
Copyright 2022 Benjamin Vedder benjamin@vedder.se
|
|
|
|
Copyright 2022 Joel Svensson svenssonjoel@yahoo.se
|
|
|
|
|
|
|
|
This file is part of the VESC firmware.
|
|
|
|
|
|
|
|
The VESC firmware is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
The VESC firmware is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "lispif.h"
|
|
|
|
#include "commands.h"
|
|
|
|
#include "terminal.h"
|
|
|
|
#include "flash_helper.h"
|
2022-01-28 18:36:34 -08:00
|
|
|
#include "buffer.h"
|
|
|
|
#include "timeout.h"
|
2022-01-13 05:50:19 -08:00
|
|
|
#include "lispbm.h"
|
2022-09-18 13:47:50 -07:00
|
|
|
#include "mempools.h"
|
2023-04-02 10:10:11 -07:00
|
|
|
#include "stm32f4xx_conf.h"
|
2023-08-03 11:44:43 -07:00
|
|
|
#include "lbm_prof.h"
|
2023-08-16 13:09:29 -07:00
|
|
|
#include "utils.h"
|
2023-08-03 11:44:43 -07:00
|
|
|
|
|
|
|
#define HEAP_SIZE (2048 + 256 + 160)
|
|
|
|
#define LISP_MEM_SIZE LBM_MEMORY_SIZE_16K
|
|
|
|
#define LISP_MEM_BITMAP_SIZE LBM_MEMORY_BITMAP_SIZE_16K
|
|
|
|
#define GC_STACK_SIZE 160
|
|
|
|
#define PRINT_STACK_SIZE 128
|
2023-08-17 03:28:24 -07:00
|
|
|
#define EXTENSION_STORAGE_SIZE 270
|
2023-08-03 11:44:43 -07:00
|
|
|
#define VARIABLE_STORAGE_SIZE 50
|
|
|
|
#define EXT_LOAD_CALLBACK_LEN 20
|
|
|
|
#define PROF_DATA_NUM 30
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-01-21 01:52:56 -08:00
|
|
|
__attribute__((section(".ram4"))) static lbm_cons_t heap[HEAP_SIZE] __attribute__ ((aligned (8)));
|
2022-01-18 11:31:24 -08:00
|
|
|
static uint32_t memory_array[LISP_MEM_SIZE];
|
2022-11-17 01:03:35 -08:00
|
|
|
static uint32_t bitmap_array[LISP_MEM_BITMAP_SIZE];
|
|
|
|
static uint32_t gc_stack_storage[GC_STACK_SIZE];
|
2022-05-05 10:50:22 -07:00
|
|
|
__attribute__((section(".ram4"))) static uint32_t print_stack_storage[PRINT_STACK_SIZE];
|
|
|
|
__attribute__((section(".ram4"))) static extension_fptr extension_storage[EXTENSION_STORAGE_SIZE];
|
|
|
|
__attribute__((section(".ram4"))) static lbm_value variable_storage[VARIABLE_STORAGE_SIZE];
|
2023-08-03 11:44:43 -07:00
|
|
|
static lbm_prof_t prof_data[PROF_DATA_NUM];
|
2023-08-07 13:07:08 -07:00
|
|
|
static volatile bool prof_running = false;
|
2022-02-13 06:18:22 -08:00
|
|
|
|
2022-09-18 13:47:50 -07:00
|
|
|
static lbm_string_channel_state_t string_tok_state;
|
|
|
|
static lbm_char_channel_t string_tok;
|
|
|
|
static lbm_buffered_channel_state_t buffered_tok_state;
|
|
|
|
static lbm_char_channel_t buffered_string_tok;
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2023-04-05 07:44:33 -07:00
|
|
|
static lbm_const_heap_t const_heap;
|
2023-04-02 10:10:11 -07:00
|
|
|
static lbm_uint *const_heap_ptr = 0;
|
|
|
|
|
2022-01-13 05:50:19 -08:00
|
|
|
static thread_t *eval_tp = 0;
|
2022-01-28 18:36:34 -08:00
|
|
|
static THD_FUNCTION(eval_thread, arg);
|
2022-01-13 08:50:27 -08:00
|
|
|
static THD_WORKING_AREA(eval_thread_wa, 2048);
|
2022-01-13 05:50:19 -08:00
|
|
|
static bool lisp_thd_running = false;
|
2022-11-04 11:46:36 -07:00
|
|
|
static mutex_t lbm_mutex;
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-03-01 03:07:27 -08:00
|
|
|
static int repl_cid = -1;
|
2023-08-16 13:09:29 -07:00
|
|
|
static volatile systime_t repl_time = 0;
|
2023-02-20 02:15:32 -08:00
|
|
|
static int restart_cnt = 0;
|
2022-03-01 03:07:27 -08:00
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
// Private functions
|
|
|
|
static uint32_t timestamp_callback(void);
|
|
|
|
static void sleep_callback(uint32_t us);
|
2023-04-02 10:10:11 -07:00
|
|
|
static bool const_heap_write(lbm_uint ix, lbm_uint w);
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2023-07-29 11:01:14 -07:00
|
|
|
// Extension load callbacks
|
|
|
|
void(*ext_load_callbacks[EXT_LOAD_CALLBACK_LEN])(void) = {0};
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
void lispif_init(void) {
|
|
|
|
// Do not attempt to start lisp after a watchdog reset, in case lisp
|
|
|
|
// was the cause of it.
|
|
|
|
// TODO: Anything else to check?
|
|
|
|
if (!timeout_had_IWDG_reset() && terminal_get_first_fault() != FAULT_CODE_BOOTING_FROM_WATCHDOG_RESET) {
|
2022-07-25 05:26:21 -07:00
|
|
|
lispif_restart(false, true);
|
2022-01-28 18:36:34 -08:00
|
|
|
}
|
2022-09-04 13:18:15 -07:00
|
|
|
|
|
|
|
lbm_set_eval_step_quota(50);
|
2022-11-04 11:46:36 -07:00
|
|
|
|
|
|
|
chMtxObjectInit(&lbm_mutex);
|
|
|
|
}
|
|
|
|
|
2023-02-20 02:15:32 -08:00
|
|
|
int lispif_get_restart_cnt(void) {
|
|
|
|
return restart_cnt;
|
|
|
|
}
|
|
|
|
|
2022-11-04 11:46:36 -07:00
|
|
|
void lispif_lock_lbm(void) {
|
|
|
|
chMtxLock(&lbm_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lispif_unlock_lbm(void) {
|
|
|
|
chMtxUnlock(&lbm_mutex);
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|
|
|
|
|
2022-03-01 15:50:01 -08:00
|
|
|
static void print_ctx_info(eval_context_t *ctx, void *arg1, void *arg2) {
|
|
|
|
(void) arg1;
|
|
|
|
(void) arg2;
|
|
|
|
|
|
|
|
char output[128];
|
|
|
|
|
|
|
|
int print_ret = lbm_print_value(output, sizeof(output), ctx->r);
|
|
|
|
|
|
|
|
commands_printf_lisp("--------------------------------");
|
|
|
|
commands_printf_lisp("ContextID: %u", ctx->id);
|
|
|
|
commands_printf_lisp("Stack SP: %u", ctx->K.sp);
|
|
|
|
commands_printf_lisp("Stack SP max: %u", ctx->K.max_sp);
|
|
|
|
if (print_ret) {
|
|
|
|
commands_printf_lisp("Value: %s", output);
|
|
|
|
} else {
|
|
|
|
commands_printf_lisp("Error: %s", output);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sym_it(const char *str) {
|
|
|
|
commands_printf_lisp("%s", str);
|
|
|
|
}
|
|
|
|
|
2023-08-03 11:44:43 -07:00
|
|
|
static void prof_thd_wrapper(void *v) {
|
|
|
|
(void)v;
|
2023-08-07 13:07:08 -07:00
|
|
|
|
|
|
|
while (prof_running) {
|
|
|
|
lbm_prof_sample();
|
|
|
|
chThdSleepMicroseconds(200);
|
|
|
|
}
|
2023-08-03 11:44:43 -07:00
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
void lispif_process_cmd(unsigned char *data, unsigned int len,
|
|
|
|
void(*reply_func)(unsigned char *data, unsigned int len)) {
|
|
|
|
COMM_PACKET_ID packet_id;
|
|
|
|
|
|
|
|
packet_id = data[0];
|
|
|
|
data++;
|
|
|
|
len--;
|
|
|
|
|
|
|
|
switch (packet_id) {
|
|
|
|
case COMM_LISP_SET_RUNNING: {
|
|
|
|
bool ok = false;
|
|
|
|
bool running = data[0];
|
2022-02-03 08:31:02 -08:00
|
|
|
lispif_disable_all_events();
|
2022-01-28 18:36:34 -08:00
|
|
|
|
|
|
|
if (!running) {
|
2022-09-23 04:51:21 -07:00
|
|
|
int timeout_cnt = 2000;
|
2022-01-28 18:36:34 -08:00
|
|
|
lbm_pause_eval();
|
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED && timeout_cnt > 0) {
|
2022-09-23 04:51:21 -07:00
|
|
|
chThdSleepMilliseconds(1);
|
2022-01-28 18:36:34 -08:00
|
|
|
timeout_cnt--;
|
|
|
|
}
|
|
|
|
ok = timeout_cnt > 0;
|
|
|
|
} else {
|
2022-07-25 05:26:21 -07:00
|
|
|
ok = lispif_restart(true, true);
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
int32_t ind = 0;
|
|
|
|
uint8_t send_buffer[50];
|
|
|
|
send_buffer[ind++] = packet_id;
|
|
|
|
send_buffer[ind++] = ok;
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
} break;
|
|
|
|
|
|
|
|
|
|
|
|
case COMM_LISP_GET_STATS: {
|
|
|
|
float cpu_use = 0.0;
|
|
|
|
float heap_use = 0.0;
|
|
|
|
float mem_use = 0.0;
|
|
|
|
|
|
|
|
static systime_t time_last = 0;
|
|
|
|
if (eval_tp) {
|
|
|
|
cpu_use = 100.0 * (float)eval_tp->p_time / (float)(chVTGetSystemTimeX() - time_last);
|
|
|
|
time_last = chVTGetSystemTimeX();
|
|
|
|
eval_tp->p_time = 0;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-04-12 03:49:29 -07:00
|
|
|
if (lbm_heap_state.gc_num > 0) {
|
|
|
|
heap_use = 100.0 * (float)(HEAP_SIZE - lbm_heap_state.gc_last_free) / (float)HEAP_SIZE;
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
mem_use = 100.0 * (float)(lbm_memory_num_words() - lbm_memory_num_free()) / (float)lbm_memory_num_words();
|
|
|
|
|
2022-09-18 13:47:50 -07:00
|
|
|
uint8_t *send_buffer_global = mempools_get_packet_buffer();
|
2022-01-28 18:36:34 -08:00
|
|
|
int32_t ind = 0;
|
|
|
|
|
|
|
|
send_buffer_global[ind++] = packet_id;
|
|
|
|
buffer_append_float16(send_buffer_global, cpu_use, 1e2, &ind);
|
|
|
|
buffer_append_float16(send_buffer_global, heap_use, 1e2, &ind);
|
|
|
|
buffer_append_float16(send_buffer_global, mem_use, 1e2, &ind);
|
|
|
|
|
2023-02-07 12:40:26 -08:00
|
|
|
// Stack. Currently unused
|
|
|
|
buffer_append_float16(send_buffer_global, 0, 1e2, &ind);
|
|
|
|
|
|
|
|
// Result. Currently unused
|
2022-12-27 03:11:31 -08:00
|
|
|
send_buffer_global[ind++] = '\0';
|
2022-01-29 12:26:15 -08:00
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
lbm_value curr = *lbm_get_env_ptr();
|
2022-03-25 09:11:43 -07:00
|
|
|
while (lbm_type_of(curr) == LBM_TYPE_CONS) {
|
2022-01-28 18:36:34 -08:00
|
|
|
lbm_value key_val = lbm_car(curr);
|
2022-03-25 09:11:43 -07:00
|
|
|
if (lbm_type_of(lbm_car(key_val)) == LBM_TYPE_SYMBOL && lbm_is_number(lbm_cdr(key_val))) {
|
2022-01-28 18:36:34 -08:00
|
|
|
const char *name = lbm_get_name_by_symbol(lbm_dec_sym(lbm_car(key_val)));
|
|
|
|
strcpy((char*)(send_buffer_global + ind), name);
|
|
|
|
ind += strlen(name) + 1;
|
2022-03-25 09:11:43 -07:00
|
|
|
buffer_append_float32_auto(send_buffer_global, lbm_dec_as_float(lbm_cdr(key_val)), &ind);
|
2022-01-28 18:36:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ind > 300) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
curr = lbm_cdr(curr);
|
|
|
|
}
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-02-16 15:49:11 -08:00
|
|
|
for (int i = 0; i < lbm_get_num_variables(); i ++) {
|
|
|
|
const char *name = lbm_get_variable_name_by_index(i);
|
|
|
|
const lbm_value var = lbm_get_variable_by_index(i);
|
|
|
|
if (lbm_is_number(var) && name) {
|
|
|
|
strcpy((char*)(send_buffer_global + ind), name);
|
|
|
|
ind += strlen(name) + 1;
|
2022-03-25 09:11:43 -07:00
|
|
|
buffer_append_float32_auto(send_buffer_global, lbm_dec_as_float(var), &ind);
|
2022-03-07 09:58:17 -08:00
|
|
|
|
|
|
|
if (ind > 300) {
|
|
|
|
break;
|
|
|
|
}
|
2022-02-16 15:49:11 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
reply_func(send_buffer_global, ind);
|
2022-09-18 13:47:50 -07:00
|
|
|
mempools_free_packet_buffer(send_buffer_global);
|
2022-01-28 18:36:34 -08:00
|
|
|
} break;
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-03-01 03:07:27 -08:00
|
|
|
case COMM_LISP_REPL_CMD: {
|
2023-08-16 13:09:29 -07:00
|
|
|
if (UTILS_AGE_S(repl_time) <= 0.5) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-01 04:08:25 -08:00
|
|
|
if (!lisp_thd_running) {
|
2022-07-25 05:26:21 -07:00
|
|
|
lispif_restart(true, false);
|
2022-03-01 04:08:25 -08:00
|
|
|
}
|
|
|
|
|
2022-03-01 03:07:27 -08:00
|
|
|
if (lisp_thd_running) {
|
2022-11-04 11:46:36 -07:00
|
|
|
lispif_lock_lbm();
|
2022-03-01 15:50:01 -08:00
|
|
|
char *str = (char*)data;
|
|
|
|
|
|
|
|
if (len <= 1) {
|
2022-03-03 10:38:51 -08:00
|
|
|
commands_printf_lisp(">");
|
2023-08-03 11:44:43 -07:00
|
|
|
} else if (strncmp(str, ":help", 5) == 0) {
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp("== Special Commands ==");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":help\n"
|
|
|
|
" Print this help text");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":info\n"
|
|
|
|
" Print info about memory usage, allocated arrays and garbage collection");
|
2023-08-03 11:44:43 -07:00
|
|
|
commands_printf_lisp(
|
|
|
|
":prof start\n"
|
|
|
|
" Start profiler");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":prof stop\n"
|
|
|
|
" Stop profiler");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":prof report\n"
|
|
|
|
" Print profiler report");
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp(
|
|
|
|
":env\n"
|
|
|
|
" Print current environment and variables");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":ctxs\n"
|
|
|
|
" Print context (threads) info");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":symbols\n"
|
|
|
|
" Print symbol names");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":reset\n"
|
|
|
|
" Reset LBM");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":pause\n"
|
|
|
|
" Pause LBM");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":continue\n"
|
|
|
|
" Continue running LBM");
|
2022-04-03 03:40:27 -07:00
|
|
|
commands_printf_lisp(
|
|
|
|
":undef <symbol_name>\n"
|
|
|
|
" Undefine symbol");
|
|
|
|
commands_printf_lisp(
|
|
|
|
":verb\n"
|
|
|
|
" Toggle verbose error messages");
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp(" ");
|
|
|
|
commands_printf_lisp("Anything else will be evaluated as an expression in LBM.");
|
|
|
|
commands_printf_lisp(" ");
|
2023-08-03 11:44:43 -07:00
|
|
|
} else if (strncmp(str, ":info", 5) == 0) {
|
2022-12-18 15:14:57 -08:00
|
|
|
commands_printf_lisp("--(LISP HEAP)--\n");
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp("Heap size: %u Bytes\n", HEAP_SIZE * 8);
|
|
|
|
commands_printf_lisp("Used cons cells: %d\n", HEAP_SIZE - lbm_heap_num_free());
|
|
|
|
commands_printf_lisp("Free cons cells: %d\n", lbm_heap_num_free());
|
2022-04-12 03:49:29 -07:00
|
|
|
commands_printf_lisp("GC counter: %d\n", lbm_heap_state.gc_num);
|
|
|
|
commands_printf_lisp("Recovered: %d\n", lbm_heap_state.gc_recovered);
|
|
|
|
commands_printf_lisp("Recovered arrays: %u\n", lbm_heap_state.gc_recovered_arrays);
|
|
|
|
commands_printf_lisp("Marked: %d\n", lbm_heap_state.gc_marked);
|
2022-12-18 15:14:57 -08:00
|
|
|
commands_printf_lisp("--(Symbol and Array memory)--\n");
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp("Memory size: %u Words\n", lbm_memory_num_words());
|
|
|
|
commands_printf_lisp("Memory free: %u Words\n", lbm_memory_num_free());
|
2022-04-12 03:49:29 -07:00
|
|
|
commands_printf_lisp("Allocated arrays: %u\n", lbm_heap_state.num_alloc_arrays);
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp("Symbol table size: %u Bytes\n", lbm_get_symbol_table_size());
|
2023-07-05 06:03:55 -07:00
|
|
|
commands_printf_lisp("Symbol table size flash: %u Bytes\n", lbm_get_symbol_table_size_flash());
|
|
|
|
commands_printf_lisp("Symbol name size: %u Bytes\n", lbm_get_symbol_table_size_names());
|
|
|
|
commands_printf_lisp("Symbol name size flash: %u Bytes\n", lbm_get_symbol_table_size_names_flash());
|
2022-12-18 15:14:57 -08:00
|
|
|
commands_printf_lisp("Extensions: %u, max %u\n", lbm_get_num_extensions(), lbm_get_max_extensions());
|
2023-04-02 10:10:11 -07:00
|
|
|
commands_printf_lisp("--(Flash)--\n");
|
2023-04-05 06:39:55 -07:00
|
|
|
commands_printf_lisp("Size: %u Bytes\n", const_heap.size);
|
2023-04-02 10:10:11 -07:00
|
|
|
commands_printf_lisp("Used cells: %d\n", const_heap.next);
|
|
|
|
commands_printf_lisp("Free cells: %d\n", const_heap.size / 4 - const_heap.next);
|
2023-08-03 11:44:43 -07:00
|
|
|
} else if (strncmp(str, ":prof start", 11) == 0) {
|
2023-08-07 13:07:08 -07:00
|
|
|
if (prof_running) {
|
|
|
|
lbm_prof_init(prof_data, PROF_DATA_NUM);
|
2023-08-03 11:44:43 -07:00
|
|
|
commands_printf_lisp("Profiler restarted\n");
|
|
|
|
} else {
|
2023-08-07 13:07:08 -07:00
|
|
|
lbm_prof_init(prof_data, PROF_DATA_NUM);
|
|
|
|
prof_running = true;
|
2023-08-03 11:44:43 -07:00
|
|
|
if (lispif_spawn(prof_thd_wrapper, 1024, "LBM Profiler", NULL)) {
|
|
|
|
commands_printf_lisp("Profiler started\n");
|
|
|
|
} else {
|
|
|
|
commands_printf_lisp("Could not start profiler, most likely out of memory\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (strncmp(str, ":prof stop", 10) == 0) {
|
|
|
|
commands_printf_lisp("Profiler stopped. Issue command ':prof report' for statistics\n");
|
2023-08-07 13:07:08 -07:00
|
|
|
prof_running = false;
|
2023-08-03 11:44:43 -07:00
|
|
|
} else if (strncmp(str, ":prof report", 12) == 0) {
|
|
|
|
lbm_uint num_sleep = lbm_prof_get_num_sleep_samples();
|
2023-08-07 13:07:08 -07:00
|
|
|
lbm_uint num_system = lbm_prof_get_num_system_samples();
|
2023-08-03 11:44:43 -07:00
|
|
|
lbm_uint tot_samples = lbm_prof_get_num_samples();
|
|
|
|
lbm_uint tot_gc = 0;
|
|
|
|
commands_printf_lisp("CID\tName\tSamples\t%%Load\t%%GC");
|
|
|
|
for (int i = 0; i < PROF_DATA_NUM; i ++) {
|
|
|
|
if (prof_data[i].cid == -1) break;
|
|
|
|
tot_gc += prof_data[i].gc_count;
|
|
|
|
commands_printf_lisp("%d\t%s\t%u\t%.3f\t%.3f",
|
|
|
|
prof_data[i].cid,
|
|
|
|
prof_data[i].name,
|
|
|
|
prof_data[i].count,
|
|
|
|
(double)(100.0 * ((float)prof_data[i].count) / (float) tot_samples),
|
|
|
|
(double)(100.0 * ((float)prof_data[i].gc_count) / (float)prof_data[i].count));
|
|
|
|
}
|
|
|
|
commands_printf_lisp(" ");
|
2023-08-07 13:07:08 -07:00
|
|
|
commands_printf_lisp("GC:\t%u\t%f%%\n", tot_gc, (double)(100.0 * ((float)tot_gc / (float)tot_samples)));
|
|
|
|
commands_printf_lisp("System:\t%u\t%f%%\n", num_system, (double)(100.0 * ((float)num_system / (float)tot_samples)));
|
|
|
|
commands_printf_lisp("Sleep:\t%u\t%f%%\n", num_sleep, (double)(100.0 * ((float)num_sleep / (float)tot_samples)));
|
|
|
|
commands_printf_lisp("Total:\t%u samples\n", tot_samples);
|
2022-03-01 15:50:01 -08:00
|
|
|
} else if (strncmp(str, ":env", 4) == 0) {
|
|
|
|
lbm_value curr = *lbm_get_env_ptr();
|
|
|
|
char output[128];
|
|
|
|
|
|
|
|
commands_printf_lisp("Environment:\n");
|
2022-03-25 09:11:43 -07:00
|
|
|
while (lbm_type_of(curr) == LBM_TYPE_CONS) {
|
2022-03-01 15:50:01 -08:00
|
|
|
lbm_print_value(output, sizeof(output), lbm_car(curr));
|
|
|
|
curr = lbm_cdr(curr);
|
2023-04-02 10:46:20 -07:00
|
|
|
commands_printf_lisp(" %s", output);
|
2022-03-01 15:50:01 -08:00
|
|
|
}
|
2023-04-02 10:46:20 -07:00
|
|
|
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp("Variables:");
|
|
|
|
for (int i = 0; i < lbm_get_num_variables(); i ++) {
|
|
|
|
const char *name = lbm_get_variable_name_by_index(i);
|
2023-04-02 10:46:20 -07:00
|
|
|
lbm_print_value(output, sizeof(output), lbm_get_variable_by_index(i));
|
2022-03-01 15:50:01 -08:00
|
|
|
commands_printf_lisp(" %s = %s", name ? name : "error", output);
|
|
|
|
}
|
|
|
|
} else if (strncmp(str, ":ctxs", 5) == 0) {
|
|
|
|
commands_printf_lisp("****** Running contexts ******");
|
|
|
|
lbm_running_iterator(print_ctx_info, NULL, NULL);
|
|
|
|
commands_printf_lisp("****** Blocked contexts ******");
|
|
|
|
lbm_blocked_iterator(print_ctx_info, NULL, NULL);
|
|
|
|
} else if (strncmp(str, ":symbols", 8) == 0) {
|
|
|
|
lbm_symrepr_name_iterator(sym_it);
|
|
|
|
commands_printf_lisp(" ");
|
|
|
|
} else if (strncmp(str, ":reset", 6) == 0) {
|
2022-07-25 05:26:21 -07:00
|
|
|
commands_printf_lisp(lispif_restart(false, flash_helper_code_size(CODE_IND_LISP) > 0) ?
|
2022-03-01 15:50:01 -08:00
|
|
|
"Reset OK\n\n" : "Reset Failed\n\n");
|
|
|
|
} else if (strncmp(str, ":pause", 6) == 0) {
|
|
|
|
lbm_pause_eval_with_gc(30);
|
2023-04-02 10:10:11 -07:00
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED) {
|
2022-11-04 11:46:36 -07:00
|
|
|
lbm_pause_eval();
|
2022-09-23 04:51:21 -07:00
|
|
|
sleep_callback(1);
|
2022-03-01 15:50:01 -08:00
|
|
|
}
|
|
|
|
commands_printf_lisp("Evaluator paused\n");
|
|
|
|
} else if (strncmp(str, ":continue", 9) == 0) {
|
|
|
|
lbm_continue_eval();
|
|
|
|
} else if (strncmp(str, ":undef", 6) == 0) {
|
|
|
|
lbm_pause_eval();
|
|
|
|
while(lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED) {
|
2022-11-04 11:46:36 -07:00
|
|
|
lbm_pause_eval();
|
2022-09-23 04:51:21 -07:00
|
|
|
sleep_callback(1);
|
2022-03-01 15:50:01 -08:00
|
|
|
}
|
|
|
|
char *sym = str + 7;
|
|
|
|
commands_printf_lisp("undefining: %s", sym);
|
|
|
|
commands_printf_lisp("%s", lbm_undefine(sym) ? "Cleared bindings" : "No definition found");
|
2022-03-01 03:07:27 -08:00
|
|
|
lbm_continue_eval();
|
2022-04-03 03:40:27 -07:00
|
|
|
} else if (strncmp(str, ":verb", 5) == 0) {
|
|
|
|
static bool verbose_now = false;
|
|
|
|
verbose_now = !verbose_now;
|
|
|
|
lbm_set_verbose(verbose_now);
|
|
|
|
commands_printf_lisp("Verbose errors %s", verbose_now ? "Enabled" : "Disabled");
|
2022-03-01 03:07:27 -08:00
|
|
|
} else {
|
2022-03-01 15:50:01 -08:00
|
|
|
bool ok = true;
|
|
|
|
int timeout_cnt = 1000;
|
|
|
|
lbm_pause_eval_with_gc(30);
|
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED && timeout_cnt > 0) {
|
|
|
|
chThdSleep(5);
|
|
|
|
timeout_cnt--;
|
|
|
|
}
|
|
|
|
ok = timeout_cnt > 0;
|
|
|
|
|
|
|
|
if (ok) {
|
2022-09-18 13:47:50 -07:00
|
|
|
lbm_create_string_char_channel(&string_tok_state, &string_tok, (char*)data);
|
2023-04-05 08:37:49 -07:00
|
|
|
repl_cid = lbm_load_and_eval_expression(&string_tok);
|
|
|
|
lbm_continue_eval();
|
|
|
|
|
2022-12-02 09:50:00 -08:00
|
|
|
if (reply_func != NULL) {
|
2023-08-16 13:09:29 -07:00
|
|
|
repl_time = chVTGetSystemTimeX();
|
|
|
|
} else {
|
|
|
|
repl_cid = -1;
|
2022-12-02 09:50:00 -08:00
|
|
|
}
|
2022-03-01 15:50:01 -08:00
|
|
|
} else {
|
|
|
|
commands_printf_lisp("Could not pause");
|
|
|
|
}
|
2022-03-01 03:07:27 -08:00
|
|
|
}
|
2022-11-04 11:46:36 -07:00
|
|
|
lispif_unlock_lbm();
|
2022-03-01 03:07:27 -08:00
|
|
|
} else {
|
|
|
|
commands_printf_lisp("LispBM is not running");
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2022-09-18 13:47:50 -07:00
|
|
|
case COMM_LISP_STREAM_CODE: {
|
|
|
|
int32_t ind = 0;
|
|
|
|
int32_t offset = buffer_get_int32(data, &ind);
|
|
|
|
int32_t tot_len = buffer_get_int32(data, &ind);
|
|
|
|
int8_t restart = data[ind++];
|
|
|
|
|
|
|
|
static bool buffered_channel_created = false;
|
|
|
|
static int32_t offset_last = -1;
|
|
|
|
static int16_t result_last = -1;
|
|
|
|
|
|
|
|
if (offset == 0) {
|
|
|
|
if (!lisp_thd_running) {
|
|
|
|
lispif_restart(true, restart == 2 ? true : false);
|
|
|
|
buffered_channel_created = false;
|
|
|
|
} else if (restart == 1) {
|
|
|
|
lispif_restart(true, false);
|
|
|
|
buffered_channel_created = false;
|
|
|
|
} else if (restart == 2) {
|
|
|
|
lispif_restart(true, true);
|
|
|
|
buffered_channel_created = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t send_ind = 0;
|
|
|
|
uint8_t send_buffer[50];
|
|
|
|
send_buffer[send_ind++] = packet_id;
|
|
|
|
buffer_append_int32(send_buffer, offset, &send_ind);
|
|
|
|
|
|
|
|
if (offset_last == offset) {
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
offset_last = offset;
|
|
|
|
|
|
|
|
if (!lisp_thd_running) {
|
|
|
|
result_last = -1;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (offset == 0) {
|
|
|
|
if (buffered_channel_created) {
|
|
|
|
int timeout = 1500;
|
|
|
|
while (!buffered_tok_state.reader_closed) {
|
|
|
|
lbm_channel_writer_close(&buffered_string_tok);
|
|
|
|
chThdSleepMilliseconds(1);
|
|
|
|
timeout--;
|
|
|
|
if (timeout == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeout == 0) {
|
|
|
|
result_last = -2;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
commands_printf_lisp("Reader not closing");
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int timeout_cnt = 1000;
|
2022-11-05 02:02:13 -07:00
|
|
|
lispif_lock_lbm();
|
2022-09-18 13:47:50 -07:00
|
|
|
lbm_pause_eval_with_gc(30);
|
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED && timeout_cnt > 0) {
|
|
|
|
chThdSleep(5);
|
|
|
|
timeout_cnt--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeout_cnt == 0) {
|
2022-11-05 02:02:13 -07:00
|
|
|
lispif_unlock_lbm();
|
2022-09-18 13:47:50 -07:00
|
|
|
result_last = -3;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
commands_printf_lisp("Could not pause");
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lbm_create_buffered_char_channel(&buffered_tok_state, &buffered_string_tok);
|
|
|
|
|
2023-08-27 23:19:32 -07:00
|
|
|
if (lbm_load_and_eval_program(&buffered_string_tok, "repl") <= 0) {
|
2022-11-05 02:02:13 -07:00
|
|
|
lispif_unlock_lbm();
|
2022-09-18 13:47:50 -07:00
|
|
|
result_last = -4;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
commands_printf_lisp("Could not start eval");
|
|
|
|
reply_func(send_buffer, ind);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lbm_continue_eval();
|
|
|
|
buffered_channel_created = true;
|
2022-11-05 02:02:13 -07:00
|
|
|
lispif_unlock_lbm();
|
2022-09-18 13:47:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
int32_t written = 0;
|
|
|
|
int timeout = 1500;
|
|
|
|
while (ind < (int32_t)len) {
|
|
|
|
int ch_res = lbm_channel_write(&buffered_string_tok, (char)data[ind]);
|
|
|
|
|
|
|
|
if (ch_res == CHANNEL_SUCCESS) {
|
|
|
|
ind++;
|
|
|
|
written++;
|
|
|
|
timeout = 0;
|
|
|
|
} else if (ch_res == CHANNEL_READER_CLOSED) {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
chThdSleepMilliseconds(1);
|
|
|
|
timeout--;
|
|
|
|
if (timeout == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ind == (int32_t)len) {
|
|
|
|
if ((offset + written) == tot_len) {
|
|
|
|
lbm_channel_writer_close(&buffered_string_tok);
|
|
|
|
offset_last = -1;
|
|
|
|
commands_printf_lisp("Stream done, starting...");
|
|
|
|
}
|
|
|
|
|
|
|
|
result_last = 0;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
} else {
|
|
|
|
if (timeout == 0) {
|
|
|
|
result_last = -5;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
commands_printf_lisp("Stream timed out");
|
|
|
|
} else {
|
|
|
|
result_last = -6;
|
|
|
|
offset_last = -1;
|
|
|
|
buffer_append_int16(send_buffer, result_last, &send_ind);
|
|
|
|
commands_printf_lisp("Stream closed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
reply_func(send_buffer, send_ind);
|
|
|
|
} break;
|
|
|
|
|
2023-08-07 13:07:08 -07:00
|
|
|
case COMM_LISP_RMSG: {
|
|
|
|
lispif_process_rmsg(data[0], data + 1, len - 1);
|
|
|
|
} break;
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
default:
|
|
|
|
break;
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-01 03:07:27 -08:00
|
|
|
static void done_callback(eval_context_t *ctx) {
|
|
|
|
lbm_cid cid = ctx->id;
|
|
|
|
lbm_value t = ctx->r;
|
|
|
|
|
|
|
|
if (cid == repl_cid) {
|
2023-08-16 13:09:29 -07:00
|
|
|
if (UTILS_AGE_S(repl_time) < 0.5) {
|
|
|
|
char output[128];
|
|
|
|
lbm_print_value(output, sizeof(output), t);
|
|
|
|
commands_printf_lisp("> %s", output);
|
|
|
|
} else {
|
|
|
|
repl_cid = -1;
|
|
|
|
}
|
2022-03-01 03:07:27 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-25 05:26:21 -07:00
|
|
|
bool lispif_restart(bool print, bool load_code) {
|
2022-01-28 18:36:34 -08:00
|
|
|
bool res = false;
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2023-02-20 02:15:32 -08:00
|
|
|
restart_cnt++;
|
2023-08-07 13:07:08 -07:00
|
|
|
prof_running = false;
|
2022-05-11 13:10:42 -07:00
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
char *code_data = (char*)flash_helper_code_data(CODE_IND_LISP);
|
|
|
|
int32_t code_len = flash_helper_code_size(CODE_IND_LISP);
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-03-01 04:08:25 -08:00
|
|
|
if (!load_code || (code_data != 0 && code_len > 0)) {
|
2022-09-23 04:51:21 -07:00
|
|
|
lispif_disable_all_events();
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
if (!lisp_thd_running) {
|
2022-02-13 06:18:22 -08:00
|
|
|
lbm_init(heap, HEAP_SIZE,
|
|
|
|
gc_stack_storage, GC_STACK_SIZE,
|
2022-05-05 10:50:22 -07:00
|
|
|
memory_array, LISP_MEM_SIZE,
|
|
|
|
bitmap_array, LISP_MEM_BITMAP_SIZE,
|
2022-02-16 15:49:11 -08:00
|
|
|
print_stack_storage, PRINT_STACK_SIZE,
|
|
|
|
extension_storage, EXTENSION_STORAGE_SIZE);
|
|
|
|
lbm_variables_init(variable_storage, VARIABLE_STORAGE_SIZE);
|
2023-01-24 02:15:12 -08:00
|
|
|
lbm_eval_init_events(20);
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
lbm_set_timestamp_us_callback(timestamp_callback);
|
|
|
|
lbm_set_usleep_callback(sleep_callback);
|
2022-02-28 05:29:59 -08:00
|
|
|
lbm_set_printf_callback(commands_printf_lisp);
|
2022-03-01 03:07:27 -08:00
|
|
|
lbm_set_ctx_done_callback(done_callback);
|
2022-04-06 10:49:09 -07:00
|
|
|
chThdCreateStatic(eval_thread_wa, sizeof(eval_thread_wa), NORMALPRIO - 1, eval_thread, NULL);
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
lisp_thd_running = true;
|
|
|
|
} else {
|
|
|
|
lbm_pause_eval();
|
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED) {
|
2022-11-04 11:46:36 -07:00
|
|
|
lbm_pause_eval();
|
2022-09-23 04:51:21 -07:00
|
|
|
chThdSleepMilliseconds(1);
|
2022-01-28 18:36:34 -08:00
|
|
|
}
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-02-13 06:18:22 -08:00
|
|
|
lbm_init(heap, HEAP_SIZE,
|
|
|
|
gc_stack_storage, GC_STACK_SIZE,
|
2022-05-05 10:50:22 -07:00
|
|
|
memory_array, LISP_MEM_SIZE,
|
|
|
|
bitmap_array, LISP_MEM_BITMAP_SIZE,
|
2022-02-16 15:49:11 -08:00
|
|
|
print_stack_storage, PRINT_STACK_SIZE,
|
|
|
|
extension_storage, EXTENSION_STORAGE_SIZE);
|
|
|
|
lbm_variables_init(variable_storage, VARIABLE_STORAGE_SIZE);
|
2023-01-24 02:15:12 -08:00
|
|
|
lbm_eval_init_events(20);
|
2022-07-25 05:26:21 -07:00
|
|
|
}
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2022-07-25 05:26:21 -07:00
|
|
|
lbm_pause_eval();
|
|
|
|
while (lbm_get_eval_state() != EVAL_CPS_STATE_PAUSED) {
|
2022-11-04 11:46:36 -07:00
|
|
|
lbm_pause_eval();
|
2022-09-23 04:51:21 -07:00
|
|
|
chThdSleepMilliseconds(1);
|
2022-01-21 01:52:56 -08:00
|
|
|
}
|
2022-01-28 18:36:34 -08:00
|
|
|
|
2023-07-29 11:01:14 -07:00
|
|
|
// Load extensions
|
2022-01-28 18:36:34 -08:00
|
|
|
lispif_load_vesc_extensions();
|
2023-07-29 11:01:14 -07:00
|
|
|
for (int i = 0;i < EXT_LOAD_CALLBACK_LEN;i++) {
|
|
|
|
if (ext_load_callbacks[i] == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ext_load_callbacks[i]();
|
|
|
|
}
|
|
|
|
|
2022-02-23 13:56:30 -08:00
|
|
|
lbm_set_dynamic_load_callback(lispif_vesc_dynamic_loader);
|
2022-01-28 18:36:34 -08:00
|
|
|
|
2023-04-05 12:29:21 -07:00
|
|
|
int code_chars = 0;
|
|
|
|
if (code_data) {
|
|
|
|
code_chars = strnlen(code_data, code_len);
|
|
|
|
}
|
2022-11-15 01:37:43 -08:00
|
|
|
|
2023-04-14 13:46:26 -07:00
|
|
|
if (code_data == 0) {
|
|
|
|
code_data = (char*)flash_helper_code_data_raw(CODE_IND_LISP);
|
|
|
|
}
|
|
|
|
|
|
|
|
const_heap_ptr = (lbm_uint*)(code_data + code_len + 16);
|
|
|
|
const_heap_ptr = (lbm_uint*)((uint32_t)const_heap_ptr & 0xFFFFFFF4);
|
|
|
|
uint32_t const_heap_len = ((uint32_t)code_data + 1024 * 128) - (uint32_t)const_heap_ptr;
|
|
|
|
lbm_const_heap_init(const_heap_write, &const_heap, const_heap_ptr, const_heap_len);
|
|
|
|
|
2022-11-15 01:37:43 -08:00
|
|
|
// Load imports
|
|
|
|
if (code_len > code_chars + 3) {
|
|
|
|
int32_t ind = code_chars + 1;
|
|
|
|
uint16_t num_imports = buffer_get_uint16((uint8_t*)code_data, &ind);
|
|
|
|
|
|
|
|
if (num_imports > 0 && num_imports < 500) {
|
|
|
|
for (int i = 0;i < num_imports;i++) {
|
|
|
|
char *name = code_data + ind;
|
|
|
|
ind += strlen(name) + 1;
|
|
|
|
int32_t offset = buffer_get_int32((uint8_t*)code_data, &ind);
|
|
|
|
int32_t len = buffer_get_int32((uint8_t*)code_data, &ind);
|
|
|
|
|
|
|
|
lbm_value val;
|
2023-04-05 06:39:55 -07:00
|
|
|
if (lbm_share_array(&val, code_data + offset, len)) {
|
2022-11-15 01:37:43 -08:00
|
|
|
lbm_define(name, val);
|
2022-07-25 05:26:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-15 01:37:43 -08:00
|
|
|
}
|
2022-07-25 05:26:21 -07:00
|
|
|
|
2022-11-15 01:37:43 -08:00
|
|
|
if (load_code) {
|
2022-03-01 04:08:25 -08:00
|
|
|
if (print) {
|
2022-07-25 05:26:21 -07:00
|
|
|
commands_printf_lisp("Parsing %d characters", code_chars);
|
2022-03-01 04:08:25 -08:00
|
|
|
}
|
|
|
|
|
2022-09-18 13:47:50 -07:00
|
|
|
lbm_create_string_char_channel(&string_tok_state, &string_tok, code_data);
|
2023-08-27 23:19:32 -07:00
|
|
|
lbm_load_and_eval_program_incremental(&string_tok, "main");
|
2022-01-29 12:26:15 -08:00
|
|
|
}
|
2022-01-28 18:36:34 -08:00
|
|
|
|
|
|
|
lbm_continue_eval();
|
|
|
|
|
|
|
|
res = true;
|
2022-01-21 01:52:56 -08:00
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
return res;
|
|
|
|
}
|
2022-01-13 05:50:19 -08:00
|
|
|
|
2023-07-29 11:01:14 -07:00
|
|
|
void lispif_add_ext_load_callback(void (*p_func)(void)) {
|
|
|
|
for (int i = 0;i < EXT_LOAD_CALLBACK_LEN;i++) {
|
|
|
|
if (ext_load_callbacks[i] == 0 || ext_load_callbacks[i] == p_func) {
|
|
|
|
ext_load_callbacks[i] = p_func;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
static uint32_t timestamp_callback(void) {
|
2022-12-14 10:48:26 -08:00
|
|
|
systime_t t = chVTGetSystemTimeX();
|
2022-01-28 18:36:34 -08:00
|
|
|
return (uint32_t) ((1000000 / CH_CFG_ST_FREQUENCY) * t);
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
static void sleep_callback(uint32_t us) {
|
|
|
|
chThdSleepMicroseconds(us);
|
|
|
|
}
|
|
|
|
|
2023-04-02 10:10:11 -07:00
|
|
|
static bool const_heap_write(lbm_uint ix, lbm_uint w) {
|
|
|
|
if (const_heap_ptr[ix] == w) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
FLASH_Unlock();
|
|
|
|
FLASH_ClearFlag(FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
|
|
|
|
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
|
|
|
FLASH_ProgramWord((uint32_t)(const_heap_ptr + ix), w);
|
|
|
|
FLASH_Lock();
|
|
|
|
|
|
|
|
if (const_heap_ptr[ix] != w) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-01-28 18:36:34 -08:00
|
|
|
static THD_FUNCTION(eval_thread, arg) {
|
|
|
|
(void)arg;
|
|
|
|
eval_tp = chThdGetSelfX();
|
|
|
|
chRegSetThreadName("Lisp Eval");
|
|
|
|
lbm_run_eval();
|
2022-01-13 05:50:19 -08:00
|
|
|
}
|