Using libsoc with Torizon

I’d like to use libsoc with Torizon to interact with things like GPIO pins. I notice from here that libsoc was added to the standard images starting in 2.8b3, does that mean it is included in the Torizon images too? That would be great as I’d like to just use it without having to build and deploy it first. I guess it would need to be included in the container rather than in the TorizonCore image?

I’m using Visual Studio to build my application for Torizon. That means the build machine is hidden from me in a container on my PC, so if I need to install libsoc on that build machine then how do I do it?

Libsoc sounds so useful and so small that I think it would be a good idea to include it in the standard container so that it can used directly from code in Visual Studio without having to configure anything.

Greetings @MikeS,

The libsoc library is not part of the base TorizonCore system. Though this can easily be remedied with the use of containers. The libsoc documentation located here, does state that libsoc can be easily installed via various package managers, including the apt-get which is available with our base Debian container.

As for development purposes you mentioned you are using Visual Studio. Does this mean you are using the Torizon Microsoft Environment? If so then the documentation for this tool goes over an example application that utilizes libsoc.

Best Regards,
Jeremias

Hi @jeremias.tx,
Yes, I am using the Torizon Microsoft Environment. Thanks for pointing out the details on the example page for this, that’s exactly what I need. When I first followed the tutorial for setting this up I either didn’t notice the libsoc section, or it was so long ago that maybe that example hadn’t been added yet. I’ll work through that information now.
Mike

You are welcome. Let us know if you need more Information.

@jeremias.tx and @jaski.tx I finally got some time to come back to this today. I tried following the instructions from https://github.com/toradex/microsoft-ecosystem-environment-documentation but I can’t build the application because it can’t find the libsoc_gpio.h header file. Should that file be pulled into my project when I add the library dependency, or will it be added to the Linux VM on my PC which performs the cross compilation?

I think the settings in my project match the tutorial exactly:
[upload|2EiAbC08GF+HVu0GuvnobbOU1JI=]
[upload|aSkXyLfLucuW6Dmphhs4dazBFH0=]

The compiler output is:

1>------ Build started: Project: TorizonApp6, Configuration: Debug_Debian_Buster_slim x64 ------
1>Building application container...
1>Done
1>Updating SDK container...
1>Done
1>Validating sources
1>Copying sources remotely to '127.0.0.1'
1>Validating architecture
1>Starting remote build
1>Compiling sources:
1>main.cpp
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error : libsoc_gpio.h: No such file or directory
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error :  #include <libsoc_gpio.h>
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error :           ^~~~~~~~~~~~~~~
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error : compilation terminated.
1>Done building project "TorizonApp6.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I must be missing something.

I should add that I can’t find that file anywhere on my build machine either, so the problem is not just the include path settings.

After you add the entries to EXTRAPACKAGE you need to rebuild your container (there is an option in the toolbar/menu for that) and then re-generate the SDK.

Thanks for your reply @valter.tx. I did already try to rebuild the container and the SDK before I submitted this question. The other thing I tried was to make a new project and add the EXTRAPACKAGES details before building the new project for the first time. The compiler output of that is shown above where it builds the container, then updates the SDK, then fails to build the application.

I tried rebuilding both the container and the SDK again today just to be sure and saw this output:

Building container...
Container has been built.
Updating SDK...SDK has been updated.

1>------ Build started: Project: TorizonApp6, Configuration: Debug_Debian_Buster_slim x64 ------
1>Application container is up to date.
1>Validating sources
1>Copying sources remotely to '127.0.0.1'
1>Validating architecture
1>Starting remote build
1>Compiling sources:
1>main.cpp
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error : libsoc_gpio.h: No such file or directory
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error :  #include <libsoc_gpio.h>
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error :           ^~~~~~~~~~~~~~~
1>C:\temp\TorizonApp6\TorizonApp6\main.cpp(4,10): error : compilation terminated.
1>Done building project "TorizonApp6.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It’s as if the EXTRAPACKAGES setting is not having any effect.

Here’s a copy of the config.json file in case that helps.

@valter.tx, @jeremias.tx and @jaski.tx, I’m still interested in getting libsoc to work. Did the details in my last comment help you to figure out what I should try next?

You should have a file named Dockerfile.debug in the application subfolder of your VS project folder, can you please share that?

Can you please try to move this:
“arg”: “ARG SSHUSERNAME=”#%application.username%#"\r\nARG EXTRAPACKAGES="$EXTRAPACKAGES libsoc2 libsoc-dev"\r\n",

from “common” to “debug” inside your config file and then rebuild container and SDK?
Can you also capture the output of those steps?

