Search code examples
c#linuxraspberry-pigpioraspberry-pi-zero

Mono cannot access file even though linux shell can without root


this might be a wrong place to ask this (but I think its right place since it involves programming).

So I got a raspberry pi zero for our school project. I SSH'd into it to check out what it can do with it. I made some research about how to use the GPIO pins on this card.
Basically:

$ echo 17 > /sys/class/gpio/export
$ echo out > /sys/class/gpio/gpio17/direction
$ echo 1 > /sys/class/gpio/gpio17/value
$ echo 17 > /sys/class/gpio/unexport

Enables GPIO pin 17 and writes digital 1 into it and 'unexport's it, no root is needed.
I also wanted to try out some of the languages in this card. I tried python, C# and Rust without a problem (even though rust compiles very slow, it works). So I started using my favourite language C# with mono. Installing it and compiling a basic program wasn't a big deal, It works.
So I write this:

using System;
using System.IO;

namespace Program
{
    public static class Program
    {
        public static void Main()
        {
            if (Directory.Exists("/sys/class/gpio/gpio17/"))
                File.WriteAllText("/sys/class/gpio/unexport", "17");

            File.WriteAllText("/sys/class/gpio/export", "17");
            File.WriteAllText("/sys/class/gpio/gpio17/direction", "out");
            File.WriteAllText("/sys/class/gpio/gpio17/value", "1");
        }
    }
}

Basically, if it finds the 17 pin open, 'unexport' it then re-export it, set as output and write digital 1.
Compilation:

mcs program.cs -out:program.exe -debug && ./program.exe

Output:

Unhandled Exception:
System.UnauthorizedAccessException: Access to the path "/sys/class/gpio/gpio17/direction" is
denied.

What? How? It works with sudo mono ./program.exe and no it doesn't with mono ./program.exe
Sure, I can always use wiringPi or python but I am curious about this one and couldn't find an answer. It doesn't make sense to me. /sys/class/gpio/gpio17 is a symbolic link and I tried to access to original path too with no luck.

What might be the problem here?


Solution

  • Guesses:

    • You unexport it first, then export it and immediately access it, I had in the past several time problems on some OS e. g. deleting a file and immediately creating it again, add a waiting time (not really clean code, but if it works)
    • check the difference of the files/folders with linux command "ls -la" or more
    • call the shell command, that worked, from C# via e. g. Process class
    • Some few times Mono did not work like C# on Windows, a workaround had to be found
    • try to open a stream to these files and leave them open? Or even a pipe is possible to these files?