3.6 KiB
Wokwi Custom Chips — investigación de referencia
Esto NO es código que copiemos. Es una descripción del sistema de Wokwi para entender el dominio del problema antes de diseñar el nuestro propio.
Consultado: 2026-04-27.
Qué es
Wokwi permite que el usuario escriba un chip en C, lo compile a WebAssembly, y lo agregue a su diagrama. El chip simula su comportamiento eléctrico/lógico cuando el sketch del Arduino interactúa con sus pines.
Fuentes:
- https://docs.wokwi.com/chips-api/getting-started
- https://docs.wokwi.com/chips-api/chip-json
- https://docs.wokwi.com/chips-api/i2c
- https://docs.wokwi.com/chips-api/uart
- https://docs.wokwi.com/chips-api/spi
- https://docs.wokwi.com/chips-api/tutorial-7seg
- https://github.com/alextrical/wokwi-24C01-custom-chip (ejemplo MIT real)
Anatomía de un chip Wokwi
Dos archivos:
chip.c— incluyewokwi-api.h. Define una funciónchip_init()que se llama una vez por cada instancia del chip al iniciar el simulador.chip.json— declara nombre, autor, lista de pines, atributos editables, opciones de display.
Ejemplo chip.json (24C01 EEPROM):
{
"version": 1,
"name": "24C01",
"author": "Alextrical",
"license": "MIT",
"pins": ["A0","A1","A2","GND","VCC","WP","SCL","SDA"]
}
API observada (resumen)
Pines
pin_t pin_init(const char* name, pin_mode mode)— registra y devuelve handle.uint32_t pin_read(pin_t),void pin_write(pin_t, uint32_t).void pin_watch(pin_t, const pin_watch_config_t*)con callback en flanco.- Modos:
INPUT,OUTPUT,OUTPUT_HIGH,INPUT_PULLUP,INPUT_PULLDOWN,ANALOG. - Edges:
RISING,FALLING,BOTH.
I2C (slave)
i2c_dev_t i2c_init(const i2c_config_t* cfg). Solo desdechip_init().- Callbacks:
connect(ud, addr, isRead)→bool ack,read(ud)→uint8,write(ud, byte)→bool ack,disconnect(ud). - Bus es 7-bit slave; el chip "responde" a una dirección.
UART
uart_dev_t uart_init(const uart_config_t* cfg). RX/TX, baud, callbacksrx_dataywrite_done.uart_write(uart, buffer, count)para emitir bytes.
SPI (slave)
spi_dev_t spi_init(const spi_config_t* cfg). Pines sck/mosi/miso, modo (0..3), callbackdone.spi_start(spi, buffer, count),spi_stop(spi).
Atributos
attr_t attr_init(const char* name, uint32_t default_val),attr_read(attr).- Versiones
attr_init_float/attr_float_readpara reales.
Tiempo
get_sim_nanos()reloj de la simulación.- API de timers:
timer_init,timer_start, etc. (no la documentamos exhaustivamente acá).
Misc
printffunciona porque el chip se compila contrawasi-libcy la salida va a la "Chips Console".- Estado por instancia: el chip hace
malloc(sizeof(chip_state_t))enchip_init().
ABI del WASM
Compilación:
clang --target=wasm32-unknown-wasi -nostartfiles \
-Wl,--import-memory -Wl,--export-table -Wl,--no-entry \
-I<sdk> chip.c -o chip.wasm
--import-memory: el host provee la memoria, el WASM la importa.--export-table: la tabla de funciones se exporta para que el host pueda invocar callbacks por índice (los punteros a función en C son índices en la tabla).--no-entry: no haymain, solo exports.
El WASM importa todas las funciones de la API (pin_init, i2c_init, etc) y exporta
chip_init + memory + __indirect_function_table.
Conclusión para Velxio
Replicamos el modelo (chip = WASM con imports + exports), no el API. Velxio escribe su propio header, sus propios nombres, su propio chip.json schema. El compilador (clang) y runtime (wasi-libc) se mantienen idénticos porque son OSS no-Wokwi.