Colibri WebAssembly Notes

From Stm32World Wiki
Jump to navigation Jump to search

Various notes, investigations and other useful information that might be needed later.

Zephyr Mutexes

I now have a case where the a zephyr mutex was set up in main(), and later called from a different Zephyr thread, and immediately crashes.

   k_mutex_lock(&data->lock, K_FOREVER);

That is an inlined function of

   __pinned_func
   static inline int k_mutex_lock(struct k_mutex * mutex, k_timeout_t timeout)
   {
       compiler_barrier();
       return z_impl_k_mutex_lock(mutex, timeout);
   }

And compiler_barrier() expands to

   do { __asm__ __volatile__ ("" ::: "memory"); }
   while (0);

on the STM32.

I am now moving code around to ensure that it is always the same thread calling the mutex.

Hmmm... Now instead completely crashing, it is ending up in

   void arch_system_halt(unsigned int reason){}

with a reason=4, which is K_ERR_KERNEL_PANIC

Call stack reveals nothing.

   arch_system_halt fatal.c:30
   k_sys_fatal_error_handler fatal.c:44
   z_fatal_error fatal.c:119
   z_arm_fatal_error fatal.c:93
   z_arm_fault fault.c:1090
   z_arm_usage_fault fault_s.S:103
   assert_post_action assert.c:44
   z_spinlock_validate_pre spinlock.h:132
   k_spin_lock spinlock.h:192
   z_unpend1_no_timeout sched.c:717
   z_impl_k_timer_stop timer.c:276
   z_log_msg_post_finalize log_core.c:195
   msg_commit log_core.c:717
   z_log_msg_commit log_core.c:723
   z_log_msg_finalize log_msg.c:54
   z_log_msg_simple_create log_msg.c:130
   z_impl_z_log_msg_simple_create_1 log_msg.c:229
   esf_dump fatal.c:67
   z_arm_fatal_error fatal.c:76
   z_do_kernel_oops fatal.c:141
   z_arm_svc svc.S:158


Need more work here...

CMake for I/O drivers

It is crucial that the wasm binary is stripped of all meta data. This is an example of a reasonable CMakeLists.txt for the Colibri DIO1 module.

   cmake_minimum_required(VERSION 3.5)
   set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)
   project(io_dio1 C)
   
   set(CMAKE_C_STANDARD 11)
   set(CMAKE_C_COMPILER clang)
   
   include_directories(colibri-sdk/)
   
   add_executable(io_dio1 dio1.c)
   set_target_properties(io_dio1 PROPERTIES SUFFIX ".wasm")
   
   target_compile_options(io_dio1 PRIVATE
           --target=wasm32
           -Oz
           -ffunction-sections
           -fdata-sections
   )
   
   target_link_options(io_dio1 PRIVATE
           --target=wasm32-unknown-unknown-wasm  # or just =wasm
           -nostdlib
           -Wl,--no-entry
           -Wl,--allow-undefined
           -Wl,--gc-sections
           -Wl,--strip-all
   
           # Exports
           -Wl,--export=event
           -Wl,--export=init
           -Wl,--export=loaded
           -Wl,--export=unloading
   
           # Memory Management
           -Wl,--import-memory        # Host provides the memory
           -Wl,--initial-memory=65536 # Request 2 pages (required for standard compliance)
           -Wl,--max-memory=65536     # Cap it at 2 pages
           -Wl,-z,stack-size=512      # Shrink WASM-internal stack (Default is often 64KB!)
   )
   
   add_custom_command(
           TARGET io_dio1 POST_BUILD
           COMMAND xxd -i -n io_dio1 ${CMAKE_BINARY_DIR}/io_dio1/io_dio1.wasm | sed 's/unsigned /const unsigned /' >${CMAKE_BINARY_DIR}/io_dio1.h
           WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
           COMMENT "Generating io_dio1.h from io_dio1.wasm using xxd"
   )
   

Memory Allocations

This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.


   ---- Program to be loaded  ----
   
   
   #include "colibri.h"
   #define export __attribute__((visibility("default")))
   
   static int next = 0;
   static int state = 0;
   
   int tick(long time) {
       if (next < time) {
           if (state){
               set_rgb_error();
               next = time + 100;
           }
           else {
               set_rgb_off();
               next = time + 500;
           }
       }
       return state;
   }
   
   export void event(int id, long value) {
       tick(value);
   }
   
   export void init() {
       set_rgb_ok_color(0x000400);
       set_rgb_warning_color(0x040400);
       set_rgb_error_color(0x080000);
   }
   
   export void loaded() {
       set_rgb_off();
   }
   
   export void unloading() {
       set_rgb_off();
   }
   
   Env      Heap @ 0x10000000    112  bytes
   wasm0    Heap @ 0x10000070    4960 bytes
   wasm1    Heap @ 0x100013D0    4368 bytes
   wasm2    Heap @ 0x100024E0    4368 bytes
   wasm3    Heap @ 0x100035f0    4368 bytes
   wasm4    Heap @ 0x10004700    4608 bytes
   wasm5    Heap @ 0x10005900    4368 bytes
   wasm6    Heap @ 0x10006a10    4368 bytes
   wasm7    Heap @ 0x10007b20    5200 bytes
   End      Heap @ 0x10008F70
   
   ----- Once -----
   NewEnvironment
       M3Environment struct    0x20
       AllocFuncType           0x09
       AllocFuncType           0x09
       AllocFuncType           0x09
       AllocFuncType           0x09
       AllocFuncType           0x09
       
   -----  Per wasm  ---
   
   NewRuntime
       M3Runtime  struct       0x434
       runtime->origStack      0x410  (stack + 4 32bit words)        
       
   ParseModule
       M3Module    module      0x78
       io_module->functTypes   0x0c
       AllocFuncType           0x08
       Free
       AllocFuncType           0x09
       Free
       AllocFuncType           0x0A
       Free
       PreAllocFunctions       0x154  (5 functions * 68 bytes?)
       "env"                   0x04   
       "memory"                0x07
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       "env"                   0x04   
       "set_rgb_off"           0x0C
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       "env"                   0x04   
       "set_rgb_ok_color"      0x11
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       "env"                   0x04   
       "set_rgb_warning_color" 0x16
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       "env"                   0x04   
       "set_rgb_error_color"   0x14
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       Free NULL                       (freeing import, module name)
       Free NULL                       (freeing import, field name)
       PreAllocFunctions       0x220  
       AddGlobal               0x20
       "event"                 0x06    (exports)
       Free NULL                       (exported name)                       
       "init"                  0x05
       Free NULL                       (exported name)                       
       "loaded"                0x07
       Free NULL                       (exported name)                       
       "unloading"             0x0A
       Free NULL                       (exported name)                       
       Free NULL                       (one extra exported name)                       
       M3DataSegments          0x20    (0 data segment)
       
   LoadModule
       NewCodePage             0x40
       Free NULL
       Free NULL
       Free NULL
       Free NULL
       AllocFuncType           0x09
       Free 
       AllocFuncType           0x09
       Free 
       AllocFuncType           0x09
       Free 
       AllocFuncType           0x09
       Free 
       AllocFuncType           0x09
       Free 
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       CompileFunction         0x08    ("event")
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       CompileFunction         0x12    ("init")
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       NewCodePage             0x40
       CompileFunction         0x14