/* Port-specific settings (override port settings defaulted in chcore.h). */\r
/*===========================================================================*/\r
\r
+// Enable syscall support\r
+#define PORT_USE_SYSCALL TRUE\r
+\r
#endif /* CHCONF_H */\r
\r
/** @} */\r
static const char *makefile_text = R"make(
all:
- @arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE -c $0 -o $0.o
- @arm-none-eabi-ld -shared -n -N -z max-page-size=512 -Ttext-segment=0 \
- $0.o -o $0.so
- @arm-none-eabi-strip -s -S --strip-unneeded $0.so
- @arm-none-eabi-objcopy --remove-section .dynsym \
- --remove-section .dynstr \
- --remove-section .dynamic \
- --remove-section .hash \
- --remove-section .ARM.exidx \
- --remove-section .ARM.attributes \
- --remove-section .comment \
- $0.so
+ @arm-none-eabi-g++ -x c++ -mcpu=cortex-m4 -mthumb -Os --specs=nosys.specs -nostartfiles -fPIE $0 -o $0.o -Wl,-Ttext-segment=0 -Wl,-eprocess_data_entry -Wl,-zmax-page-size=512
+ @arm-none-eabi-strip -s -S --strip-unneeded $0.o
+ @arm-none-eabi-objcopy --remove-section .ARM.exidx \
+ --remove-section .ARM.attributes \
+ --remove-section .comment \
+ --remove-section .noinit \
+ $0.o
)make";
static const char *file_header = R"cpp(
using adcsample_t = uint16_t;
-__attribute__((section(".process_data"))) void process_data(adcsample_t *samples, unsigned int size);
+static void process_data(adcsample_t *samples, unsigned int size);
-// End stmdspgui header code
+__attribute__((optimize("-O0")))
+static void *alloc(unsigned int count) {
+ void *result = nullptr;
+ asm("mov r0, %0; mov r1, %1; svc 0" :: "r" (&result), "r" (count));
+ return result;
+}
+extern "C" void process_data_entry() {
+ auto func = (void (*)())process_data;
+ func();
+}
+
+// End stmdspgui header code
)cpp";
wxString MainFrame::compileEditorCode()
wxString make_command = wxString("make -C ") + file_name.BeforeLast('/') +
" -f " + file_name + "make";
if (system(make_command.ToAscii()) == 0)
- return file_name + ".so";
+ return file_name + ".o";
else
return "";
}
// [elf_load_offset](auto func) { (func + elf_load_offset)(); });
//}
- // Find filter code start
- if (auto filter = find_section(ehdr, ".process_data"); filter)
- return ptr_from_offset<entry_t>(elf_load_offset, filter->sh_addr | 1); // OR 1 to enable thumb
- else
- return nullptr;
+ return ptr_from_offset<entry_t>(elf_load_offset, ehdr->e_entry);
}
} // namespace elf
Elf32_Shdr *find_section(Elf32_Ehdr *ehdr, const char *name)
{
- auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff);
- auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr,
+ auto shdr = ptr_from_offset<Elf32_Shdr *>(ehdr, ehdr->e_shoff);
+ auto shdr_str = ptr_from_offset<Elf32_Shdr *>(ehdr,
ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
- for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) {
- char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name;
- if (!strcmp(section, name))
- return shdr;
+ for (Elf32_Half i = 0; i < ehdr->e_shnum; i++) {
+ char *section = ptr_from_offset<char *>(ehdr, shdr_str->sh_offset) + shdr->sh_name;
+ if (!strcmp(section, name))
+ return shdr;
- shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize);
- }
+ shdr = ptr_from_offset<Elf32_Shdr *>(shdr, ehdr->e_shentsize);
+ }
- return 0;
+ return 0;
}
}
}
+void quick_freeall();
+
void signal_operate(adcsample_t *buffer, size_t count)
{
- if (elf_entry)
+ if (elf_entry) {
elf_entry(buffer, count);
+ quick_freeall();
+ }
+
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];
}
+// Dynamic memory allocation below
+
+uint8_t quick_malloc_heap[8192];
+uint8_t *quick_malloc_next = quick_malloc_heap;
+
+void *quick_malloc(unsigned int size)
+{
+ if (auto free = std::distance(quick_malloc_next, quick_malloc_heap + 8192); free < 0 || size > static_cast<unsigned int>(free))
+ return nullptr;
+
+ auto ptr = quick_malloc_next;
+ quick_malloc_next += size;
+ return ptr;
+}
+
+void quick_freeall()
+{
+ if (quick_malloc_next != quick_malloc_heap)
+ quick_malloc_next = quick_malloc_heap;
+}
+
+void port_syscall(struct port_extctx *ctxp, uint32_t n)
+{
+ switch (n) {
+ case 0:
+ *reinterpret_cast<void **>(ctxp->r0) = quick_malloc(ctxp->r1);
+ break;
+ case 1:
+ quick_freeall();
+ break;
+ }
+
+ chSysHalt("svc");
+}
+