mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Merge pull request #830 from bernd-herzog/error_handling
added runtime error details to guru meditation
This commit is contained in:
commit
023ee2a6f5
@ -125,7 +125,7 @@ set(CPPSRC
|
|||||||
${COMMON}/cpld_max5.cpp
|
${COMMON}/cpld_max5.cpp
|
||||||
${COMMON}/cpld_update.cpp
|
${COMMON}/cpld_update.cpp
|
||||||
${COMMON}/cpld_xilinx.cpp
|
${COMMON}/cpld_xilinx.cpp
|
||||||
${COMMON}/debug.cpp
|
debug.cpp
|
||||||
${COMMON}/ert_packet.cpp
|
${COMMON}/ert_packet.cpp
|
||||||
${COMMON}/event.cpp
|
${COMMON}/event.cpp
|
||||||
${COMMON}/gcc.cpp
|
${COMMON}/gcc.cpp
|
||||||
|
209
firmware/application/debug.cpp
Normal file
209
firmware/application/debug.cpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2023 Bernd Herzog
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program 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; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "debug.hpp"
|
||||||
|
|
||||||
|
#include <ch.h>
|
||||||
|
#include <hal.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "ui_painter.hpp"
|
||||||
|
#include "portapack.hpp"
|
||||||
|
#include "ui_font_fixed_8x16.hpp"
|
||||||
|
|
||||||
|
void runtime_error(LED);
|
||||||
|
std::string number_to_hex_string(uint32_t);
|
||||||
|
void draw_line(int32_t, const char *, regarm_t);
|
||||||
|
static bool error_shown = false;
|
||||||
|
|
||||||
|
extern void draw_guru_meditation_header(uint8_t source, const char *hint) {
|
||||||
|
ui::Painter painter;
|
||||||
|
ui::Style style_default {
|
||||||
|
.font = ui::font::fixed_8x16,
|
||||||
|
.background = ui::Color::black(),
|
||||||
|
.foreground = ui::Color::white()
|
||||||
|
};
|
||||||
|
|
||||||
|
painter.fill_rectangle(
|
||||||
|
{ 0, 0, portapack::display.width(), portapack::display.height() },
|
||||||
|
ui::Color::red()
|
||||||
|
);
|
||||||
|
|
||||||
|
constexpr int border = 8;
|
||||||
|
painter.fill_rectangle(
|
||||||
|
{ border, border, portapack::display.width() - (border * 2), portapack::display.height() - (border * 2) },
|
||||||
|
ui::Color::black()
|
||||||
|
);
|
||||||
|
|
||||||
|
// NOTE: in situations like a hard fault it seems not possible to write strings longer than 16 characters.
|
||||||
|
painter.draw_string({ 48, 24 }, style_default, "M? Guru");
|
||||||
|
painter.draw_string({ 48 + 8*8, 24 }, style_default, "Meditation");
|
||||||
|
|
||||||
|
if (source == CORTEX_M0)
|
||||||
|
painter.draw_string({ 48 + 8, 24 }, style_default, "0");
|
||||||
|
|
||||||
|
if (source == CORTEX_M4)
|
||||||
|
painter.draw_string({ 48 + 8, 24 }, style_default, "4");
|
||||||
|
|
||||||
|
painter.draw_string({ 15, 55 }, style_default, "Hint: ");
|
||||||
|
painter.draw_string({ 15 + 8*8, 55 }, style_default, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_guru_meditation(uint8_t source, const char *hint) {
|
||||||
|
if(error_shown == false){
|
||||||
|
error_shown = true;
|
||||||
|
draw_guru_meditation_header(source, hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source == CORTEX_M0)
|
||||||
|
runtime_error(hackrf::one::led_rx);
|
||||||
|
|
||||||
|
if (source == CORTEX_M4)
|
||||||
|
runtime_error(hackrf::one::led_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_guru_meditation(uint8_t source, const char *hint, struct extctx *ctxp) {
|
||||||
|
if(error_shown == false)
|
||||||
|
{
|
||||||
|
error_shown = true;
|
||||||
|
draw_guru_meditation_header(source, hint);
|
||||||
|
|
||||||
|
if (ctxp != nullptr) {
|
||||||
|
int i = 0;
|
||||||
|
draw_line(80 + i++ * 20, "r0:", ctxp->r0);
|
||||||
|
draw_line(80 + i++ * 20, "r1:", ctxp->r1);
|
||||||
|
draw_line(80 + i++ * 20, "r2:", ctxp->r2);
|
||||||
|
draw_line(80 + i++ * 20, "r3:", ctxp->r3);
|
||||||
|
draw_line(80 + i++ * 20, "r12:", ctxp->r12);
|
||||||
|
|
||||||
|
// NOTE: run for M0
|
||||||
|
// # arm-none-eabi-gdb --batch --eval-command="x/8i 0x<link_register_value_here>" firmware/application/application.elf
|
||||||
|
// or for M4
|
||||||
|
// # arm-none-eabi-gdb --batch --eval-command="x/8i 0x<link_register_value_here>" firmware/baseband/<image_name_here>.elf
|
||||||
|
// to see whats causing the fault.
|
||||||
|
draw_line(80 + i++ * 20, "lr:", ctxp->lr_thd);
|
||||||
|
draw_line(80 + i++ * 20, "pc:", ctxp->pc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source == CORTEX_M0)
|
||||||
|
runtime_error(hackrf::one::led_rx);
|
||||||
|
|
||||||
|
if (source == CORTEX_M4)
|
||||||
|
runtime_error(hackrf::one::led_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_line(int32_t y_offset, const char *label, regarm_t value){
|
||||||
|
ui::Painter painter;
|
||||||
|
ui::Style style_default {
|
||||||
|
.font = ui::font::fixed_8x16,
|
||||||
|
.background = ui::Color::black(),
|
||||||
|
.foreground = ui::Color::white()
|
||||||
|
};
|
||||||
|
|
||||||
|
painter.draw_string({ 15, y_offset }, style_default, label);
|
||||||
|
painter.draw_string({ 15 + 8*8, y_offset }, style_default, number_to_hex_string((uint32_t)value));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string number_to_hex_string(uint32_t number){
|
||||||
|
char str[16];
|
||||||
|
char* p = &str[16];
|
||||||
|
do {
|
||||||
|
p--;
|
||||||
|
uint32_t digit = number % 16;
|
||||||
|
number /= 16;
|
||||||
|
*p = digit>=10 ? 'A' + (digit-10) : '0' + digit;
|
||||||
|
} while ( number > 0 );
|
||||||
|
p--;
|
||||||
|
*p = 'x';
|
||||||
|
p--;
|
||||||
|
*p = '0';
|
||||||
|
return std::string(p, &str[16]-p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void runtime_error(LED led) {
|
||||||
|
led.off();
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
volatile size_t n = 1000000U;
|
||||||
|
while(n--);
|
||||||
|
led.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
void port_halt(void) {
|
||||||
|
port_disable();
|
||||||
|
|
||||||
|
if (dbg_panic_msg == nullptr)
|
||||||
|
dbg_panic_msg = "system halted";
|
||||||
|
|
||||||
|
draw_guru_meditation(CORTEX_M0, dbg_panic_msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CH_IRQ_HANDLER(MemManageVector) {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
chDbgPanic("MemManage");
|
||||||
|
#else
|
||||||
|
chSysHalt();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CH_IRQ_HANDLER(BusFaultVector) {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
chDbgPanic("BusFault");
|
||||||
|
#else
|
||||||
|
chSysHalt();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CH_IRQ_HANDLER(UsageFaultVector) {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
chDbgPanic("UsageFault");
|
||||||
|
#else
|
||||||
|
chSysHalt();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CH_IRQ_HANDLER(HardFaultVector) {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
struct extctx *ctxp;
|
||||||
|
port_lock_from_isr();
|
||||||
|
|
||||||
|
if ((uint32_t)_saved_lr & 0x04)
|
||||||
|
ctxp = (struct extctx *)__get_PSP();
|
||||||
|
else
|
||||||
|
ctxp = (struct extctx *)__get_MSP();
|
||||||
|
|
||||||
|
port_disable();
|
||||||
|
draw_guru_meditation(CORTEX_M0, "Hard Fault", ctxp);
|
||||||
|
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
#else
|
||||||
|
chSysHalt();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* extern "C" */
|
31
firmware/application/debug.hpp
Normal file
31
firmware/application/debug.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2023 Bernd Herzog
|
||||||
|
*
|
||||||
|
* This file is part of PortaPack.
|
||||||
|
*
|
||||||
|
* This program 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 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program 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; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __DEBUG_H__
|
||||||
|
#define __DEBUG_H__
|
||||||
|
|
||||||
|
#include "hackrf_gpio.hpp"
|
||||||
|
|
||||||
|
extern void draw_guru_meditation(uint8_t, const char *);
|
||||||
|
extern void draw_guru_meditation(uint8_t, const char *, struct extctx *);
|
||||||
|
|
||||||
|
#endif/*__DEBUG_H__*/
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "portapack.hpp"
|
#include "portapack.hpp"
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
|
#include "debug.hpp"
|
||||||
|
|
||||||
#include "sd_card.hpp"
|
#include "sd_card.hpp"
|
||||||
#include "rtc_time.hpp"
|
#include "rtc_time.hpp"
|
||||||
@ -141,37 +142,10 @@ eventmask_t EventDispatcher::wait() {
|
|||||||
|
|
||||||
void EventDispatcher::dispatch(const eventmask_t events) {
|
void EventDispatcher::dispatch(const eventmask_t events) {
|
||||||
if( shared_memory.m4_panic_msg[0] != 0 ) {
|
if( shared_memory.m4_panic_msg[0] != 0 ) {
|
||||||
halt = true;
|
if (shared_memory.bb_data.data[0] == 0)
|
||||||
}
|
draw_guru_meditation(CORTEX_M4, shared_memory.m4_panic_msg);
|
||||||
|
else
|
||||||
if( halt ) {
|
draw_guru_meditation(CORTEX_M4, shared_memory.m4_panic_msg, (struct extctx *)&shared_memory.bb_data.data[4]);
|
||||||
if( shared_memory.m4_panic_msg[0] != 0 ) {
|
|
||||||
painter.fill_rectangle(
|
|
||||||
{ 0, 0, portapack::display.width(), portapack::display.height() },
|
|
||||||
ui::Color::red()
|
|
||||||
);
|
|
||||||
|
|
||||||
constexpr int border = 8;
|
|
||||||
painter.fill_rectangle(
|
|
||||||
{ border, border, portapack::display.width() - (border * 2), portapack::display.height() - (border * 2) },
|
|
||||||
ui::Color::black()
|
|
||||||
);
|
|
||||||
|
|
||||||
painter.draw_string({ 48, 24 }, top_widget->style(), "M4 Guru Meditation");
|
|
||||||
|
|
||||||
shared_memory.m4_panic_msg[sizeof(shared_memory.m4_panic_msg) - 1] = 0;
|
|
||||||
const std::string message = shared_memory.m4_panic_msg;
|
|
||||||
const int x_offset = (portapack::display.width() - (message.size() * 8)) / 2;
|
|
||||||
constexpr int y_offset = (portapack::display.height() - 16) / 2;
|
|
||||||
painter.draw_string(
|
|
||||||
{ x_offset, y_offset },
|
|
||||||
top_widget->style(),
|
|
||||||
message
|
|
||||||
);
|
|
||||||
|
|
||||||
shared_memory.m4_panic_msg[0] = 0;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( events & EVT_MASK_APPLICATION ) {
|
if( events & EVT_MASK_APPLICATION ) {
|
||||||
|
@ -98,7 +98,6 @@ private:
|
|||||||
static bool is_running;
|
static bool is_running;
|
||||||
bool sd_card_present = false;
|
bool sd_card_present = false;
|
||||||
static bool display_sleep;
|
static bool display_sleep;
|
||||||
bool halt = false;
|
|
||||||
bool in_key_event = false;
|
bool in_key_event = false;
|
||||||
|
|
||||||
eventmask_t wait();
|
eventmask_t wait();
|
||||||
|
@ -139,7 +139,7 @@ set(CPPSRC
|
|||||||
audio_stats_collector.cpp
|
audio_stats_collector.cpp
|
||||||
${COMMON}/utility.cpp
|
${COMMON}/utility.cpp
|
||||||
${COMMON}/chibios_cpp.cpp
|
${COMMON}/chibios_cpp.cpp
|
||||||
${COMMON}/debug.cpp
|
debug.cpp
|
||||||
${COMMON}/gcc.cpp
|
${COMMON}/gcc.cpp
|
||||||
tone_gen.cpp
|
tone_gen.cpp
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2023 Bernd Herzog
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
@ -26,60 +27,36 @@
|
|||||||
|
|
||||||
#include "portapack_shared_memory.hpp"
|
#include "portapack_shared_memory.hpp"
|
||||||
|
|
||||||
#if defined(LPC43XX_M0)
|
void write_m4_panic_msg(const char *panic_message, struct extctx *ctxp) {
|
||||||
static void debug_indicate_error_init() {
|
if (ctxp == nullptr) {
|
||||||
// TODO: Get knowledge of LED GPIO port/bit from shared place.
|
shared_memory.bb_data.data[0] = 0;
|
||||||
LPC_GPIO->CLR[2] = (1 << 2);
|
}
|
||||||
}
|
else {
|
||||||
|
shared_memory.bb_data.data[0] = 1;
|
||||||
|
memcpy(&shared_memory.bb_data.data[4], ctxp, sizeof(struct extctx));
|
||||||
|
}
|
||||||
|
|
||||||
static void debug_indicate_error_update() {
|
for(size_t i=0; i<sizeof(shared_memory.m4_panic_msg); i++) {
|
||||||
// Flash RX (yellow) LED to indicate baseband error.
|
if( *panic_message == 0 ) {
|
||||||
// TODO: Get knowledge of LED GPIO port/bit from shared place.
|
shared_memory.m4_panic_msg[i] = 0;
|
||||||
LPC_GPIO->NOT[2] = (1 << 2);
|
} else {
|
||||||
}
|
shared_memory.m4_panic_msg[i] = *(panic_message++);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#if defined(LPC43XX_M4)
|
|
||||||
static void debug_indicate_error_init() {
|
|
||||||
// TODO: Get knowledge of LED GPIO port/bit from shared place.
|
|
||||||
LPC_GPIO->CLR[2] = (1 << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void debug_indicate_error_update() {
|
|
||||||
// Flash TX (red) LED to indicate baseband error.
|
|
||||||
// TODO: Get knowledge of LED GPIO port/bit from shared place.
|
|
||||||
LPC_GPIO->NOT[2] = (1 << 8);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void runtime_error() {
|
|
||||||
debug_indicate_error_init();
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
volatile size_t n = 1000000U;
|
|
||||||
while(n--);
|
|
||||||
debug_indicate_error_update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
void port_halt(void) {
|
void port_halt(void) {
|
||||||
// Copy debug panic message to M0 region.
|
|
||||||
const auto* p = dbg_panic_msg;
|
|
||||||
for(size_t i=0; i<sizeof(shared_memory.m4_panic_msg); i++) {
|
|
||||||
if( *p == 0 ) {
|
|
||||||
shared_memory.m4_panic_msg[i] = 0;
|
|
||||||
} else {
|
|
||||||
shared_memory.m4_panic_msg[i] = *(p++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
port_disable();
|
port_disable();
|
||||||
runtime_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(LPC43XX_M4)
|
if (dbg_panic_msg == nullptr)
|
||||||
|
dbg_panic_msg = "system halted";
|
||||||
|
|
||||||
|
write_m4_panic_msg(dbg_panic_msg, nullptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CH_IRQ_HANDLER(MemManageVector) {
|
CH_IRQ_HANDLER(MemManageVector) {
|
||||||
#if CH_DBG_ENABLED
|
#if CH_DBG_ENABLED
|
||||||
chDbgPanic("MemManage");
|
chDbgPanic("MemManage");
|
||||||
@ -103,6 +80,31 @@ CH_IRQ_HANDLER(UsageFaultVector) {
|
|||||||
chSysHalt();
|
chSysHalt();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CH_IRQ_HANDLER(HardFaultVector) {
|
||||||
|
#if CH_DBG_ENABLED
|
||||||
|
regarm_t _saved_lr;
|
||||||
|
asm volatile ("mov %0, lr" : "=r" (_saved_lr) : : "memory");
|
||||||
|
CH_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
struct extctx *ctxp;
|
||||||
|
port_lock_from_isr();
|
||||||
|
|
||||||
|
if ((uint32_t)_saved_lr & 0x04)
|
||||||
|
ctxp = (struct extctx *)__get_PSP();
|
||||||
|
else
|
||||||
|
ctxp = (struct extctx *)__get_MSP();
|
||||||
|
|
||||||
|
write_m4_panic_msg("Hard Fault", ctxp);
|
||||||
|
|
||||||
|
port_disable();
|
||||||
|
while (true);
|
||||||
|
|
||||||
|
CH_IRQ_EPILOGUE();
|
||||||
|
#else
|
||||||
|
chSysHalt();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user