Skip to content

Commit

Permalink
Feature: add support for the wokwi simulator (#2688)
Browse files Browse the repository at this point in the history
More information from here:

https://sming.readthedocs.io/en/latest/experimental/wokwi.html

* Add mergeflash target which merges all partitions into a single file.
* Added wokwi-support. Make ide-vscode workspace with ENABLE_WORKI=1 .
* Add Wokwi documentation.
* Add Wokwi debug support.
  • Loading branch information
slaff authored Dec 18, 2023
1 parent 7cd0f60 commit 1ba2c2d
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 28 deletions.
7 changes: 7 additions & 0 deletions Sming/Components/esptool/component.mk
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ define WriteFlash
)
endef

define MergeFlash
$(if $1,\
$(info MergeFlash $1) \
$(call ESPTOOL_EXECUTE,merge_bin -o $2 $(flashimageoptions) $(subst =, ,$1)) \
)
endef

# Verify flash against file contents
# $1 -> List of `Offset=File` chunks
define VerifyFlash
Expand Down
5 changes: 5 additions & 0 deletions Sming/component.mk
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ else ifneq ($(SMING_ARCH),Host)
$(TERMINAL)
endif

.PHONY: mergeflash
mergeflash: all ##Merge the boot loader and all defined partition images into a single flash file
$(Q) $(call CheckPartitionChunks,$(FLASH_PARTITION_CHUNKS))
$(call MergeFlash,$(FLASH_BOOT_CHUNKS) $(FLASH_MAP_CHUNK) $(FLASH_PARTITION_CHUNKS),$(FW_BASE)/app-merged.bin)

.PHONY: verifyflash
verifyflash: ##Read all flash sections and verify against source
$(Q) $(call CheckPartitionChunks,$(FLASH_PARTITION_CHUNKS))
Expand Down
86 changes: 58 additions & 28 deletions Tools/ide/vscode/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,36 +58,46 @@ def update_launch():
filename = '.vscode/launch.json'
launch = load_json(filename, False)
template = load_template('launch.json', appPath)
if env.get('ENABLE_WOKWI'):
wokwi_template = load_template('wokwi/launch.json', appPath)
template["configurations"].extend(wokwi_template["configurations"])
if launch is None:
launch = template.copy()
configurations = get_property(launch, 'configurations', [])
config_name = "%s GDB" % env['SMING_ARCH']
config = find_object(configurations, config_name)
template_config = find_object(template['configurations'], config_name)
if template_config is None:
print("Warning: Template launch configuration '%s' not found" % config_name)
elif not config is None:
configurations.remove(config)
config = template_config.copy()
configurations.append(config)

if config is None:
return

config['miDebuggerPath'] = find_tool(env['GDB'])
dbgargs = "-x ${env:SMING_HOME}/Arch/%s/Components/gdbstub/gdbcmds" % env['SMING_ARCH']
if env['SMING_ARCH'] == 'Host':
args = []
args += env['CLI_TARGET_OPTIONS'].split()
args += ["--"]
args += env['HOST_PARAMETERS'].split()
config['args'] = args
else:
if not env.isWsl():
dbgargs += " -b %s" % env.resolve('${COM_SPEED_GDB}')
config['miDebuggerServerAddress'] = env.resolve('${COM_PORT_GDB}')
config['miDebuggerArgs'] = dbgargs
config['program'] = "${workspaceFolder}/" + env.resolve('${TARGET_OUT_0}')
wokwi_config_name = "Wokwi GDB"
config_names = ["%s GDB" % env['SMING_ARCH']]
if env.get('ENABLE_WOKWI'):
config_names.append(wokwi_config_name)
for config_name in config_names:
config = find_object(configurations, config_name)
template_config = find_object(template['configurations'], config_name)
if template_config is None:
print("Warning: Template launch configuration '%s' not found" % config_name)
elif not config is None:
configurations.remove(config)
config = template_config.copy()
configurations.append(config)

if config is None:
return

config['miDebuggerPath'] = find_tool(env['GDB'])
dbgargs = "-x ${env:SMING_HOME}/Arch/%s/Components/gdbstub/gdbcmds" % env['SMING_ARCH']
if env['SMING_ARCH'] == 'Host':
args = []
args += env['CLI_TARGET_OPTIONS'].split()
args += ["--"]
args += env['HOST_PARAMETERS'].split()
config['args'] = args
else:
if not env.isWsl():
dbgargs += " -b %s" % env.resolve('${COM_SPEED_GDB}')
if config_name != wokwi_config_name:
config['miDebuggerServerAddress'] = env.resolve('${COM_PORT_GDB}')
if config_name != wokwi_config_name:
config['miDebuggerArgs'] = dbgargs
config['program'] = "${workspaceFolder}/" + env.resolve('${TARGET_OUT_0}')

save_json(launch, filename)

