Skip to content

Commit

Permalink
Introducing relocatable library loading
Browse files Browse the repository at this point in the history
* Introducing relocatable library loading

Using an relocatable elf loader, patches and modules can be loaded to arbitrary
memory locations. Position-independent ELFs are not supported.
This enables running multiple patches simultaneously.

Referencing dynamic loading libraries is not possible with relocatable
libraries. So a mechanism was needed to locate a library providing a missing
symbol. The approach taken is prefixing exported symbols with the library name
and one underscore. So loading a dynamic library containing an unreferenced
symbol `lib1_factory` causes the loader to load `/lib/lib1.elf` and look inside
for the symbol `lib1_facory`.
This does not work for C++ function names as they are mangled. Prefixing a
function name in C++ does not prefix the corresponding symbol name.
So in order to use C++ function in dynamic loaded libraries, an `extern "C"`
declaration is required. Exported classes need to be pure virtual.

Uploading a patch into flash does not include any referenced dynamic libraries,
so an sdcard will be required for those cases.

* No more hard-linking

Patches used to hard-link with the firmware. That broke patches when the
firmware is changed, those had to be compiled again. Now patches only link to
API symbols, those have a longer lifetime.

* Introducing separation between firmware and API

Every symbol in firmware was exposed to patches. Now there is a separate `api`
directory containing declarations that can be used in patches.

* Dynamic memory allocation

Patch memory usage was statically allocated, the benefit is that if a patch
compiles, it 'd be certain to execute too.
Now patches that occupy more memory than is available will only fail during
loading.

* Memory fragmentation

It is possible to load patch A and then patch B. But when patch A is stopped
and patch C is started, it is possible that there is not enough continuous space
for patch C, even when patch B and C could run simultaneously. The best approach
is to stop patch B too when patch A is stopped. This is currently not enforced.
The alternative approach (not implemented) is to partition memory into segments
so that a certain fixed number of patches can always run.
But that 'd prevent one patch to use more memory than a quarter if the
partitioning is for four patches.

The memory fragmentation problem can be mitigated by modifying objects that 'd
allocate a significant percentage of continuous memory (say, 4MB of sdram) into
objects that allocate multiple blocks (say, 16 blocks of 256KB each).

* Patches used to run with a subdirectory as its working directory

This conflicts with the possibility of running multiple patches run
simultaneously, so this is no longer the case. Absolute filenames are strongly
recommended now.

* GPIO pin modes

GPIO pin modes were reset when a patch is loaded. This conflicts with running
multiple patches, and no longer the case. It is the sole responsibility of
objects to restore their configuration when disposed.

* USB protocol

Cleaned up, incompatible with previous experimental releases.
Automatic upgrading from release 1.0.12 and downgrading to 1.0.12 is supported.

* Mutable instruments' objects

Moved out of firmware, currently broken, need to be re-implemented as dynamic
libraries.

* Removed "Controller objects"

Controller objects were conceived to integrate a patch loading scheme in every
other patch. Since multiple patches can load, one "master" patch can load other
patches (perhaps responding to midi program changes). Examples are yet to be
made.
  • Loading branch information
JohannesTaelman committed Oct 8, 2019
1 parent f07b476 commit 4e66442
Show file tree
Hide file tree
Showing 609 changed files with 36,957 additions and 161,773 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Expand Up @@ -12,7 +12,7 @@ Makefile eol=lf
*.pdf binary
*.exe binary
*.tar binary
*.a binary

*.axp text diff=html
*.axo text diff=html

3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "firmware/elfloader"]
path = firmware/elfloader
url = https://github.com/JohannesTaelman/elfloader
8 changes: 4 additions & 4 deletions Axoloti.sh
Expand Up @@ -26,16 +26,16 @@ which java >/dev/null || echo "java not found in path"

marlin_jvmargs='-Xbootclasspath/a:lib/marlin-0.9.1-Unsafe.jar -Dsun.java2d.renderer=org.marlin.pisces.MarlinRenderingEngine'

if [ -f $rootdir/dist/Axoloti.jar ]
if [ -f "$rootdir/dist/Axoloti.jar" ]
then
case "$platform" in
mac)
echo java $marlin_jvmargs -Xdock:name=Axoloti -jar $rootdir/dist/Axoloti.jar $*
java $marlin_jvmargs -Xdock:name=Axoloti -jar $rootdir/dist/Axoloti.jar $* 2>&1 | tee "$axoloti_home/axoloti.log"
echo java $marlin_jvmargs -Xdock:name=Axoloti -jar "$rootdir/dist/Axoloti.jar" $*
java $marlin_jvmargs -Xdock:name=Axoloti -jar "$rootdir/dist/Axoloti.jar" $* 2>&1 | tee "$axoloti_home/axoloti.log"
;;
linux)
echo java $marlin_jvmargs -jar $rootdir/dist/Axoloti.jar $*
java $marlin_jvmargs -jar $rootdir/dist/Axoloti.jar $* 2>&1 | tee "$axoloti_home/axoloti.log"
java $marlin_jvmargs -jar "$rootdir/dist/Axoloti.jar" $* 2>&1 | tee "$axoloti_home/axoloti.log"
;;
esac
else
Expand Down
133 changes: 0 additions & 133 deletions CMSIS/DSP_Lib/Include/arm_common_tables.h

This file was deleted.

79 changes: 0 additions & 79 deletions CMSIS/DSP_Lib/Include/arm_const_structs.h

This file was deleted.

0 comments on commit 4e66442

Please sign in to comment.