WebAssembly

介绍

WebAssembly,简称 Wasm,是一种面向编译目标的、可移植的二进制指令格式及其执行规范。

Wasm 是一个编译目标,可以使用 C/C++、Rust、Go 等语言写代码,然后编译成 .wasm 文件,然后通过 Wasm 运行时加载并执行。

在嵌入式系统中,Wasm Runtime 可以运行在 MCU 上,由 MCU 为 Wasm 模块提供必要的 Host API。

1
2
3
4
5
6
7
8
9
+-------+    Wasm Compiler    +-------+  Load / Execute  +--------------+
| C/C++ | ------------+-----> | .wasm | ---------------> | Wasm Runtime |
+-------+             |       +-------+                  +--------------+
                      |                                         |
 +------+             |                                         | Host Function
 | Rust | ------------+                                         v
 +------+                                                    +-----+
                                                             | MCU |
                                                             +-----+

Wasm Runtime

Wasm Runtime 负责加载、验证、实例化和执行 Wasm 模块,并可以将 MCU 提供的功能注册为 Host Function,使 Wasm 模块能够访问有限的硬件或系统功能。

在当前的嵌入式开发中主要是使用 C/C++,所以我们一般是使用 C 语言编写的 Wasm Runtime。

当前主流的 Wasm Runtime 有:

当前验证使用的是 WAMR-2.4.5。

MSYS2

环境:

  • Windows 10 64-bit 家庭版(22H2)
  • 终端:MSYS2(3.6.9-01d6c708.x86_64 2026-05-24)
  • 工具链:gcc version 15.3.0
  • 构建工具:Makefile

