Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add support for the wokwi simulator #2688

Merged
merged 5 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -141,6 +141,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.
Loading