@valter.tx here are copies of config.json and Dockerfile.debug as they were yesterday, before I tried your suggestion about moving “arg”. I notice that Dockerfile.debug contains the line ARG EXTRAPACKAGES="libc-dev gdb lxde-core" and seems to make no mention of libsoc, I think that might be a clue.

@valter.tx I made that change to config.json. The output from rebuilding the container and SDK doesn’t contain any helpful information:

Building container...
Container has been built.

Updating SDK...SDK has been updated.

But this has brought me a big step forward because now I can compile and link the application and the compiler can find the include files like libsoc_gpio.h.

The folder in the container on the module contains two files: my application .out file and the libsoc configuration file colibri-imx7-1GB.conf. But the application fails to load the board configuration at this step:

    printf("Hello from CPPProjectTemplate!\n");

	board_config* config = NULL;
	gpio* ledgpio = NULL;
	int ledgpioid = -1;
	int state = 0;

	// we don't have /proc/device-tree mounted inside the container so 
	// we must configure conf file path in environment
	setenv("LIBSOC_CONF", "./colibri-imx7-1GB.conf", 1);
	config = libsoc_board_init();

	if (!config)
	{
		printf("Cannot load board configuration.");
		return -1;
	}

If I use SSH to connect to the container then I can see the file in the same folder as the application, and I can read the file, but libsoc can’t find it. Does it need to be in another location?

Ok, for the 1st issue (libsoc-dev not installed), the problem is that settings in the “common” section are replaced by those in the specialized debug and release ones, and for arg there is actually a settings already specified, leading to arg.common entry being ignored.
An alternative would be that the tool would merge the two, leading to arg being the concatenation of common.arg and debug.arg, but in this way you may not be able to completely remove one command or override its content…
For 2nd issue, if the file is on the target, can you try to load it using it’s full path?
Check also that it’s using linux EOL (LF) character and not Windows one (CR+LF), this may be an issue if you checkout things from git.

Hi @valter.tx. Sorry for the long delay, I’ve been travelling. The previous problem was that the .conf file was using Windows line endings because I checked it out of git on Windows before deploying it to the module, as you suspected. I image this is a common problem when developing for Linux on a Windows PC, I’ll need to watch out for that.

The next line of code in the libsoc example is:

ledgpioid = libsoc_board_gpio_id(config, "SODIMM_190");

This appears to work correctly as it returns 132, which I know is the GPIO number for SODIMM_190. I can work with GPIO 132 using sysfs directly.

The line after that is:

ledgpio = libsoc_gpio_request(ledgpioid, LS_SHARED);

This line fails and returns null. I was expecting this line of code to export GPIO 132 in sysfs, but it doesn’t. I can export and unexport is manually using bash inside the container.

Can you help me make the next step?

@valter.tx here is some more helpful information. To debug libsoc I have cloned the source and included it in my application instead of using it as a library. I can then see that libsoc_gpio_request fails on this line of code and returns fd as NULL:

int fd = file_open ("/sys/class/gpio/export", O_SYNC | O_WRONLY);

I also noticed that the code actually runs perfectly if I log into the container with bash and execute it directly. It only fails when running inside the debugger in Visual Studio.

When I log into the container using bash I am using the root account and it works. I added a call to getlogin_r() to my code to determine which account VIsual Studio is using for debugging and the result was “torizon”. It must be that root has access to sysfs and torizon does not. Does that makes sense and how do I give torizon access to sysfs? Should the torizon account have access to sysfs by default in the container?

@valter.tx I was able to give the torizon user access to the required files in /sys by creating a new user group. The code which uses libsoc works now. One problem though is that each time a GPIO pin is exported it is only shared with the root account, even if it was the torizon account which exported it. That means I need to edit the permissions each time I export a new GPIO pin. There must be a better way.

Hello @MikeS, I was also travelling, I am sorry if also my reply is a bit delayed.
I suppose that you did not create the project using “root” as the user in the wizard. Of course it makes sense to run using a regular user, but in this case you will probably need to assign a group to the GPIO filesystem branches and then create the same group (only ID should match) inside the container and assign your user to it.
Selecting “root” as the user inside the container is a shortcut that can make development easier.

The sample code you posted uses the GPIO file system interface that is not available inside containers and has been anyway deprecated. libgpiod uses the new interface via /dev/gpiochip*.
Here:
https://developer.toradex.com/knowledge-base/libgpiod
you can find information and samples.

Hi @jeremias.tx ,

I’m trying to use libsoc and I have followed this topic. I get as far as MikeS did in this line:

int fd = file_open ("/sys/class/gpio/export", O_SYNC | O_WRONLY);

where fd is null and I get this message in the debug screen: “libsoc-file-debug: Read-only file system”.
My question is the same: how do I give access to sysfs to the torizon user?

Thanks in advance for your help.
Andreu.