这里的测试只开启了解释器功能。

  • Makefile 如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    
    #
    # Makefile
    #
    # SPDX-License-Identifier: Apache-2.0
    # SPDX-FileCopyrightText: 2026 Zeepunt
    
    Q := @
    
    ifeq ($(V),1)
    	quiet =
    	cmd = $(cmd_$(1))
    else
    	quiet = quiet_
    	cmd = $(Q)$(if $(quiet_cmd_$(1)),echo '  $(quiet_cmd_$(1))' &&) $(cmd_$(1))
    endif
    
    BUILD_DIR := build
    
    TARGET    := main
    
    CC_PREFIX :=
    AS        := $(CC_PREFIX)as
    CC        := $(CC_PREFIX)gcc
    LD        := $(CC_PREFIX)ld
    NM        := $(CC_PREFIX)nm
    AR        := $(CC_PREFIX)ar
    OBJCOPY   := $(CC_PREFIX)objcopy
    OBJDUMP   := $(CC_PREFIX)objdump
    SIZE      := $(CC_PREFIX)size
    STRIP     := $(CC_PREFIX)strip
    
    ELF := $(BUILD_DIR)/$(TARGET).elf
    MAP := $(BUILD_DIR)/$(TARGET).map
    
    CFLAGS := \
    	-std=c11 \
    	-g \
    	-O0
    
    CFLAGS += \
    	-fdata-sections \
    	-ffunction-sections
    
    # _DEFAULT_SOURCE 用于开启 glibc 的所有扩展声明
    # MSYS2 的 libc 没有 MAP_32BIT, 这里需要添加
    CFLAGS += \
    	-D_GNU_SOURCE \
    	-DMAP_32BIT=0
    
    LDFLAGS := \
    	-Wl,-Map=$(MAP) \
    	-Wl,--gc-sections \
    	-Wl,--print-memory-usage
    
    LDLIBS :=
    
    ####################################################################################
    WAMR_ROOT   := wasm-micro-runtime
    WAMR_CORE   := $(WAMR_ROOT)/core
    
    IWASM_DIR   := $(WAMR_CORE)/iwasm
    SHARED_DIR  := $(WAMR_CORE)/shared
    
    # WAMR compilation flags
    
    ## interpreter
    WAMR_BUILD_INTERP                ?= 1
    ## fast interpreter
    WAMR_BUILD_FAST_INTERP           ?= 1
    ## mini loader
    WAMR_BUILD_MINI_LOADER           ?= 0
    
    ## garbage collection
    WAMR_BUILD_GC                    ?= 0
    ## String reference support
    WAMR_BUILD_STRINGREF             ?= 0
    ## reference types
    WAMR_BUILD_REF_TYPES             ?= 0
    
    ## AoT runtime
    WAMR_BUILD_AOT                   ?= 0
    ## AoT validator
    WAMR_BUILD_AOT_VALIDATOR         ?= 0
    
    ## JIT compilation
    WAMR_BUILD_JIT                   ?= 0
    ## fast JIT
    WAMR_BUILD_FAST_JIT              ?= 0
    ## fast JIT dump
    WAMR_BUILD_FAST_JIT_DUMP         ?= 0
    
    # libc builtin functions
    WAMR_BUILD_LIBC_BUILTIN          ?= 1
    # libc uvwasi compatibility
    WAMR_BUILD_LIBC_UVWASI           ?= 0
    # wasi libc
    WAMR_BUILD_LIBC_WASI             ?= 1
    # module instance context
    WAMR_BUILD_MODULE_INST_CONTEXT   ?= 0
    
    # multi-module support
    WAMR_BUILD_MULTI_MODULE          ?= 0
    
    # copy call stack
    WAMR_BUILD_COPY_CALL_STACK       ?= 0
    
    ## SIMD support
    WAMR_BUILD_SIMD                  ?= 1
    
    ## pthread library
    WAMR_BUILD_LIB_PTHREAD           ?= 0
    ## pthread semaphore support
    WAMR_BUILD_LIB_PTHREAD_SEMAPHORE ?= 0
    
    ## wasi threads
    WAMR_BUILD_LIB_WASI_THREADS      ?= 0
    
    ## debug interpreter
    WAMR_BUILD_DEBUG_INTERP          ?= 0
    
    ifneq ($(filter 1,$(WAMR_BUILD_FAST_JIT) $(WAMR_BUILD_JIT)),)
    WAMR_BUILD_INTERP      := 1
    WAMR_BUILD_FAST_INTERP := 0
    endif
    
    ifeq ($(WAMR_BUILD_JIT),1)
    WAMR_BUILD_AOT := 1
    endif
    
    ifeq ($(WAMR_BUILD_STRINGREF),1)
    WAMR_BUILD_GC := 1
    endif
    
    ifeq ($(WAMR_BUILD_GC),1)
    WAMR_BUILD_REF_TYPES := 1
    endif
    
    ifeq ($(WAMR_BUILD_LIBC_UVWASI),1)
    CFLAGS += -DWASM_ENABLE_MODULE_INST_CONTEXT=1
    
    WAMR_BUILD_MODULE_INST_CONTEXT := 1
    else ifeq ($(WAMR_BUILD_LIBC_WASI),1)
    CFLAGS += -DWASM_ENABLE_MODULE_INST_CONTEXT=1
    
    WAMR_BUILD_MODULE_INST_CONTEXT := 1
    endif
    
    ifeq ($(WAMR_BUILD_LIB_PTHREAD_SEMAPHORE),1)
    WAMR_BUILD_LIB_PTHREAD := 1
    endif
    
    ####################################################################################
    
    # WAMR iwasm
    IWASM_INCLUDE := -I$(IWASM_DIR)/include
    IWASM_SOURCE  :=
    
    ## common
    WAMR_DISABLE_APP_ENTRY           ?= 0
    WAMR_BUILD_INVOKE_NATIVE_GENERAL ?= 0
    
    IWASM_INCLUDE += -I$(IWASM_DIR)/common
    
    CFLAGS += -DBH_MALLOC=wasm_runtime_malloc
    CFLAGS += -DBH_FREE=wasm_runtime_free
    
    IWASM_SOURCE += \
    	$(IWASM_DIR)/common/wasm_blocking_op.c \
    	$(IWASM_DIR)/common/wasm_c_api.c \
    	$(IWASM_DIR)/common/wasm_exec_env.c \
    	$(IWASM_DIR)/common/wasm_loader_common.c \
    	$(IWASM_DIR)/common/wasm_memory.c \
    	$(IWASM_DIR)/common/wasm_native.c \
    	$(IWASM_DIR)/common/wasm_runtime_common.c \
    	$(IWASM_DIR)/common/wasm_shared_memory.c
    
    ifeq ($(WAMR_BUILD_INTERP),1)
    IWASM_SOURCE += $(IWASM_DIR)/common/wasm_application.c
    endif
    
    ifeq ($(WAMR_BUILD_INVOKE_NATIVE_GENERAL),1)
    IWASM_SOURCE += $(IWASM_DIR)/common/arch/invokeNative_general.c
    else
    ifeq ($(WAMR_BUILD_SIMD),1)
    IWASM_SOURCE += $(IWASM_DIR)/common/arch/invokeNative_mingw_x64_simd.s
    else
    IWASM_SOURCE += $(IWASM_DIR)/common/arch/invokeNative_mingw_x64.s
    endif
    endif
    
    ## interpreter
    ifeq ($(WAMR_BUILD_INTERP),1)
    CFLAGS += -DWASM_ENABLE_INTERP=1
    
    IWASM_INCLUDE += -I$(IWASM_DIR)/interpreter
    
    IWASM_SOURCE += $(IWASM_DIR)/interpreter/wasm_runtime.c
    
    ifeq ($(WAMR_BUILD_FAST_INTERP),1)
    CFLAGS += -DWASM_ENABLE_FAST_INTERP=1
    
    IWASM_SOURCE += $(IWASM_DIR)/interpreter/wasm_interp_fast.c
    else
    IWASM_SOURCE += $(IWASM_DIR)/interpreter/wasm_interp_classic.c
    endif
    
    ifeq ($(WAMR_BUILD_MINI_LOADER),1)
    IWASM_SOURCE += $(IWASM_DIR)/interpreter/wasm_mini_loader.c
    else
    IWASM_SOURCE += $(IWASM_DIR)/interpreter/wasm_loader.c
    endif
    endif
    
    ## fast-jit
    ifeq ($(WAMR_BUILD_FAST_JIT),1)
    endif
    
    ## compilation
    ifeq ($(WAMR_BUILD_JIT),1)
    endif
    
    # aot
    ifeq ($(WAMR_BUILD_AOT),1)
    endif
    
    ## gc
    ifeq ($(WAMR_BUILD_GC),1)
    endif
    
    ## libraries
    ifeq ($(WAMR_BUILD_LIBC_BUILTIN),1)
    CFLAGS += -DWASM_ENABLE_LIBC_BUILTIN=1
    
    IWASM_INCLUDE += -I$(IWASM_DIR)/libraries/libc-builtin
    
    IWASM_SOURCE += $(IWASM_DIR)/libraries/libc-builtin/libc_builtin_wrapper.c
    endif
    
    ifeq ($(WAMR_BUILD_LIBC_UVWASI),1)
    else ifeq ($(WAMR_BUILD_LIBC_WASI),1)
    CFLAGS += -DWASM_ENABLE_LIBC_WASI=1
    
    IWASM_INCLUDE += \
    	-I$(IWASM_DIR)/libraries/libc-wasi \
    	-I$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/include \
    	-I$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/src
    
    IWASM_SOURCE += \
    	$(IWASM_DIR)/libraries/libc-wasi/libc_wasi_wrapper.c \
    	$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/src/blocking_op.c \
    	$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c \
    	$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/src/random.c \
    	$(IWASM_DIR)/libraries/libc-wasi/sandboxed-system-primitives/src/str.c
    endif
    
    ifeq ($(WAMR_BUILD_LIB_PTHREAD),1)
    endif
    
    ifeq ($(WAMR_BUILD_LIB_WASI_THREADS),1)
    endif
    
    ####################################################################################
    
    # WAMR shared
    SHARED_INCLUDE :=
    SHARED_SOURCE  :=
    
    ## platform (Linux)
    CFLAGS += -DBH_PLATFORM_LINUX
    CFLAGS += -DWASM_HAVE_MREMAP=0
    
    SHARED_INCLUDE += \
    	-I$(SHARED_DIR)/platform/include \
    	-I$(SHARED_DIR)/platform/linux \
    	-I$(SHARED_DIR)/platform/common/posix
    
    SHARED_SOURCE += \
    	$(SHARED_DIR)/platform/linux/platform_init.c \
    	$(SHARED_DIR)/platform/common/memory/mremap.c \
    	$(SHARED_DIR)/platform/common/posix/posix_blocking_op.c \
    	$(SHARED_DIR)/platform/common/posix/posix_malloc.c \
    	$(SHARED_DIR)/platform/common/posix/posix_memmap.c \
    	$(SHARED_DIR)/platform/common/posix/posix_sleep.c \
    	$(SHARED_DIR)/platform/common/posix/posix_socket.c \
    	$(SHARED_DIR)/platform/common/posix/posix_thread.c \
    	$(SHARED_DIR)/platform/common/posix/posix_time.c
    
    ifeq ($(WAMR_BUILD_LIBC_WASI),1)
    SHARED_SOURCE += \
    	$(SHARED_DIR)/platform/common/posix/posix_clock.c \
    	$(SHARED_DIR)/platform/common/posix/posix_file.c
    endif
    
    ifneq ($(filter 1,$(WAMR_BUILD_LIBC_WASI) $(WAMR_BUILD_DEBUG_INTERP)),)
    SHARED_INCLUDE += -I$(SHARED_DIR)/platform/common/libc-util
    
    SHARED_SOURCE += $(SHARED_DIR)/platform/common/libc-util/libc_errno.c
    else
    endif
    
    ## mem-alloc
    SHARED_INCLUDE += -I$(SHARED_DIR)/mem-alloc
    
    SHARED_SOURCE += \
    	$(SHARED_DIR)/mem-alloc/mem_alloc.c \
    	$(SHARED_DIR)/mem-alloc/ems/ems_alloc.c \
    	$(SHARED_DIR)/mem-alloc/ems/ems_gc.c \
    	$(SHARED_DIR)/mem-alloc/ems/ems_hmu.c \
    	$(SHARED_DIR)/mem-alloc/ems/ems_kfc.c
    
    ## utils
    SHARED_INCLUDE += \
    	-I$(SHARED_DIR)/utils \
    	-I$(SHARED_DIR)/utils/uncommon
    
    SHARED_SOURCE += \
    	$(SHARED_DIR)/utils/bh_assert.c \
    	$(SHARED_DIR)/utils/bh_bitmap.c \
    	$(SHARED_DIR)/utils/bh_common.c \
    	$(SHARED_DIR)/utils/bh_hashmap.c \
    	$(SHARED_DIR)/utils/bh_leb128.c \
    	$(SHARED_DIR)/utils/bh_list.c \
    	$(SHARED_DIR)/utils/bh_log.c \
    	$(SHARED_DIR)/utils/bh_queue.c \
    	$(SHARED_DIR)/utils/bh_vector.c \
    	$(SHARED_DIR)/utils/runtime_timer.c \
    	$(SHARED_DIR)/utils/uncommon/bh_getopt.c \
    	$(SHARED_DIR)/utils/uncommon/bh_read_file.c
    
    ####################################################################################
    
    WAMR_RUNTIME_LIB_INCLUDE := \
    	${IWASM_INCLUDE} \
    	${SHARED_INCLUDE}
    
    WAMR_RUNTIME_LIB_SOURCE := \
    	${IWASM_SOURCE} \
    	${SHARED_SOURCE}
    
    INCLUDES := \
    	$(WAMR_RUNTIME_LIB_INCLUDE)
    
    SOURCES := \
    	$(WAMR_RUNTIME_LIB_SOURCE) \
    	main.c
    
    OBJS := \
    	$(patsubst %.c,$(BUILD_DIR)/%.o,$(filter %.c,$(SOURCES))) \
    	$(patsubst %.s,$(BUILD_DIR)/%.o,$(filter %.s,$(SOURCES)))
    
    quiet_cmd_as = AS      $<
    cmd_as       = $(CC) $(CFLAGS) -c -o $@ $<
    
    quiet_cmd_cc = CC      $<
    cmd_cc       = $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
    
    quiet_cmd_ld = LD      $(TARGET)
    cmd_ld       = $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)
    
    quiet_cmd_size = SIZE    $(TARGET)
    cmd_size       = $(SIZE) $@
    
    PHONY :=
    PHONY += all
    all: $(ELF)
    
    $(ELF): $(OBJS)
    	$(call cmd,ld)
    	$(call cmd,size)
    
    $(BUILD_DIR)/%.o: %.c | $(BUILD_DIR)
    	$(Q)mkdir -p $(dir $@)
    	$(call cmd,cc)
    
    $(BUILD_DIR)/%.o: %.s | $(BUILD_DIR)
    	$(Q)mkdir -p $(dir $@)
    	$(call cmd,as)
    
    $(BUILD_DIR):
    	$(Q)mkdir -p $(BUILD_DIR)
    
    PHONY += clean
    clean:
    	$(Q)rm -rf $(BUILD_DIR)
    
    PHONY += run
    run: $(ELF)
    	$(Q)$(ELF)
    
    .PHONY: $(PHONY)
    
  • 需要修改以下文件:

    • core/shared/platform/common/posix/posix_file.c

      1
      2
      3
      4
      5
      6
      
      #if !defined(__APPLE__) && !defined(ESP_PLATFORM)
      #define CONFIG_HAS_PWRITEV 0  /* 由 1 改为 0 */
      #define CONFIG_HAS_PREADV 0   /* 由 1 改为 0 */
      #else
      ...
      #endif
      

