From f81093922aaa8004fa5a6d7f161e24f7623ddcf7 Mon Sep 17 00:00:00 2001 From: Benjamin Vedder Date: Tue, 15 Jun 2021 12:56:38 +0200 Subject: [PATCH] Added event logging --- Makefile | 1 + conf_general.h | 2 +- events.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++ events.h | 29 ++++++++++++ main.c | 2 + mc_interface.c | 17 +++++++ timeout.c | 5 ++- 7 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 events.c create mode 100644 events.h diff --git a/Makefile b/Makefile index 42a11fae5..1b94d09f5 100755 --- a/Makefile +++ b/Makefile @@ -160,6 +160,7 @@ CSRC = $(STARTUPSRC) \ mempools.c \ worker.c \ bms.c \ + events.c \ $(HWSRC) \ $(APPSRC) \ $(NRFSRC) \ diff --git a/conf_general.h b/conf_general.h index 56acf4e29..cd8eb62c6 100755 --- a/conf_general.h +++ b/conf_general.h @@ -24,7 +24,7 @@ #define FW_VERSION_MAJOR 5 #define FW_VERSION_MINOR 03 // Set to 0 for building a release and iterate during beta test builds -#define FW_TEST_VERSION_NUMBER 39 +#define FW_TEST_VERSION_NUMBER 40 #include "datatypes.h" diff --git a/events.c b/events.c new file mode 100644 index 000000000..11e81ac6b --- /dev/null +++ b/events.c @@ -0,0 +1,119 @@ +/* + Copyright 2021 Benjamin Vedder benjamin@vedder.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 . + */ + +#include "events.h" +#include "terminal.h" +#include "commands.h" +#include "utils.h" +#include "ch.h" +#include +#include + +// Settings +#define EVENTS_LEN 30 + +// Private types +typedef struct { + const char *name; + thread_t *thread; + float param; + systime_t time; + bool set; +} event_t; + +// Private variables +static volatile event_t m_events[EVENTS_LEN]; +static volatile int m_event_now = 0; +static mutex_t m_mtx; + +// Private functions +static void terminal_print(int argc, const char **argv); + +void events_init(void) { + chMtxObjectInit(&m_mtx); + + for (int i = 0;i < EVENTS_LEN;i++) { + volatile event_t *e = &m_events[i]; + e->set = false; + } + + terminal_register_command_callback( + "events", + "Print recent motor events", + 0, + terminal_print); +} + +void events_add(const char *name, float param) { + chMtxLock(&m_mtx); + + int event = m_event_now; + + event--; + if (event < 0) { + event = EVENTS_LEN - 1; + } + volatile event_t *e = &m_events[event]; + + // Just update the last event if it looks like + // a repeated command. Otherwise the buffer will + // fill too fast. + if (e->name != name || // Comparing memory location is enough + e->thread != chThdGetSelfX() || + UTILS_AGE_S(e->time) > 0.2 || + (fabsf(param) > 1e-4) != (fabsf(e->param) > 1e-4)) { + event = (event + 1) % EVENTS_LEN; + e = &m_events[event]; + } + + e->name = name; + e->thread = chThdGetSelfX(); + e->param = param; + e->time = chVTGetSystemTimeX(); + e->set = true; + + event = (event + 1) % EVENTS_LEN; + m_event_now = event; + + chMtxUnlock(&m_mtx); +} + +static void terminal_print(int argc, const char **argv) { + (void)argc; (void)argv; + + int event = m_event_now; + int print_cnt = 0; + + do { + volatile event_t *e = &m_events[event]; + + if (e->set) { + print_cnt++; + commands_printf("Age : %.2f s", (double)UTILS_AGE_S(e->time)); + commands_printf("Thread : %s", e->thread->p_name); + commands_printf("Motor : %i", e->thread->motor_selected); + commands_printf("Command: %s", e->name); + commands_printf("Param : %.3f\n", (double)e->param); + } + + event = (event + 1) % EVENTS_LEN; + } while (event != m_event_now); + + commands_printf("Events total: %d\n", print_cnt); +} diff --git a/events.h b/events.h new file mode 100644 index 000000000..efeeb7c48 --- /dev/null +++ b/events.h @@ -0,0 +1,29 @@ +/* + Copyright 2021 Benjamin Vedder benjamin@vedder.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 . + */ + +#ifndef EVENTS_H_ +#define EVENTS_H_ + +#include +#include + +void events_init(void); +void events_add(const char *name, float param); + +#endif /* EVENTS_H_ */ diff --git a/main.c b/main.c index 7de241cf9..51b85ca23 100644 --- a/main.c +++ b/main.c @@ -53,6 +53,7 @@ #endif #include "shutdown.h" #include "mempools.h" +#include "events.h" /* * HW resources used: @@ -205,6 +206,7 @@ int main(void) { chThdSleepMilliseconds(100); + events_init(); hw_init_gpio(); LED_RED_OFF(); LED_GREEN_OFF(); diff --git a/mc_interface.c b/mc_interface.c index 461d7429a..1b4c82062 100644 --- a/mc_interface.c +++ b/mc_interface.c @@ -38,6 +38,7 @@ #include "mempools.h" #include "crc.h" #include "bms.h" +#include "events.h" #include #include @@ -589,6 +590,8 @@ void mc_interface_set_duty(float dutyCycle) { default: break; } + + events_add("set_duty", dutyCycle); } void mc_interface_set_duty_noramp(float dutyCycle) { @@ -613,6 +616,8 @@ void mc_interface_set_duty_noramp(float dutyCycle) { default: break; } + + events_add("set_duty_noramp", dutyCycle); } void mc_interface_set_pid_speed(float rpm) { @@ -637,6 +642,8 @@ void mc_interface_set_pid_speed(float rpm) { default: break; } + + events_add("set_pid_speed", rpm); } void mc_interface_set_pid_pos(float pos) { @@ -664,6 +671,8 @@ void mc_interface_set_pid_pos(float pos) { default: break; } + + events_add("set_pid_pos", pos); } void mc_interface_set_current(float current) { @@ -688,6 +697,8 @@ void mc_interface_set_current(float current) { default: break; } + + events_add("set_current", current); } void mc_interface_set_brake_current(float current) { @@ -717,6 +728,8 @@ void mc_interface_set_brake_current(float current) { default: break; } + + events_add("set_current_brake", current); } /** @@ -776,6 +789,8 @@ void mc_interface_set_handbrake(float current) { default: break; } + + events_add("set_handbrake", current); } /** @@ -819,6 +834,8 @@ void mc_interface_release_motor_override(void) { default: break; } + + events_add("release_motor_override", 0.0); } bool mc_interface_wait_for_motor_release(float timeout) { diff --git a/timeout.c b/timeout.c index c36e4bef6..2c0c6f5f8 100644 --- a/timeout.c +++ b/timeout.c @@ -209,13 +209,14 @@ static THD_FUNCTION(timeout_thread, arg) { } if (kill_sw || (timeout_msec != 0 && chVTTimeElapsedSinceX(last_update_time) > MS2ST(timeout_msec))) { - mc_interface_release_motor_override(); + if (!has_timeout && !kill_sw_active) { + mc_interface_release_motor_override(); + } mc_interface_unlock(); mc_interface_select_motor_thread(1); mc_interface_set_brake_current(timeout_brake_current); mc_interface_select_motor_thread(2); mc_interface_set_brake_current(timeout_brake_current); - mc_interface_ignore_input(20); if (!kill_sw) { has_timeout = true;