Expand All @@ -103,6 +113,26 @@ def update_workspace():
schemas += [schema]
save_json(ws, filename)

def update_wokwi():
filename = '.vscode/extensions.json'
extensions = load_json(filename, False)
template = load_template('wokwi/extensions.json', appPath)
if extensions is None:
extensions = template.copy()
save_json(extensions, filename)
return
extensions["recommendations"] = extensions["recommendations"] + list(set(template["recommendations"]) - set(extensions["recommendations"]))
save_json(extensions, filename)

if not os.path.exists('diagram.json'):
diagrams_template = load_template('wokwi/diagram.json', appPath)
save_json(diagrams_template, 'diagram.json')

if not os.path.exists('wokwi.toml'):
source = open(appPath + '/template/wokwi/wokwi.toml', 'r').read()
source = env.resolve(source)
open('wokwi.toml', 'w+').write(source)

def main():
if not env['SMING_HOME'] or not env['SMING_ARCH']:
sys.exit(1)
Expand All @@ -113,9 +143,9 @@ def main():
update_intellisense()
update_tasks()
update_launch()
if env.get('ENABLE_WOKWI'):
update_wokwi()
update_workspace()



if __name__ == '__main__':
main()
18 changes: 18 additions & 0 deletions Tools/ide/vscode/template/wokwi/diagram.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 1,
"author": "Sming Framework",
"editor": "wokwi",
"parts": [
{
"type": "wokwi-esp32-devkit-v1",
"id": "esp",
"top": 0,
"left": 0,
"attrs": {}
}
],
"connections": [
["esp:TX0", "$serialMonitor:RX", "", []],
["esp:RX0", "$serialMonitor:TX", "", []]
]
}
3 changes: 3 additions & 0 deletions Tools/ide/vscode/template/wokwi/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["wokwi.wokwi-vscode"]
}
18 changes: 18 additions & 0 deletions Tools/ide/vscode/template/wokwi/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Wokwi GDB",
"type": "cppdbg",
"request": "launch",
"program": "",
"args": [],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerServerAddress": "localhost:3333"
}
]
}
5 changes: 5 additions & 0 deletions Tools/ide/vscode/template/wokwi/wokwi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[wokwi]
version=1
firmware='${FW_BASE}/app-merged.bin'
elf='${TARGET_OUT_0}'
gdbServerPort=3333
1 change: 1 addition & 0 deletions docs/source/experimental/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Experimental Stuff

httpserver-ssl
signed-ota
wokwi
Binary file added docs/source/experimental/wokwi-debug.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
61 changes: 61 additions & 0 deletions docs/source/experimental/wokwi.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
****************
Simulator: Wokwi
****************

.. highlight:: bash

* At the moment Sming and Wokwi have experimenta support for the Esp32 architecture.
* Only VS Code IDE is supported
* The Esp32 simulator lacks certain features and may encounter failures; hence, it is recommended for use with simple applications.

Wokwi Support into VS Code
==========================

To integrate Wokwi support into your VS Code, run the following command from your application's root directory::

make ide-vscode ENABLE_WOKWI=1 SMING_ARCH=Esp32

Install the recommended extensions
----------------------------------

Ensure that you have installed the newly recommended extensions. If none appear, manually install the ``wokwi.wokwi-vscode`` extension.

Merge all partitions to a single flash file
-------------------------------------------

From the root directory of your application, run the following command to consolidate all partitions for the simulator and flash them into a single file::

make mergeflash SMING_ARCH=Esp32

Usage
=====

Basic_Blink
-----------

The Basic_Blink sample can be compiled and executed directly on a simulator before deploying it to a physical microcontroller.
Follow the commands below to get started::

cd $SMING_ARCH/../samples/Basic_Blink
make ide-vscode ENABLE_WOKWI=1 SMING_ARCH=Esp32
make mergedflash

Once the compilation is complete, open the folder in VS Code, install the recommended extensions, and either open the ``diagram.json`` file or press F1 and type ``Wokwi``.
From the options, choose to start the Wokwi simulator.

Debugging
=========

Running the Basic_Blink sample in the simulator enables you to debug it directly in VS Code.
Set a breakpoint in the ``init`` function in the Basic_Blink ``app/application.cpp`` file.
Press F1 and select "Start Simulator and Wait for Debugger." In the Launch configurations, choose "Wokwi GDB" and click the play button.
This initiates a new debugging session, allowing you to debug the code running in the simulator.

.. image:: wokwi-debug.jpg
:height: 192px

Diagram Editor
==============

The ``diagram.json`` file, which includes elements and their connections, can be edited on the `Wokwi official website <https://wokwi.com/>`__.
You can add new elements such as extra LEDs or servos. Ensure to copy the modified contents of the diagram.json from the website to your local environment.

0 comments on commit 1ba2c2d

Please sign in to comment.