测试的 main.c 文件:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * main.c
 *
 * SPDX-License-Identifier: Apache-2.0
 * SPDX-FileCopyrightText: 2026 Zeepunt
 */
#include <stdint.h>
#include <stdio.h>

#include "wasm_export.h"
#include "bh_platform.h"

static uint8_t __aligned(4) s_wasm_interp[] = {
    0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x03, 0x60,
    0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x01,
    0x7F, 0x00, 0x02, 0x31, 0x04, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x70, 0x75,
    0x74, 0x73, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x61, 0x6C,
    0x6C, 0x6F, 0x63, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x70, 0x72,
    0x69, 0x6E, 0x74, 0x66, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x66,
    0x72, 0x65, 0x65, 0x00, 0x02, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01,
    0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x13, 0x03,
    0x7F, 0x01, 0x41, 0xC0, 0x28, 0x0B, 0x7F, 0x00, 0x41, 0xBA, 0x08, 0x0B,
    0x7F, 0x00, 0x41, 0xC0, 0x28, 0x0B, 0x07, 0x2C, 0x04, 0x06, 0x6D, 0x65,
    0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74,
    0x61, 0x5F, 0x65, 0x6E, 0x64, 0x03, 0x01, 0x0B, 0x5F, 0x5F, 0x68, 0x65,
    0x61, 0x70, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x04, 0x6D, 0x61,
    0x69, 0x6E, 0x00, 0x04, 0x0A, 0xB2, 0x01, 0x01, 0xAF, 0x01, 0x01, 0x03,
    0x7F, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02,
    0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x9B, 0x88, 0x80, 0x80, 0x00,
    0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x02, 0x40, 0x02, 0x40, 0x41,
    0x80, 0x08, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x0D, 0x00,
    0x41, 0xA8, 0x88, 0x80, 0x80, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00,
    0x1A, 0x41, 0x7F, 0x21, 0x04, 0x0C, 0x01, 0x0B, 0x20, 0x02, 0x20, 0x03,
    0x36, 0x02, 0x10, 0x41, 0x80, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x41,
    0x10, 0x6A, 0x10, 0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x41, 0x00, 0x21,
    0x04, 0x20, 0x03, 0x41, 0x04, 0x6A, 0x41, 0x00, 0x2F, 0x00, 0x91, 0x88,
    0x80, 0x80, 0x00, 0x3B, 0x00, 0x00, 0x20, 0x03, 0x41, 0x00, 0x28, 0x00,
    0x8D, 0x88, 0x80, 0x80, 0x00, 0x36, 0x00, 0x00, 0x20, 0x02, 0x20, 0x03,
    0x36, 0x02, 0x00, 0x41, 0x93, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x10,
    0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x20, 0x03, 0x10, 0x83, 0x80, 0x80,
    0x80, 0x00, 0x0B, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x80, 0x80, 0x80,
    0x80, 0x00, 0x20, 0x04, 0x0B, 0x0B, 0x41, 0x01, 0x00, 0x41, 0x80, 0x08,
    0x0B, 0x3A, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72, 0x3A, 0x20, 0x25,
    0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00, 0x62, 0x75, 0x66,
    0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
    0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C, 0x6C, 0x6F, 0x63,
    0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x00
};

