diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2021-01-27 11:18:33 -0500 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2021-01-27 11:18:33 -0500 |
commit | 4f59610a00da78639c1909acb09c7dfde4519a28 (patch) | |
tree | c4b9f18f4a0826c2f635ee3b16a3a88d7a195114 /source | |
parent | 1a14ef827ed99a814b00d8ea4b98b8633582b945 (diff) |
sandboxed user algorithm
Diffstat (limited to 'source')
-rw-r--r-- | source/common.hpp | 61 | ||||
-rw-r--r-- | source/main.cpp | 141 | ||||
-rw-r--r-- | source/samplebuffer.cpp | 52 | ||||
-rw-r--r-- | source/samplebuffer.hpp | 39 |
4 files changed, 198 insertions, 95 deletions
diff --git a/source/common.hpp b/source/common.hpp deleted file mode 100644 index 876cf74..0000000 --- a/source/common.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#include <array> -#include <cstdint> - -using Sample = uint16_t; - -// gives 8000 -constexpr unsigned int MAX_SAMPLE_BUFFER_BYTESIZE = 16384; -constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = MAX_SAMPLE_BUFFER_BYTESIZE / sizeof(Sample); - -class SampleBuffer -{ -public: - SampleBuffer(Sample *buffer) : - m_buffer(buffer) {} - - void clear() { - std::fill(m_buffer, m_buffer + m_size, 2048); - } - void modify(Sample *data, unsigned int srcsize) { - auto size = srcsize < m_size ? srcsize : m_size; - std::copy(data, data + size, m_buffer); - m_modified = m_buffer; - } - void midmodify(Sample *data, unsigned int srcsize) { - auto size = srcsize < m_size / 2 ? srcsize : m_size / 2; - std::copy(data, data + size, middata()); - m_modified = middata(); - } - - void setSize(unsigned int size) { - m_size = size < MAX_SAMPLE_BUFFER_SIZE ? size : MAX_SAMPLE_BUFFER_SIZE; - } - - Sample *data() { - return m_buffer; - } - Sample *middata() { - return m_buffer + m_size / 2; - } - uint8_t *bytedata() { - return reinterpret_cast<uint8_t *>(m_buffer); - } - - Sample *modified() { - auto m = m_modified; - m_modified = nullptr; - return m; - } - unsigned int size() const { - return m_size; - } - unsigned int bytesize() const { - return m_size * sizeof(Sample); - } - -private: - Sample *m_buffer = nullptr; - unsigned int m_size = MAX_SAMPLE_BUFFER_SIZE; - Sample *m_modified = nullptr; -}; - diff --git a/source/main.cpp b/source/main.cpp index 97612f4..1a89c93 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -15,13 +15,12 @@ static_assert(sizeof(adcsample_t) == sizeof(uint16_t)); static_assert(sizeof(dacsample_t) == sizeof(uint16_t)); -#include "common.hpp" -#include "error.hpp" - #include "adc.hpp" #include "cordic.hpp" #include "dac.hpp" #include "elf_load.hpp" +#include "error.hpp" +#include "samplebuffer.hpp" #include "sclock.hpp" #include "usbserial.hpp" @@ -45,30 +44,44 @@ static RunStatus run_status = RunStatus::Idle; #define MSG_FOR_FIRST(m) (m & 1) #define MSG_FOR_MEASURE(m) (m > 2) -static msg_t conversionMBBuffer[4]; -static MAILBOX_DECL(conversionMB, conversionMBBuffer, 4); +static ErrorManager EM; -static THD_WORKING_AREA(conversionThreadWA, 2048); +static msg_t conversionMBBuffer[2]; +static MAILBOX_DECL(conversionMB, conversionMBBuffer, 2); + +// Thread for LED status and wakeup hold +static THD_WORKING_AREA(monitorThreadWA, 128); +static THD_FUNCTION(monitorThread, arg); +// Thread for managing the conversion task +static THD_WORKING_AREA(conversionThreadMonitorWA, 128); +static THD_FUNCTION(conversionThreadMonitor, arg); +// Thread for unprivileged algorithm execution +static THD_WORKING_AREA(conversionThreadWA, 128); static THD_FUNCTION(conversionThread, arg); +__attribute__((section(".convdata"))) +static THD_WORKING_AREA(conversionThreadUPWA, 256); -static time_measurement_t conversion_time_measurement; - -static ErrorManager EM; +static thread_t *conversionThreadHandle = nullptr; +__attribute__((section(".convdata"))) +static thread_t *conversionThreadMonitorHandle = nullptr; +__attribute__((section(".convdata"))) +static time_measurement_t conversion_time_measurement; +__attribute__((section(".convdata"))) static SampleBuffer samplesIn (reinterpret_cast<Sample *>(0x38000000)); // 16k +__attribute__((section(".convdata"))) static SampleBuffer samplesOut (reinterpret_cast<Sample *>(0x30004000)); // 16k + static SampleBuffer samplesSigGen (reinterpret_cast<Sample *>(0x30000000)); // 16k static unsigned char elf_file_store[MAX_ELF_FILE_SIZE]; +__attribute__((section(".convdata"))) static ELF::Entry elf_entry = nullptr; static void signal_operate(adcsample_t *buffer, size_t count); static void signal_operate_measure(adcsample_t *buffer, size_t count); static void main_loop(); -static THD_WORKING_AREA(waThread1, 128); -static THD_FUNCTION(Thread1, arg); - int main() { // Initialize the RTOS @@ -80,6 +93,26 @@ int main() // Enable FPU SCB->CPACR |= 0xF << 20; + // Set up MPU for user algorithm + // Region 2: Data for algorithm manager thread + mpuConfigureRegion(MPU_REGION_2, + 0x20000000, + MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_SIZE_4K | + MPU_RASR_ENABLE); + // Region 3: Code for algorithm manager thread + mpuConfigureRegion(MPU_REGION_3, + 0x08080000, + MPU_RASR_ATTR_AP_RO_RO | MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_SIZE_4K | + MPU_RASR_ENABLE); + // Region 4: Algorithm code + mpuConfigureRegion(MPU_REGION_4, + 0x00000000, + MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_SIZE_64K | + MPU_RASR_ENABLE); + ADC::begin(); DAC::begin(); SClock::begin(); @@ -90,9 +123,14 @@ int main() ADC::setRate(SClock::Rate::R32K); chTMObjectInit(&conversion_time_measurement); - chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, nullptr); - chThdCreateStatic(conversionThreadWA, sizeof(conversionThreadWA), - NORMALPRIO, conversionThread, nullptr); + chThdCreateStatic(monitorThreadWA, sizeof(monitorThreadWA), + NORMALPRIO, monitorThread, nullptr); + conversionThreadMonitorHandle = chThdCreateStatic( + conversionThreadMonitorWA, sizeof(conversionThreadMonitorWA), + NORMALPRIO, conversionThreadMonitor, nullptr); + conversionThreadHandle = chThdCreateStatic( + conversionThreadWA, sizeof(conversionThreadWA), + NORMALPRIO + 1, conversionThread, nullptr); main_loop(); } @@ -278,35 +316,47 @@ void conversion_abort() run_status = RunStatus::Idle; } -THD_FUNCTION(conversionThread, arg) +THD_FUNCTION(conversionThreadMonitor, arg) { (void)arg; - while (1) { // Recover from algorithm fault if necessary - if (run_status == RunStatus::Recovering) - conversion_abort(); + //if (run_status == RunStatus::Recovering) + // conversion_abort(); + + msg_t message; + if (chMBFetchTimeout(&conversionMB, &message, TIME_INFINITE) == MSG_OK) + chMsgSend(conversionThreadHandle, message); + } +} + +__attribute__((section(".convcode"))) +static void convThdMain(); +THD_FUNCTION(conversionThread, arg) +{ + (void)arg; + elf_entry = nullptr; + port_unprivileged_jump(reinterpret_cast<uint32_t>(convThdMain), + reinterpret_cast<uint32_t>(conversionThreadUPWA) + 256); +} + +void convThdMain() +{ + while (1) { msg_t message; - if (chMBFetchTimeout(&conversionMB, &message, TIME_INFINITE) == MSG_OK) { - static Sample *samples = nullptr; - static unsigned int size = 0; - samples = MSG_FOR_FIRST(message) ? samplesIn.data() : samplesIn.middata(); - size = samplesIn.size() / 2; + asm("svc 0; mov %0, r0" : "=r" (message)); + if (message != 0) { + auto samples = MSG_FOR_FIRST(message) ? samplesIn.data() : samplesIn.middata(); + auto size = samplesIn.size() / 2; if (elf_entry) { if (!MSG_FOR_MEASURE(message)) { - //asm("cpsid i"); - //mpuDisable(); - //port_unprivileged_jump((uint32_t)+[] { - samples = elf_entry(samples, size); - //}, 0xF800); - //mpuEnable(MPU_CTRL_PRIVDEFENA); - //asm("cpsie i"); + samples = elf_entry(samples, size); } else { - chTMStartMeasurementX(&conversion_time_measurement); + //chTMStartMeasurementX(&conversion_time_measurement); samples = elf_entry(samples, size); - chTMStopMeasurementX(&conversion_time_measurement); + //chTMStopMeasurementX(&conversion_time_measurement); } } @@ -340,7 +390,7 @@ void signal_operate_measure(adcsample_t *buffer, [[maybe_unused]] size_t count) ADC::setOperation(signal_operate); } -THD_FUNCTION(Thread1, arg) +THD_FUNCTION(monitorThread, arg) { (void)arg; @@ -380,6 +430,29 @@ THD_FUNCTION(Thread1, arg) extern "C" { __attribute__((naked)) +void port_syscall(struct port_extctx *ctxp, uint32_t n) +{ + switch (n) { + case 0: { + chSysLock(); + chMsgWaitS(); + auto msg = chMsgGet(conversionThreadMonitorHandle); + chMsgReleaseS(conversionThreadMonitorHandle, MSG_OK); + //chSchDoYieldS(); + chSysUnlock(); + ctxp->r0 = msg; + } + break; + default: + while (1); + break; + } + + asm("svc 0"); + while (1); +} + +__attribute__((naked)) void HardFault_Handler() { // Below not working (yet) diff --git a/source/samplebuffer.cpp b/source/samplebuffer.cpp new file mode 100644 index 0000000..6932392 --- /dev/null +++ b/source/samplebuffer.cpp @@ -0,0 +1,52 @@ +#include "common.hpp" + +SampleBuffer::SampleBuffer(Sample *buffer) : + m_buffer(buffer) {} + +void SampleBuffer::clear() { + std::fill(m_buffer, m_buffer + m_size, 2048); +} +__attribute__((section(".convcode"))) +void SampleBuffer::modify(Sample *data, unsigned int srcsize) { + auto size = srcsize < m_size ? srcsize : m_size; + for (Sample *d = data, *s = m_buffer; d != data + size;) + *d++ = *s++; + m_modified = m_buffer; +} +__attribute__((section(".convcode"))) +void SampleBuffer::midmodify(Sample *data, unsigned int srcsize) { + auto size = srcsize < m_size / 2 ? srcsize : m_size / 2; + for (Sample *d = data, *s = middata(); d != data + size;) + *d++ = *s++; + m_modified = middata(); +} + +void SampleBuffer::setSize(unsigned int size) { + m_size = size < MAX_SAMPLE_BUFFER_SIZE ? size : MAX_SAMPLE_BUFFER_SIZE; +} + +__attribute__((section(".convcode"))) +Sample *SampleBuffer::data() { + return m_buffer; +} +__attribute__((section(".convcode"))) +Sample *SampleBuffer::middata() { + return m_buffer + m_size / 2; +} +uint8_t *SampleBuffer::bytedata() { + return reinterpret_cast<uint8_t *>(m_buffer); +} + +Sample *SampleBuffer::modified() { + auto m = m_modified; + m_modified = nullptr; + return m; +} +__attribute__((section(".convcode"))) +unsigned int SampleBuffer::size() const { + return m_size; +} +unsigned int SampleBuffer::bytesize() const { + return m_size * sizeof(Sample); +} + diff --git a/source/samplebuffer.hpp b/source/samplebuffer.hpp new file mode 100644 index 0000000..9aabfdd --- /dev/null +++ b/source/samplebuffer.hpp @@ -0,0 +1,39 @@ +#ifndef SAMPLEBUFFER_HPP_ +#define SAMPLEBUFFER_HPP_ + +#include <array> +#include <cstdint> + +using Sample = uint16_t; + +// gives 8000 +constexpr unsigned int MAX_SAMPLE_BUFFER_BYTESIZE = 16384; +constexpr unsigned int MAX_SAMPLE_BUFFER_SIZE = MAX_SAMPLE_BUFFER_BYTESIZE / sizeof(Sample); + +class SampleBuffer +{ +public: + SampleBuffer(Sample *buffer); + + void clear(); + + void modify(Sample *data, unsigned int srcsize); + void midmodify(Sample *data, unsigned int srcsize); + Sample *modified(); + + Sample *data(); + Sample *middata(); + uint8_t *bytedata(); + + void setSize(unsigned int size); + unsigned int size() const; + unsigned int bytesize() const; + +private: + Sample *m_buffer = nullptr; + unsigned int m_size = MAX_SAMPLE_BUFFER_SIZE; + Sample *m_modified = nullptr; +}; + +#endif // SAMPLEBUFFER_HPP_ + |