From 32fc992f6a41a9a139aaaa6569f549b54c8a912f Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 22 Aug 2020 20:34:03 -0400 Subject: [PATCH] filter loading and real-time execution --- filter/test.cpp | 3 +-- gui/stmdsp.cpp | 15 +++++++++++++++ gui/stmdsp.hpp | 2 ++ gui/wxmain.hpp | 21 +++++++++++++++++++++ source/elf_load.cpp | 13 +++++++++---- source/elf_load.hpp | 7 +++++-- source/main.cpp | 14 +++++++++++++- 7 files changed, 66 insertions(+), 9 deletions(-) diff --git a/filter/test.cpp b/filter/test.cpp index 0953539..24fdb72 100644 --- a/filter/test.cpp +++ b/filter/test.cpp @@ -8,8 +8,7 @@ void process_data(adcsample_t *samples, unsigned int size); void process_data(adcsample_t *samples, unsigned int size) { - size--; for (unsigned int i = 0; i < size; i++) - samples[i] = samples[i] * 80 / 100 + samples[i + 1] * 20 / 100; + samples[i] /= 2; } diff --git a/gui/stmdsp.cpp b/gui/stmdsp.cpp index ed152f7..73ae880 100644 --- a/gui/stmdsp.cpp +++ b/gui/stmdsp.cpp @@ -53,10 +53,25 @@ namespace stmdsp m_serial.read(reinterpret_cast(data.data()), 2048 * sizeof(adcsample_t)); return data; } + + return {}; } void device::continuous_stop() { if (connected()) m_serial.write("S"); } + + void device::upload_filter(unsigned char *buffer, size_t size) { + if (connected()) { + uint8_t request[3] = { + 'e', + static_cast(size), + static_cast(size >> 8) + }; + m_serial.write(request, 3); + + m_serial.write(buffer, size); + } + } } diff --git a/gui/stmdsp.hpp b/gui/stmdsp.hpp index c179955..ec58e5a 100644 --- a/gui/stmdsp.hpp +++ b/gui/stmdsp.hpp @@ -44,6 +44,8 @@ namespace stmdsp std::vector continuous_read(); void continuous_stop(); + void upload_filter(unsigned char *buffer, size_t size); + private: serial::Serial m_serial; }; diff --git a/gui/wxmain.hpp b/gui/wxmain.hpp index 1fc74bd..289e891 100644 --- a/gui/wxmain.hpp +++ b/gui/wxmain.hpp @@ -8,9 +8,11 @@ #include #include #include +#include #include #include #include +#include class MainFrame : public wxFrame { @@ -18,6 +20,7 @@ class MainFrame : public wxFrame Welcome = 1, Single, SelectDevice, + UploadFilter, RenderTimer }; @@ -36,6 +39,7 @@ public: { new wxStaticText(this, Id::Welcome, "Welcome to the GUI.", wxPoint(20, 20)); new wxButton(this, Id::Single, "Single", wxPoint(20, 60)); + new wxButton(this, Id::UploadFilter, "Upload Filter", wxPoint(120, 60)); m_device_combo = new wxComboBox(this, Id::SelectDevice, "", wxPoint(470, 20), wxSize(150, 30)); m_device_combo->SetEditable(false); stmdsp::scanner scanner; @@ -47,6 +51,7 @@ public: m_render_timer = new wxTimer(this, Id::RenderTimer); Bind(wxEVT_BUTTON, &MainFrame::onSinglePressed, this, Id::Single); + Bind(wxEVT_BUTTON, &MainFrame::onUploadPressed, this, Id::UploadFilter); Bind(wxEVT_PAINT, &MainFrame::onPaint, this, wxID_ANY); Bind(wxEVT_TIMER, &MainFrame::onRenderTimer, this, Id::RenderTimer); } @@ -106,6 +111,22 @@ public: } } + void onUploadPressed(wxCommandEvent& ce) { + wxFileDialog dialog (this, "Select filter to upload", "", "", "*.so", + wxFD_OPEN | wxFD_FILE_MUST_EXIST); + if (dialog.ShowModal() != wxID_CANCEL) { + if (wxFileInputStream file_stream (dialog.GetPath()); file_stream.IsOk()) { + auto size = file_stream.GetSize(); + auto buffer = new unsigned char[size]; + auto device = new stmdsp::device(m_device_combo->GetStringSelection().ToStdString()); + if (device->connected()) { + file_stream.ReadAll(buffer, size); + device->upload_filter(buffer, size); + } + } + } + } + void onRenderTimer([[maybe_unused]] wxTimerEvent& te) { updateDrawing(); } diff --git a/source/elf_load.cpp b/source/elf_load.cpp index 661dbc3..8149e8a 100644 --- a/source/elf_load.cpp +++ b/source/elf_load.cpp @@ -4,7 +4,6 @@ #include #include -extern void *elf_load_offset; static const unsigned char elf_header[] = { '\177', 'E', 'L', 'F' }; template @@ -17,10 +16,10 @@ static Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name); namespace elf { -entry_t elf_load(void *elf_data) +entry_t load(void *elf_data, void *elf_load_offset) { auto ehdr = reinterpret_cast(elf_data); - if (std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header)) + if (!std::equal(ehdr->e_ident, ehdr->e_ident + 4, elf_header)) return nullptr; auto phdr = ptr_from_offset(elf_data, ehdr->e_phoff); @@ -31,6 +30,8 @@ entry_t elf_load(void *elf_data) phdr->p_filesz); //break; } + + phdr = ptr_from_offset(phdr, ehdr->e_phentsize); } // Zero .bss section @@ -53,7 +54,11 @@ entry_t elf_load(void *elf_data) // [elf_load_offset](auto func) { (func + elf_load_offset)(); }); //} - return ptr_from_offset(elf_load_offset, ehdr->e_entry); + // Find filter code start + if (auto filter = find_section(ehdr, ".process_data"); filter) + return ptr_from_offset(elf_load_offset, filter->sh_addr | 1); // OR 1 to enable thumb + else + return nullptr; } } // namespace elf diff --git a/source/elf_load.hpp b/source/elf_load.hpp index 722b19b..3e03f1d 100644 --- a/source/elf_load.hpp +++ b/source/elf_load.hpp @@ -1,11 +1,14 @@ #ifndef ELF_LOAD_HPP_ #define ELF_LOAD_HPP_ +#include +#include + namespace elf { - using entry_t = void (*)(); + using entry_t = void (*)(uint16_t *, size_t); - entry_t load(void *file_data); + entry_t load(void *elf_data, void *elf_load_offset); } #endif // ELF_LOAD_HPP_ diff --git a/source/main.cpp b/source/main.cpp index 162771a..6c418ce 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -14,6 +14,7 @@ #include "adc.hpp" #include "dac.hpp" +#include "elf_load.hpp" #include "usbserial.hpp" #include @@ -30,6 +31,10 @@ CC_ALIGN(CACHE_LINE_SIZE) #endif static std::array dac_samples; +static uint8_t elf_file_store[2048]; +static uint8_t elf_exec_store[2048]; +static elf::entry_t elf_entry = nullptr; + static volatile bool signal_operate_done = false; static void signal_operate(adcsample_t *buffer, size_t count); @@ -73,7 +78,12 @@ int main() adc::read_stop(); break; case 'e': - + if (usbserial::read(&cmd[1], 2) < 2) + break; + if (unsigned int count = cmd[1] | (cmd[2] << 8); count < sizeof(elf_file_store)) { + usbserial::read(elf_file_store, count); + elf_entry = elf::load(elf_file_store, elf_exec_store); + } break; case 'W': if (usbserial::read(&cmd[1], 2) < 2) @@ -103,6 +113,8 @@ int main() void signal_operate(adcsample_t *buffer, size_t count) { + if (elf_entry) + elf_entry(buffer, count); auto dac_buffer = &dac_samples[buffer == &adc_samples[0] ? 0 : 1024]; std::copy(buffer, buffer + count, dac_buffer); signal_operate_done = buffer == &adc_samples[1024];