static void *app_instance_main(wasm_module_inst_t module_inst)
{
    wasm_application_execute_main(module_inst, 0, NULL);

    const char *exception = wasm_runtime_get_exception(module_inst);
    if (exception != NULL) {
        printf("%s\n", exception);
    }

    return NULL;
}

int main(int argc, char *argv[])
{
    RuntimeInitArgs init_args = {0};
#if WASM_ENABLE_GLOBAL_HEAP_POOL == 0
    init_args.mem_alloc_type = Alloc_With_Allocator;
    init_args.mem_alloc_option.allocator.malloc_func = (void *)malloc;
    init_args.mem_alloc_option.allocator.realloc_func = (void *)realloc;
    init_args.mem_alloc_option.allocator.free_func = (void *)free;
#endif

    if (!wasm_runtime_full_init(&init_args)) {
        printf("wasm runtime init failed\n");
        return -1;
    }

#if WASM_ENABLE_INTERP != 0
    char error_buf[128] = {0};

    wasm_module_t wasm_module = NULL;
    wasm_module_inst_t wasm_module_inst = NULL;

    wasm_module = wasm_runtime_load(s_wasm_interp,
                                    sizeof(s_wasm_interp) / sizeof(s_wasm_interp[0]),
                                    error_buf,
                                    sizeof(error_buf));

    if (wasm_module == NULL) {
        printf("wasm runtime load failed: %s\n", error_buf);
        goto exit;
    }

    printf("wasm runtime instantiate\n");
    wasm_module_inst = wasm_runtime_instantiate(wasm_module,
                                                32 * 1024, /* stack size */
                                                32 * 1024, /* heap size */
                                                error_buf,
                                                sizeof(error_buf));
    if (wasm_module_inst == NULL) {
        printf("wasm runtime instantiate failed: %s\n", error_buf);
        goto unload;
    }

    printf("run the application's main function\n");
    app_instance_main(wasm_module_inst);

    printf("wasm runtime deinstantiate\n");
    wasm_runtime_deinstantiate(wasm_module_inst);

unload:
    printf("wasm module unload\n");
    wasm_runtime_unload(wasm_module);
#endif

exit:
    printf("wasm runtime destroy\n");
    wasm_runtime_destroy();

    return 0;
}

测试结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ make
...
Memory region         Used Size  Region Size  %age Used
  SIZE    main
   text    data     bss     dec     hex filename
 396973    9856     416  407245   636cd build/main.elf

$ make run
wasm runtime instantiate
run the application's main function
Hello world!
buf ptr: 0x1458
buf: 1234
wasm runtime deinstantiate
wasm module unload
wasm runtime destroy

参考工程

