mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Added Memory Dump app for Debug (#1588)
* Add files via upload * Add files via upload * Added single word read/write support * Add files via upload
This commit is contained in:
parent
2c0446e83d
commit
de937f02d4
@ -277,14 +277,11 @@ RegistersView::RegistersView(
|
||||
static_cast<int>(title.size()) * 8, 16});
|
||||
text_title.set(title);
|
||||
|
||||
field_write_reg_num.set_value(0);
|
||||
field_write_reg_num.on_change = [this](SymField&) {
|
||||
field_write_data_val.set_value(this->registers_widget.reg_read(field_write_reg_num.to_integer()));
|
||||
field_write_data_val.set_dirty();
|
||||
};
|
||||
|
||||
field_write_data_val.on_change = [this](SymField&) {};
|
||||
|
||||
const auto value = registers_widget.reg_read(0);
|
||||
field_write_data_val.set_value(value);
|
||||
|
||||
@ -450,9 +447,10 @@ DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
{"Buttons Test", ui::Color::dark_cyan(), &bitmap_icon_controls, [&nav]() { nav.push<DebugControlsView>(); }},
|
||||
{"Debug Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { portapack::persistent_memory::debug_dump(); }},
|
||||
{"M0 Stack Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { stack_dump(); }},
|
||||
{"Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<DebugMemoryView>(); }},
|
||||
{"P.Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<DebugPmemView>(); }},
|
||||
{"Memory Dump", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<DebugMemoryDumpView>(); }},
|
||||
{"Memory Usage", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<DebugMemoryView>(); }},
|
||||
{"Peripherals", ui::Color::dark_cyan(), &bitmap_icon_peripherals, [&nav]() { nav.push<DebugPeripheralsMenuView>(); }},
|
||||
{"Pers. Memory", ui::Color::dark_cyan(), &bitmap_icon_memory, [&nav]() { nav.push<DebugPmemView>(); }},
|
||||
//{ "Radio State", ui::Color::white(), nullptr, [&nav](){ nav.push<NotImplementedView>(); } },
|
||||
{"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav]() { nav.push<SDCardDebugView>(); }},
|
||||
{"Temperature", ui::Color::dark_cyan(), &bitmap_icon_temperature, [&nav]() { nav.push<TemperatureView>(); }},
|
||||
@ -466,6 +464,43 @@ DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
set_max_rows(2); // allow wider buttons
|
||||
}
|
||||
|
||||
/* DebugMemoryDumpView *********************************************************/
|
||||
|
||||
DebugMemoryDumpView::DebugMemoryDumpView(NavigationView& nav) {
|
||||
add_children({
|
||||
&button_dump,
|
||||
&button_read,
|
||||
&button_write,
|
||||
&button_done,
|
||||
&labels,
|
||||
&field_starting_address,
|
||||
&field_byte_count,
|
||||
&field_rw_address,
|
||||
&field_data_value,
|
||||
});
|
||||
|
||||
button_done.on_select = [&nav](Button&) { nav.pop(); };
|
||||
|
||||
button_dump.on_select = [this](Button&) {
|
||||
if (field_byte_count.to_integer() != 0)
|
||||
memory_dump((uint32_t*)field_starting_address.to_integer(), ((uint32_t)field_byte_count.to_integer() + 3) / 4, false);
|
||||
};
|
||||
|
||||
button_read.on_select = [this](Button&) {
|
||||
field_data_value.set_value(*(uint32_t*)field_rw_address.to_integer());
|
||||
field_data_value.set_dirty();
|
||||
};
|
||||
|
||||
button_write.set_style(&Styles::red);
|
||||
button_write.on_select = [this](Button&) {
|
||||
*(uint32_t*)field_rw_address.to_integer() = (uint32_t)field_data_value.to_integer();
|
||||
};
|
||||
}
|
||||
|
||||
void DebugMemoryDumpView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
/* DebugPmemView *********************************************************/
|
||||
|
||||
DebugPmemView::DebugPmemView(NavigationView& nav)
|
||||
|
@ -48,8 +48,8 @@ class DebugMemoryView : public View {
|
||||
|
||||
private:
|
||||
Text text_title{
|
||||
{96, 96, 48, 16},
|
||||
"Memory",
|
||||
{72, 96, 96, 16},
|
||||
"Memory Usage",
|
||||
};
|
||||
|
||||
Text text_label_m0_core_free{
|
||||
@ -301,6 +301,58 @@ class DebugControlsView : public View {
|
||||
"Done"};
|
||||
};
|
||||
|
||||
class DebugMemoryDumpView : public View {
|
||||
public:
|
||||
DebugMemoryDumpView(NavigationView& nav);
|
||||
void focus() override;
|
||||
std::string title() const override { return "Memory Dump"; };
|
||||
|
||||
private:
|
||||
Button button_dump{
|
||||
{72, 4 * 16, 96, 24},
|
||||
"Dump"};
|
||||
|
||||
Button button_read{
|
||||
{16, 11 * 16, 96, 24},
|
||||
"Read"};
|
||||
|
||||
Button button_write{
|
||||
{128, 11 * 16, 96, 24},
|
||||
"Write"};
|
||||
|
||||
Button button_done{
|
||||
{128, 240, 96, 24},
|
||||
"Done"};
|
||||
|
||||
Labels labels{
|
||||
{{5 * 8, 1 * 16}, "Dump Range to File", Color::yellow()},
|
||||
{{0 * 8, 2 * 16}, "Starting Address: 0x", Color::light_grey()},
|
||||
{{0 * 8, 3 * 16}, "Byte Count: 0x", Color::light_grey()},
|
||||
{{3 * 8, 8 * 16}, "Read/Write Single Word", Color::yellow()},
|
||||
{{0 * 8, 9 * 16}, "Memory Address: 0x", Color::light_grey()},
|
||||
{{0 * 8, 10 * 16}, "Data Value: 0x", Color::light_grey()}};
|
||||
|
||||
SymField field_starting_address{
|
||||
{20 * 8, 2 * 16},
|
||||
8,
|
||||
SymField::Type::Hex};
|
||||
|
||||
SymField field_byte_count{
|
||||
{20 * 8, 3 * 16},
|
||||
8,
|
||||
SymField::Type::Hex};
|
||||
|
||||
SymField field_rw_address{
|
||||
{20 * 8, 9 * 16},
|
||||
8,
|
||||
SymField::Type::Hex};
|
||||
|
||||
SymField field_data_value{
|
||||
{20 * 8, 10 * 16},
|
||||
8,
|
||||
SymField::Type::Hex};
|
||||
};
|
||||
|
||||
class DebugPmemView : public View {
|
||||
public:
|
||||
DebugPmemView(NavigationView& nav);
|
||||
|
@ -258,38 +258,43 @@ void draw_stack_dump() {
|
||||
}
|
||||
}
|
||||
|
||||
// Disk I/O in this function doesn't work after a fault
|
||||
// Using the stack while dumping the stack isn't ideal, but hopefully anything imporant is still on the call stack.
|
||||
bool stack_dump() {
|
||||
uint32_t num_words = &__process_stack_end__ - &__process_stack_base__;
|
||||
return memory_dump(&__process_stack_base__, num_words, true);
|
||||
}
|
||||
|
||||
bool memory_dump(uint32_t* addr_start, uint32_t num_words, bool stack_flag) {
|
||||
Painter painter;
|
||||
std::string debug_dir = "DEBUG";
|
||||
std::filesystem::path filename{};
|
||||
File stack_dump_file{};
|
||||
File dump_file{};
|
||||
bool error;
|
||||
std::string str;
|
||||
uint32_t* addr_end;
|
||||
uint32_t* p;
|
||||
int n{0};
|
||||
bool data_found{false};
|
||||
|
||||
make_new_directory(debug_dir);
|
||||
filename = next_filename_matching_pattern(debug_dir + "/STACK_DUMP_????.TXT");
|
||||
filename = next_filename_matching_pattern(debug_dir + "/" + (stack_flag ? "STACK" : "MEMORY") + "_DUMP_????.TXT");
|
||||
error = filename.empty();
|
||||
if (!error)
|
||||
error = stack_dump_file.create(filename) != 0;
|
||||
error = dump_file.create(filename) != 0;
|
||||
if (error) {
|
||||
painter.draw_string({16, 320 - 32}, ui::Styles::red, "ERROR DUMPING " + filename.filename().string() + "!");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (p = &__process_stack_base__; p < &__process_stack_end__; p++) {
|
||||
addr_end = addr_start + num_words;
|
||||
for (p = addr_start; p < addr_end; p++) {
|
||||
// skip past unused stack words
|
||||
if (!data_found) {
|
||||
if (stack_flag && !data_found) {
|
||||
if (*p == CRT0_STACKS_FILL_PATTERN)
|
||||
continue;
|
||||
else {
|
||||
data_found = true;
|
||||
auto stack_space_left = p - &__process_stack_base__;
|
||||
stack_dump_file.write_line(to_string_hex((uint32_t)&__process_stack_base__, 8) + ": Unused words " + to_string_dec_uint(stack_space_left));
|
||||
auto stack_space_left = p - addr_start;
|
||||
dump_file.write_line(to_string_hex((uint32_t)addr_start, 8) + ": Unused words " + to_string_dec_uint(stack_space_left));
|
||||
|
||||
// align subsequent lines to start on 16-byte boundaries
|
||||
p -= (stack_space_left & 3);
|
||||
@ -299,20 +304,20 @@ bool stack_dump() {
|
||||
// write address
|
||||
if (n++ == 0) {
|
||||
str = to_string_hex((uint32_t)p, 8) + ":";
|
||||
stack_dump_file.write(str.data(), 9);
|
||||
dump_file.write(str.data(), 9);
|
||||
}
|
||||
|
||||
// write stack dword
|
||||
str = " " + to_string_hex(*p, 8);
|
||||
stack_dump_file.write(str.data(), 9);
|
||||
dump_file.write(str.data(), 9);
|
||||
|
||||
if (n == 4) {
|
||||
stack_dump_file.write("\r\n", 2);
|
||||
dump_file.write("\r\n", 2);
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
painter.draw_string({16, 320 - 32}, ui::Styles::green, filename.filename().string() + " dumped!");
|
||||
painter.draw_string({0, 320 - 16}, ui::Styles::green, filename.filename().string() + " dumped!");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -48,5 +48,6 @@ inline uint32_t get_free_stack_space() {
|
||||
}
|
||||
|
||||
bool stack_dump();
|
||||
bool memory_dump(uint32_t* addr_start, uint32_t num_words, bool stack_flag);
|
||||
|
||||
#endif /*__DEBUG_H__*/
|
||||
|
Loading…
Reference in New Issue
Block a user