4. Visual Studio Code

Visual Studio Code is a lightweight but powerful source code editor which runs on multiple platforms.

With the C/C++ for Visual Studio Code extension it is possible to use Calypsi in Visual Studio Code.

This works as Visual Studio Code can be tailored to use different build and debugger tools. The most crucial part is perhaps the debugger integration which is based on the MI (Machine Interface), which is also what the Calypsi debugger supports.

Visual Studio Code is a good choice for a graphical user interface to Calypsi as it is very actively developed, lightweight, responsive and highly configurable.

Documenting the full Visual Studio Code is beyond the scope of this guide. Refer to the official Visual Studio Code documentation for detailed information.

Some basics on how to get started is covered here as it may not work entirely as you may expect from traditional IDEs.

_images/vscode-session.png

4.1. Installation

Installation is easy to do by downloading it from the official site. You can easily update it inside Visual Studio Code itself.

4.2. Project setup

In contrast to many IDEs you will not find any project setup in the menus.

To create a new project from scratch, use File>Open and create a new folder for your project and then press Open. You now have an empty project directory.

If you have an existing project, you can just select File>Open and browse to the top folder in that project, the press Open and you have loaded your project.

Project specific files are kept in an .vscode directory in your project directory. Initially there are no such files.

Building

Once you have populated your project and perhaps created a Makefile, you can add a task to build it. Select Tasks>Configure Tasks... and pick Create tasks.json file from template. Then select Others to get a tasks.json that you can edit. It may end up looking something like:

{
    "version": "0.2.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "make -k",
            "options": {
                "cwd": "${workspaceRoot}/src"
            },
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}

Here we tell it that we want to run make -k in the src sub-directory and match error output to something that looks like what gcc would produce.

Debugging

To start the debugger you need to add a launch configuration.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C++ Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/src/myproject",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}/src",
            "environment": [],
            "externalConsole": true,
            "logging": {
                "trace": true,
                "traceResponse": true,
                "engineLogging":true
            },
            "linux": {
                "MIMode": "lldb"
            },
            "osx": {
                "MIMode": "lldb",
                "miDebuggerPath": "dbnut",
                "launchCompleteCommand": "exec-run",
                "setupCommands": [
                    {
                        "text": "module insert /Users/me/projects/modules41/41cx.mod",
                        "description": "load mainframe",
                        "ignoreFailures": false
                    }
                ]
            },
            "windows": {
                "MIMode": "gdb"
            }
        },
    ]
}

There are a couple of things to specify here.

  1. We need to specify that we are using dbnut as the debugger using miDebuggerPath

  2. We also need to tell that we want to use lldb as MIMode 1

  3. We also need to load the calculator firmware. Here it is done using setupCommands that invokes the debugger console command module insert.

Footnotes

1

Even though dbnut is much closer to gdb than lldb at the command level, we need to specify lldb as the MI mode. The reason is that in the gdb mode, Visual Studio Code works around a bug on UNIX style platforms for the MI command -exec-interrupt (which interrupts execution). The work around is it to send a signal to a real UNIX process to interrupt it. As we are running in a simulation environment the process is not a normal UNIX process and cannot be interrupted that way. Instead we use the lldb mode where MI command -exec-interrupt works properly, just as it does with dbnut.

Reference https://sourceware.org/bugzilla/show_bug.cgi?id=20035