ESP32S3

测试项目:ATK_DNESP32S3

  • ESP-IDF v6.0.2
  • ESP32-S3
  • xtensa-esp-elf-gcc(gcc version 15.2.0)

乐鑫已经提供有适配好的 WAMR 组件:wasm-micro-runtime。

我们只需要添加组件依赖:

1
idf.py add-dependency "espressif/wasm-micro-runtime"

当前使用的是最新的版本:2.4.0~1。

编译

实际测试发现,当前的 WAMR 版本编译会报错(issues 5066 和 pull 5069)。

我们需要在对应的文件里添加下面的内容:

  • core/shared/platform/esp-idf/platform_internal.h

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    #include <sys/stat.h>
    
    #if defined(__PICOLIBC__)
    /**
     * 1. ESP-IDF 6.0.2 默认使用 Picolibc, 这个 C 库没有提供该函数
     * 2. 在 espidf_platform.c 文件里定义有该函数
     */
    int
    renameat(int fromfd, const char *from, int tofd, const char *to);
    #endif
    

测试

测试代码:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
 * app_wasm.c
 *
 * SPDX-License-Identifier: Apache-2.0
 * SPDX-FileCopyrightText: 2026 Zeepunt
 */
#include <pthread.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#include "esp_err.h"
#include "esp_log.h"

#include "wasm_export.h"
#include "bh_platform.h"

static const char *TAG = "app_wasm";

static pthread_t s_wasm_tid;

static uint8_t __aligned(4) s_wasm_interp[] = {
    0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x01, 0x10, 0x03, 0x60,
    0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x01,
    0x7F, 0x00, 0x02, 0x31, 0x04, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x70, 0x75,
    0x74, 0x73, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x61, 0x6C,
    0x6C, 0x6F, 0x63, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x70, 0x72,
    0x69, 0x6E, 0x74, 0x66, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x04, 0x66,
    0x72, 0x65, 0x65, 0x00, 0x02, 0x03, 0x02, 0x01, 0x01, 0x04, 0x05, 0x01,
    0x70, 0x01, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x06, 0x13, 0x03,
    0x7F, 0x01, 0x41, 0xC0, 0x28, 0x0B, 0x7F, 0x00, 0x41, 0xBA, 0x08, 0x0B,
    0x7F, 0x00, 0x41, 0xC0, 0x28, 0x0B, 0x07, 0x2C, 0x04, 0x06, 0x6D, 0x65,
    0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x0A, 0x5F, 0x5F, 0x64, 0x61, 0x74,
    0x61, 0x5F, 0x65, 0x6E, 0x64, 0x03, 0x01, 0x0B, 0x5F, 0x5F, 0x68, 0x65,
    0x61, 0x70, 0x5F, 0x62, 0x61, 0x73, 0x65, 0x03, 0x02, 0x04, 0x6D, 0x61,
    0x69, 0x6E, 0x00, 0x04, 0x0A, 0xB2, 0x01, 0x01, 0xAF, 0x01, 0x01, 0x03,
    0x7F, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x20, 0x6B, 0x22, 0x02,
    0x24, 0x80, 0x80, 0x80, 0x80, 0x00, 0x41, 0x9B, 0x88, 0x80, 0x80, 0x00,
    0x10, 0x80, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x02, 0x40, 0x02, 0x40, 0x41,
    0x80, 0x08, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x0D, 0x00,
    0x41, 0xA8, 0x88, 0x80, 0x80, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80, 0x00,
    0x1A, 0x41, 0x7F, 0x21, 0x04, 0x0C, 0x01, 0x0B, 0x20, 0x02, 0x20, 0x03,
    0x36, 0x02, 0x10, 0x41, 0x80, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x41,
    0x10, 0x6A, 0x10, 0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x41, 0x00, 0x21,
    0x04, 0x20, 0x03, 0x41, 0x04, 0x6A, 0x41, 0x00, 0x2F, 0x00, 0x91, 0x88,
    0x80, 0x80, 0x00, 0x3B, 0x00, 0x00, 0x20, 0x03, 0x41, 0x00, 0x28, 0x00,
    0x8D, 0x88, 0x80, 0x80, 0x00, 0x36, 0x00, 0x00, 0x20, 0x02, 0x20, 0x03,
    0x36, 0x02, 0x00, 0x41, 0x93, 0x88, 0x80, 0x80, 0x00, 0x20, 0x02, 0x10,
    0x82, 0x80, 0x80, 0x80, 0x00, 0x1A, 0x20, 0x03, 0x10, 0x83, 0x80, 0x80,
    0x80, 0x00, 0x0B, 0x20, 0x02, 0x41, 0x20, 0x6A, 0x24, 0x80, 0x80, 0x80,
    0x80, 0x00, 0x20, 0x04, 0x0B, 0x0B, 0x41, 0x01, 0x00, 0x41, 0x80, 0x08,
    0x0B, 0x3A, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72, 0x3A, 0x20, 0x25,
    0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00, 0x62, 0x75, 0x66,
    0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77,
    0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C, 0x6C, 0x6F, 0x63,
    0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C, 0x65, 0x64, 0x00
};

static void *priv_app_instance_main(wasm_module_inst_t module_inst)
{
    wasm_application_execute_main(module_inst, 0, NULL);

    const char *exception = wasm_runtime_get_exception(module_inst);
    if (exception != NULL) {
        ESP_LOGE(TAG, "%s", exception);
    }

    return NULL;
}

