Fix crash by implementing a custom malloc

Ref https://surma.dev/things/c-to-webassembly/
This commit is contained in:
Starbeamrainbowlabs 2024-12-13 03:06:32 +00:00
parent 84b29f542c
commit 609ce12302
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 65 additions and 48 deletions

View file

@ -1,3 +1,8 @@
# osfs-wasm # osfs-wasm
Compiling the Over-Simplified FileSystem to WASM for fun and profit > Compiling the Over-Simplified FileSystem to WASM for fun and profit
EEPROM sizes, ref <https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8867-SEEPROM-Products-Brochure.pdf> (which suggests kilo**bit**s?!) and <http://ww1.microchip.com/downloads/en/DeviceDoc/21189f.pdf> (which suggests KiB)

View file

@ -31,15 +31,15 @@ task_begin "Compile";
echo -e ">>> Working directory is ${HC}${PWD}${RS}" >&2; echo -e ">>> Working directory is ${HC}${PWD}${RS}" >&2;
execute clang -v -v -v --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry \ execute clang --target=wasm32 -nostdlib -Wl,--export-all -Wl,--no-entry \
-I"${dirpath_include}" \ -I"${dirpath_include}" \
-I "${dirpath_walloc}" \ -I "${dirpath_walloc}" \
-I "${dirpath_osfs}" \ -I "${dirpath_osfs}" \
-o "${dirpath_output}/osfs.wasm" \ -o "${dirpath_output}/osfs.wasm" \
"${dirpath_walloc}/walloc.c" \
"${dirpath_osfs}/OSFS.cpp" \ "${dirpath_osfs}/OSFS.cpp" \
"${dirpath_include}/wrapper.cpp" \ "${dirpath_include}/wrapper.cpp" \
; ;
# "${dirpath_walloc}/walloc.c" \
task_end "${?}"; task_end "${?}";

View file

@ -1,6 +1,27 @@
#include "Arduino.h" #include "Arduino.h"
#include "OSFS.h" #include "OSFS.h"
#include <walloc.h>
// -------------------------------------------------------------------------
// Custom malloc implementation
// Initial design ref https://surma.dev/things/c-to-webassembly/ → Building an
// allocator
// This started as a simple bump allocator, but we've turned it into a singleton
// allocator that always allocates the same area of memory, since we only want to allocate a single area of memory
extern unsigned char __heap_base;
unsigned int bump_pointer = (unsigned int)&__heap_base;
void *malloc(int n) {
unsigned int r = bump_pointer; // This works because the heap grows *upwards* in WASM, not downwards
// bump_pointer += n;
return (void *)r;
}
void free(void *p) {
// lol
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -51,18 +72,18 @@ OSFS::result result;
uint16_t OSFS::startOfEEPROM = 1; uint16_t OSFS::startOfEEPROM = 1;
uint16_t OSFS::endOfEEPROM = 64; // change w/set_eeprom_size uint16_t OSFS::endOfEEPROM = 64; // change w/set_eeprom_size
byte *memory = (byte*)malloc((size_t)(64 * 1024)); // virtual EEPROM, default 64KiB byte *memory = (byte*)malloc((size_t)(64 * 1024)); // virtual EEPROM, default 64KiB
void __clear_memory(uint32_t size) {
memset(memory, 0, (size_t)(size * 1024));
}
void __create_memory(uint32_t size) { void __create_memory(uint32_t size) {
free((void *)memory); free((void *)memory);
void *memory_raw = malloc((size_t)(size * 1024)); void *memory_raw = malloc((size_t)(size * 1024));
memory = (byte *)memory_raw; memory = (byte *)memory_raw;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Error handling // Error handling
@ -71,9 +92,7 @@ void __create_memory(uint32_t size) {
int last_error = 0; int last_error = 0;
int get_last_error() { int get_last_error() { return last_error; }
return last_error;
}
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -90,14 +109,8 @@ void set_eeprom_size(uint16_t new_size) {
__create_memory(new_size); __create_memory(new_size);
} }
uint16_t get_eeprom_size() { uint16_t get_eeprom_size() { return OSFS::endOfEEPROM; }
return OSFS::endOfEEPROM; uint32_t get_eeprom_size_bytes() { return OSFS::endOfEEPROM * 1024; }
}
uint32_t get_eeprom_size_bytes() {
return OSFS::endOfEEPROM * 1024;
}
void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output) { void OSFS::readNBytes(uint16_t address, unsigned int num, byte *output) {
// eeprom.read(address, output, num); // eeprom.read(address, output, num);
@ -111,7 +124,6 @@ void OSFS::readNBytes(uint16_t address, unsigned int num, byte* output) {
for (unsigned int i = 0; i < num; i++) { for (unsigned int i = 0; i < num; i++) {
output[i] = memory[address + i]; output[i] = memory[address + i];
} }
} }
void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input) { void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input) {
// eeprom.write(address, input, num); // eeprom.write(address, input, num);