SPI interface works but does not work when stepping through with debugger in VSC (Visual Studio Code)

My specs first:
Module: Colibri iMX6DL 512 MB IT v1.1B
Carrier: Colibri Evaluation Board
OS : TorizonCore Upstream 5.6.0 devel_202202+build.21
Docker: Docker Desktop 4.5.1 (74721) is currently the newest version available.
VSC: Version 1.65.2

Hello!
I am cross-compiling code to my target from a windows laptop running VSC. I am trying to debug my SPI interface, which seems to be mostly working from what I can see so far, (aside from some minor issues I want to debug)

My SPI is based entirely from the example code spidev_test.c found here:

with very little modification.

I can reliably get the program to run when I create the executable (on my target, an ARM 32-bit processor on the: Colibri iMX6DL 512MB IT module running on a carrier board: Toradex Colibri Evaluation Board) and run it from the command line prompt.

However, when I run it using the debugger, it aborts on the line indicated below.
The debugger inspects the value of device to be “/dev/spidev3.0” as it should be, but the 0_RDWR does not seem to evaluate to anything… although this might be #defined (can you inspect a #defined value with the debugger?)

parse_opts(argc, argv);
	if (input_tx && input_file)
		pabort("ERROR 220: only one of -p and --input may be selected");

fileDescriptor = open(device, O_RDWR);                  // returns -1 
	if (fileDescriptor < 0)
		pabort("ERROR 221: SPI can't open SPI device");  // exits the program inside this function

I am wondering if there is something I am doing wrong… I am new to VSC so any of the .json properties may be wrong…

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "C++ Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}\\EmeraBlockEnergyBox",
            "args": [
                "-I", "5000", 
                "-s", "50", 
                "-v"
            ],
            "miDebuggerServerAddress": "",
            "stopAtEntry": false,
            "cwd": "${workspaceRoot}",
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "gdb-multiarch",
            "targetArchitecture": "",
            "preLaunchTask": "${defaultBuildTask}",
            "setupCommands": [
                {
                    "description": "Setting architecture",
                    "text": "set architecture %{torizon.gdb-arch}",
                    "ignoreFailures": false,
                    "externalConsole":false
                }
            ]
        }
    ]
}

settings.json

{
    "torizon.configuration": "debug",
    "torizon.appfolder": "appconfig_0",
    "files.associations": {
        "numeric": "c",
        "stdlib.h": "c",
        "emerablockenergybox.h": "c",
        "spidev.h": "c",
        "cstdio": "c"
    }
}

tasks.json

{
"version": "2.0.0",
"tasks": [
    {
        "label": "build_debug",
        "command": "make",
        "type": "shell",
        "args": [],
        "problemMatcher": {
            "base": "$gcc"
        },
        "options": {
            "env": {
                "CFLAGS": "-g",
                "CXXFLAGS": "-g"
            }
        },
        "group": {
            "kind": "build",
            "isDefault": true
        }
    },
    {
        "label": "build_release",
        "command": "make",
        "type": "shell",
        "args": [],
        "problemMatcher": {
            "base": "$gcc"
        },
        "options": {
            "env": {
                "CFLAGS": ""
            }
        },
        "group": "build"
    },
    {
        "label": "clean",
        "command": "make",
        "type": "shell",
        "args": [
            "clean"
        ],
        "problemMatcher": {
            "base": "$gcc"
        },
        "group": "build"
    },
    {
        "detail": "deploy application to work folder",
        "label": "deploy",
        "command": "make",
        "args": [
            "WORKDIR=${command:torizon.ccpp.getTargetFolder}",
            "install"
        ],
        "type": "shell",
        "group": "none"
    }
],
"options": {
    "env": {
        "TORIZON_PROP_ARG": "ARG SSHUSERNAME=#%application.username%#\n"
    }
}
}

devcontainer.json

{
    "name": "torizon_EmeraBlockEnergyBox",
    "dockerFile": "Dockerfile",
    "extensions": [
        "ms-vscode.cpptools"
    ],
    "containerEnv": {
        "AR": "arm-linux-gnueabihf-ar",
        "AS": "arm-linux-gnueabihf-as",
        "CC": "arm-linux-gnueabihf-gcc",
        "CXX": "arm-linux-gnueabihf-g++",
        "CPP": "arm-linux-gnueabihf-cpp",
        "LD": "arm-linux-gnueabihf-ld",
        "STRIP": "arm-linux-gnueabihf-strip",
        "CROSS_COMPILE": "arm-linux-gnueabihf-"
    },
    "runArgs": [
        "--network=host"
    ],
    "remoteUser": "torizon",
    "postCreateCommand": "mkdir -p /home/torizon/.vscode-server-insiders/extensions ; mkdir -p /home/torizon/.vscode-server/extensions; ln -s /home/torizon/.torizon-extension /home/torizon/.vscode-server-insiders/extensions/toradex.torizon ; ln -s /home/torizon/.torizon-extension /home/torizon/.vscode-server/extensions/toradex.torizon ; chgrp docker /var/run/docker.sock ; true",
    "mounts": [
        "source=${localEnv:HOME}${localEnv:USERPROFILE}/.moses,target=/home/torizon/.moses,type=bind",
        "source=//var/run/docker.sock,target=/var/run/docker.sock,type=bind",
        "source=c:\\Users\\LeighBoyd\\.vscode\\extensions\\toradex.torizon-1.3.0,target=/home/torizon/.torizon-extension,type=bind"
    ]
}

Any ideas what I can try to make it work in debug mode?

Greetings @leighjboyd,

I’m assuming when you ran the executable on the board itself you weren’t running this in a container?

Our VSCode extension runs code inside a container. If you wish to access external peripherals like SPI you need to give access to the container so it can access these. You can configure these using the VSCode extension.

See the section of this article here for more details: Torizon Best Practices Guide | Toradex Developer Center

Best Regards,
Jeremias

This seemed to help! thanks!
Is this also why the debugger cannot use fopen() to read and write to files?
What device would I need to add in that case?

Is this also why the debugger cannot use fopen() to read and write to files?

A container is a isolated environment that runs on top of the host system. If want it to have access to anything on the host it needs to be explicitly given, similar to how you just did with SPI.

If you want to share files between the host and container you want to look at this section: Torizon Best Practices Guide | Toradex Developer Center

Best Regards,
Jeremias