static void *priv_wasm_handler(void *arg)
{
    RuntimeInitArgs init_args = {0};
#if WASM_ENABLE_GLOBAL_HEAP_POOL == 0
    init_args.mem_alloc_type = Alloc_With_Allocator;
    init_args.mem_alloc_option.allocator.malloc_func  = (void *)os_malloc;
    init_args.mem_alloc_option.allocator.realloc_func = (void *)os_realloc;
    init_args.mem_alloc_option.allocator.free_func    = (void *)os_free;
#endif

    if (!wasm_runtime_full_init(&init_args)) {
        ESP_LOGE(TAG, "wasm runtime init failed");
        goto exit;
    }

#if WASM_ENABLE_INTERP != 0
    char error_buf[128] = {0};

    wasm_module_t wasm_module = NULL;
    wasm_module_inst_t wasm_module_inst = NULL;

    wasm_module = wasm_runtime_load(s_wasm_interp,
                                    sizeof(s_wasm_interp) / sizeof(s_wasm_interp[0]),
                                    error_buf,
                                    sizeof(error_buf) / sizeof(error_buf[0]));
    if (wasm_module == NULL) {
        ESP_LOGE(TAG, "wasm runtime load failed: %s", error_buf);
        goto destroy;
    }

    ESP_LOGI(TAG, "wasm runtime instantiate");
    wasm_module_inst = wasm_runtime_instantiate(wasm_module,
                                                32 * 1024, /* stack size */
                                                32 * 1024, /* heap size */
                                                error_buf,
                                                sizeof(error_buf) / sizeof(error_buf[0]));
    if (wasm_module_inst == NULL) {
        ESP_LOGE(TAG, "wasm runtime instantiate failed: %s", error_buf);
        goto unload;
    }

    ESP_LOGI(TAG, "run the application's main function");
    priv_app_instance_main(wasm_module_inst);

    ESP_LOGI(TAG, "wasm runtime deinstantiate");
    wasm_runtime_deinstantiate(wasm_module_inst);

unload:
    ESP_LOGI(TAG, "wasm module unload");
    wasm_runtime_unload(wasm_module);
#endif

#if WASM_ENABLE_AOT != 0
#endif

destroy:
    ESP_LOGI(TAG, "wasm runtime destroy");
    wasm_runtime_destroy();

exit:
    return NULL;
}

int app_wasm_init(void)
{
    int ret = 0;

    pthread_attr_t pthread_attr;
    ret = pthread_attr_init(&pthread_attr);
    if (ret != 0) {
        ESP_LOGE(TAG, "pthread_attr_init failed: %d", ret);
        goto exit;
    }

    pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED);
    pthread_attr_setstacksize(&pthread_attr, 4 * 4096);

    /* WAMR 内部会使用 pthread_self, 所以不能使用 FreeRTOS 接口 */
    ret = pthread_create(&s_wasm_tid,
                         &pthread_attr,
                         priv_wasm_handler,
                         (void *)NULL);
    if (ret != 0) {
        ESP_LOGE(TAG, "wasm thread create failed: %d", ret);
        goto exit;
    }

    ret = 0;
exit:
    pthread_attr_destroy(&pthread_attr);

    return ret;
}

打印信息:

1
2
3
4
5
6
7
8
I (715) app_wasm: wasm runtime instantiate
I (725) app_wasm: run the application's main function
Hello world!
buf ptr: 0x1458
buf: 1234
I (735) app_wasm: wasm runtime deinstantiate
I (735) app_wasm: wasm module unload
I (735) app_wasm: wasm runtime destroy

分析

该组件大小

1
2
3
4
5
6
$ idf.py size-components
                                                                                                         Per-archive contributions to ELF file                                                                     
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Archive File                       | Total Size | IRAM | .text | .vectors | DIRAM | .bss | .data | .text | Flash Code |  .text | Flash Data | .tdata | .rodata | .appdesc | External RAM | .bss | RTC FAST | .rtc_reserved | RTC SLOW | .force_slow |
|------------------------------------+------------+------+-------+----------+-------+------+-------+-------+------------+--------+------------+--------+---------+----------+--------------+------+----------+---------------+----------+-------------|
| libespressif__wasm-micro-runtime.a |     170196 |   55 |    55 |        0 |  7214 |  360 |  6854 |     0 |     162708 | 162708 |        219 |      0 |     219 |        0 |            0 |    0 |        0 |             0 |        0 |           0 |
  • Flash

    • Flash Code

      .text = 162708 Bytes

    • Flash Data

      .rodata = 219 Bytes

    • IRAM

      .text = 55 Bytes

    • DIRAM

      .data = 6854 Bytes

    总共 162708 + 219 + 55 + 6854 = 169836 Bytes,约 165.9 KB。

  • RAM

    • IRAM

      .text = 55 Bytes

    • DIRAM

      .bss = 360 Bytes

      .data = 6854 Bytes

    总共 55 + 360 + 6854 = 7269 Bytes,约 7.1 KB。

编译使用的宏

  • 方法一

    1
    2
    3
    
    $ rm -r build
    $ idf.py -v build > build.log 2>&1
    $ Select-String -Path build.log -Pattern "wasm-micro-runtime" | ForEach-Object { $_.Line } > wamr_cmds.txt
    

    然后将 wamr_cmds.txt 文件丢给 AI 分析。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    
    # ESP-IDF
    -DESP_PLATFORM
    -DESP_PSA_ITS_AVAILABLE
    -DIDF_VER="v6.0.2"
    -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE
    -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ
    -DBUILD_TARGET_XTENSA
    -DBUILD_TARGET_XTENSA=1
    
    # WAMR
    -DWASM_DISABLE_HW_BOUND_CHECK=0
    -DWASM_DISABLE_STACK_HW_BOUND_CHECK=0
    -DWASM_DISABLE_WAKEUP_BLOCKING_OP=0
    -DWASM_ENABLE_AOT=1
    -DWASM_ENABLE_AOT_INTRINSICS=1
    -DWASM_ENABLE_APP_FRAMEWORK=1
    -DWASM_ENABLE_BASE_LIB
    -DWASM_ENABLE_BULK_MEMORY=1
    -DWASM_ENABLE_EXTENDED_CONST_EXPR=0
    -DWASM_ENABLE_FAST_INTERP=1
    -DWASM_ENABLE_INTERP=1
    -DWASM_ENABLE_LIBC_BUILTIN=1
    -DWASM_ENABLE_LIBC_WASI=1
    -DWASM_ENABLE_LIB_PTHREAD=1
    -DWASM_ENABLE_MINI_LOADER=0
    -DWASM_ENABLE_MODULE_INST_CONTEXT=1
    -DWASM_ENABLE_MULTI_MODULE=0
    -DWASM_ENABLE_QUICK_AOT_ENTRY=1
    -DWASM_ENABLE_SHARED_MEMORY=1
    -DWASM_ENABLE_SHRUNK_MEMORY=1
    -DWASM_ENABLE_THREAD_MGR=1
    -DWASM_GLOBAL_HEAP_SIZE=10485760
    -DWASM_MEM_DUAL_BUS_MIRROR=1
    
    -DBH_FREE=wasm_runtime_free
    -DBH_MALLOC=wasm_runtime_malloc
    -DBH_PLATFORM_ESP_IDF
    
    -DAPP_THREAD_STACK_SIZE_MAX=131072
    
    # Other
    -D_GNU_SOURCE
    -D_GLIBCXX_HAVE_POSIX_SEMAPHORE
    -D_GLIBCXX_USE_POSIX_SEMAPHORE
    -D_POSIX_READER_WRITER_LOCKS
    -D__STDC_WANT_LIB_EXT1__=0
    -DNDEBUG
    
  • 方法二

    编译完成后,会生成 build/compile_commands.json 文件,在该文件中找到 file 是 wasm-micro-runtime 目录的文件。

    1
    2
    3
    4
    5
    6
    
    {
      "directory": "D:/Zeepunt/temp/ATK_DNESP32S3/build",
      "command": "C:\\Espressif\\tools\\xtensa-esp-elf\\esp-15.2.0_20251204\\xtensa-esp-elf\\bin\\xtensa-esp32s3-elf-gcc.exe -DAPP_THREAD_STACK_SIZE_MAX=131072 -DBH_FREE=wasm_runtime_free -DBH_MALLOC=wasm_runtime_malloc -DBH_PLATFORM_ESP_IDF -DBUILD_TARGET_XTENSA -DBUILD_TARGET_XTENSA=1 -DESP_PLATFORM -DIDF_VER=\\\"v6.0.2\\\" -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ -DWASM_DISABLE_HW_BOUND_CHECK=0 -DWASM_DISABLE_STACK_HW_BOUND_CHECK=0 -DWASM_DISABLE_WAKEUP_BLOCKING_OP=0 -DWASM_ENABLE_AOT=1 -DWASM_ENABLE_AOT_INTRINSICS=1 -DWASM_ENABLE_APP_FRAMEWORK=1 -DWASM_ENABLE_BASE_LIB -DWASM_ENABLE_BULK_MEMORY=1 -DWASM_ENABLE_EXTENDED_CONST_EXPR=0 -DWASM_ENABLE_FAST_INTERP=1 -DWASM_ENABLE_INTERP=1 -DWASM_ENABLE_LIBC_BUILTIN=1 -DWASM_ENABLE_LIBC_WASI=1 -DWASM_ENABLE_LIB_PTHREAD=1 -DWASM_ENABLE_MINI_LOADER=0 -DWASM_ENABLE_MODULE_INST_CONTEXT=1 -DWASM_ENABLE_MULTI_MODULE=0 -DWASM_ENABLE_QUICK_AOT_ENTRY=1 -DWASM_ENABLE_SHARED_MEMORY=1 -DWASM_ENABLE_SHRUNK_MEMORY=1 -DWASM_ENABLE_THREAD_MGR=1 -DWASM_GLOBAL_HEAP_SIZE=10485760 -DWASM_MEM_DUAL_BUS_MIRROR=1 -D_GLIBCXX_HAVE_POSIX_SEMAPHORE -D_GLIBCXX_USE_POSIX_SEMAPHORE -D_GNU_SOURCE -D_POSIX_READER_WRITER_LOCKS -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/interpreter -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/aot -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/libraries/libc-builtin -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/libraries/lib-pthread -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/libraries/thread-mgr -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/build-scripts/esp-idf/wamr/../../../core/iwasm/include -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/platform/esp-idf -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/platform/esp-idf/../include -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/platform/common/libc-util -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/mem-alloc -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/common -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/utils -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/coap/er-coap -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/coap/extension -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/wamr-app-framework/app-framework/app-native-shared -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/wamr-app-framework/app-framework/base/native -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/wamr-app-framework/app-mgr/app-manager -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/wamr-app-framework/app-mgr/app-mgr-shared -ID:/Zeepunt/temp/ATK_DNESP32S3/build/config -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/iwasm/include -ID:/Zeepunt/temp/ATK_DNESP32S3/managed_components/espressif__wasm-micro-runtime/core/shared/platform/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_libc/platform_include -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/config/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/config/include/freertos -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/config/xtensa/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/FreeRTOS-Kernel/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos -ID:/ESP-IDF/v6.0.2/esp-idf/components/freertos/esp_additions/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/include/soc -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/ldo/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/debug_probe/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/etm/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/mspi_timing_tuning/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/mspi_timing_tuning/tuning_scheme_impl/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/power_supply/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/modem/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/include/soc/esp32s3 -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/port/esp32s3/. -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/port/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/. -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hw_support/mspi_timing_tuning/port/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/heap/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/heap/tlsf -ID:/ESP-IDF/v6.0.2/esp-idf/components/log/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/soc/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/soc/esp32s3 -ID:/ESP-IDF/v6.0.2/esp-idf/components/soc/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/soc/esp32s3/register -ID:/ESP-IDF/v6.0.2/esp-idf/components/hal/platform_port/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/hal/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/hal/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_rom/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_rom/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_rom/esp32s3/include/esp32s3 -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_rom/esp32s3 -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_common/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_system/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_system/port/soc -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_system/port/include/private -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_stdio/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/xtensa/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/xtensa/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/xtensa/deprecated_include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_gpio/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_gpio/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_usb/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_usb/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_pmu/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_pmu/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_ana_conv/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_ana_conv/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_dma/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_hal_dma/esp32s3/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/include/apps -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/lwip/src/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/port/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/port/freertos/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/port/esp32xx/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/port/esp32xx/include/arch -ID:/ESP-IDF/v6.0.2/esp-idf/components/lwip/port/esp32xx/include/sys -ID:/ESP-IDF/v6.0.2/esp-idf/components/pthread/include -ID:/ESP-IDF/v6.0.2/esp-idf/components/esp_timer/include @\"D:/Zeepunt/temp/ATK_DNESP32S3/build/toolchain/cflags\" -std=gnu99 -ffunction-sections -fdata-sections                                          -Wall -Wno-unused-parameter -Wno-pedantic -O3 -DNDEBUG -fdiagnostics-color=always -ffunction-sections -fdata-sections -Wall -Werror -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=unused-but-set-variable -Wno-error=deprecated-declarations -Wextra -Wno-error=extra -Wno-unused-parameter -Wno-sign-compare -Wno-enum-conversion -gdwarf-4 -ggdb -Og -fno-shrink-wrap -fmacro-prefix-map=D:/Zeepunt/temp/ATK_DNESP32S3=. -fmacro-prefix-map=D:/ESP-IDF/v6.0.2/esp-idf=/IDF -fstrict-volatile-bitfields -fno-jump-tables -fno-tree-switch-conversion -std=gnu23 -Wno-old-style-declaration -fzero-init-padding-bits=all -fno-malloc-dce -Wno-format -Wno-type-limits -o esp-idf\\espressif__wasm-micro-runtime\\CMakeFiles\\__idf_espressif__wasm-micro-runtime.dir\\core\\iwasm\\common\\wasm_blocking_op.c.obj -c D:\\Zeepunt\\temp\\ATK_DNESP32S3\\managed_components\\espressif__wasm-micro-runtime\\core\\iwasm\\common\\wasm_blocking_op.c",
      "file": "D:\\Zeepunt\\temp\\ATK_DNESP32S3\\managed_components\\espressif__wasm-micro-runtime\\core\\iwasm\\common\\wasm_blocking_op.c",
      "output": "esp-idf\\espressif__wasm-micro-runtime\\CMakeFiles\\__idf_espressif__wasm-micro-runtime.dir\\core\\iwasm\\common\\wasm_blocking_op.c.obj"
    }
    

    将其丢给 AI 分析。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    # ESP-IDF
    -DESP_PLATFORM
    -DIDF_VER="v6.0.2"
    -DSOC_MMU_PAGE_SIZE=CONFIG_MMU_PAGE_SIZE
    -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ
    -DBUILD_TARGET_XTENSA=1
    
    # WAMR
    -DWASM_DISABLE_HW_BOUND_CHECK=0
    -DWASM_DISABLE_STACK_HW_BOUND_CHECK=0
    -DWASM_DISABLE_WAKEUP_BLOCKING_OP=0
    -DWASM_ENABLE_AOT=1
    -DWASM_ENABLE_AOT_INTRINSICS=1
    -DWASM_ENABLE_APP_FRAMEWORK=1
    -DWASM_ENABLE_BASE_LIB
    -DWASM_ENABLE_BULK_MEMORY=1
    -DWASM_ENABLE_EXTENDED_CONST_EXPR=0
    -DWASM_ENABLE_FAST_INTERP=1
    -DWASM_ENABLE_INTERP=1
    -DWASM_ENABLE_LIBC_BUILTIN=1
    -DWASM_ENABLE_LIBC_WASI=1
    -DWASM_ENABLE_LIB_PTHREAD=1
    -DWASM_ENABLE_MINI_LOADER=0
    -DWASM_ENABLE_MODULE_INST_CONTEXT=1
    -DWASM_ENABLE_MULTI_MODULE=0
    -DWASM_ENABLE_QUICK_AOT_ENTRY=1
    -DWASM_ENABLE_SHARED_MEMORY=1
    -DWASM_ENABLE_SHRUNK_MEMORY=1
    -DWASM_ENABLE_THREAD_MGR=1
    -DWASM_GLOBAL_HEAP_SIZE=10485760
    -DWASM_MEM_DUAL_BUS_MIRROR=1
    
    -DBH_FREE=wasm_runtime_free
    -DBH_MALLOC=wasm_runtime_malloc
    -DBH_PLATFORM_ESP_IDF
    
    -DAPP_THREAD_STACK_SIZE_MAX=131072
    
    # Other
    -D_GNU_SOURCE
    -D_GLIBCXX_HAVE_POSIX_SEMAPHORE
    -D_GLIBCXX_USE_POSIX_SEMAPHORE
    -D_POSIX_READER_WRITER_LOCKS
    -DNDEBUG
    

应用场景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
             客户产品代码 / 自研产品代码
                        |
                        v
                 OpenSDK (Rust/Go/...)
                        |
                        v
                      .wasm
                        |
                        v
       +----------------+----------------+
       |                                 |
+--------------+                 +--------------+
| WAMR Runtime | ESP32           | WAMR Runtime | Linux
+--------------+                 +--------------+
       |                                 |
       +----------------+----------------+
                        ʌ
                        |
              +--------------------+
              | WIFI / LVGL / GPIO | Host API
              +--------------------+

场景一:客户购买硬件(自带固件,固件由厂家维护),然后根据 OpenSDK 的接口文档进行产品开发。

场景二:厂家自研产品,一部分人员维护硬件和固件,另外一部分人员根据 OpenSDK 的接口文件进行应用开发。

Host API 是多平台共用的,在其内部实现中调用不同平台的接口来完成相同的功能。

Linux 平台是方便应用调试,比如使用 LVGL 进行 UI 绘制时,直接在 Linux 看效果,然后再放到硬件进行实机测试。