Raspbian: running a program using PascalIO from the IDE lazarus / 12-Debugger ---------------------------------------------------------------------- GuidoJ · 2021-03-02 14:57 Hello! I'm a very experienced Delphi developer and I'm taking first steps on a Raspberry PI 4 with Raspbian and FPC+Lazarus. Of course, I have next to no knowledge about LINUX. My current task: Switch an LED on and off. I downloaded the PascalIO package, then wrote some simple code that should turn an IO port on/off. var   IOvalue : boolean; procedure TForm1.Button1Click(Sender:TObject); var   pin: TGpioLinuxPin; begin   IOvalue := not IOvalue;   pin := TGpioLinuxPin.Create(12);   pin.Direction := gdOut;   pin.Value := IOvalue;   pin.Destroy; end. If I start the program from the IDE, nothing happens on pushing the button. Setting a breakpoint and stepping through the code makes the LED flash. From the console I need to use   sudo ./MyGPIOtest to start the program and get a response from the LED. The code seems to be OK. Any suggestions, how to make the program run correctly from within the IDE? Thank you for your help! ---------------------------------------------------------------------- MarkMLl · 2021-03-02 15:13 Without having tried it, my suspicion is that when you destroy the pin you're setting it to be an input again so it stops driving the LED. BTW, it's "Linux", and is named after its initial developer rather than being an initialism. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-02 16:13 Everything works fine, outside the IDE or during singlestepping. The LED even stays on after terminating the program. ---------------------------------------------------------------------- MarkMLl · 2021-03-02 16:47 Quote from: GuidoJ on March 02, 2021, 05:13:26 pmEverything works fine, outside the IDE or during singlestepping. The LED even stays on after terminating the program. If you're running it in the IDE, how are you giving it sudo? Have you made sure that your normal user ID is a member of the gpio group? MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-02 17:23 Hi Mark! Four cases: 1. console -> "sudo ./MyGPIOtest" - result OK 2. start in IDE [F9] - LED does not react to button 3. start in IDE [F9], singlestepping [F8] - result OK 4. start in IDE without debugger [ctrl][shift][F9] - LED does not react to button Cases 2 and 4 - running inside the IDE but not singlestepping [F8] through the code - are the problem. GPIO group? Ah... "sudo adduser pi gpio" -> the user "pi" is already in the group "gpio" So the answere is "yes". Thanks, Guido ---------------------------------------------------------------------- MarkMLl · 2021-03-02 17:30 Quote from: GuidoJ on March 02, 2021, 06:23:17 pmFour cases: 1. console -> "sudo ./MyGPIOtest" - result OK 2. start in IDE [F9] - LED does not react to button 3. start in IDE [F9], singlestepping [F8] - result OK 4. start in IDE without debugger [ctrl][shift][F9] - LED does not react to button Cases 2 and 4 - running inside the IDE but not singlestepping [F8] through the code - are the problem. GPIO group? Ah... "sudo adduser pi gpio" -> the user "pi" is already in the group "gpio" So the answere is "yes". I don't have a confident answer then. I've been looking at lower-level access to the GPIO bits over the last week or so, i.e. interacting directly with them at the /sys/class/gpio/* or /dev/gpiochip* level (there's two different APIs) but not using PascalIO... my major interest was trying to disentangle different behaviour on PCs and RPis. I think one final thing I'd suggest is to add an APM like this Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  IOvalue : boolean; procedure TForm1.Button1Click(Sender:TObject);var  pin: TGpioLinuxPin;begin  IOvalue := not IOvalue;  pin := TGpioLinuxPin.Create(12);  pin.Direction := gdOut;  pin.Value := IOvalue;  Application.ProcessMessages;  pin.Destroyend;  ...just in case there's something tricky about the way the component has been written. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-02 19:23 Nope, the APM did not work! I guess, I just have to learn more about rights and user levels in Linux. My current project: Make my heating react to the weather forecast. Get a forecast website via HTTP/HTTPSParse the website and extract the sunshine hours and temperature data (already running on windows)Switch off the gas heater "a few hours" before the sun starts to shine and let the thermal solar system take over...using GPIO and maybe an optocoupler to signal the status to the heating(later) readout the energy content of the solar tanks via 1-wire-bus. Thanks, Mark, for your ideas. ---------------------------------------------------------------------- MarkMLl · 2021-03-02 19:52 I'm a bit bemused as to what's going on. At this point the normal thing would be for you to zip or tar your entire project and tack it onto a message so that somebody else could try it... I for one though aren't promising immediate time since tomorrow is going to be hard enough work as it is. MarkMLl ---------------------------------------------------------------------- avra · 2021-03-03 09:12 Quote from: GuidoJ on March 02, 2021, 06:23:17 pm1. console -> "sudo ./MyGPIOtest" - result OK 2. start in IDE [F9] - LED does not react to button 3. start in IDE [F9], singlestepping [F8] - result OK 4. start in IDE without debugger [ctrl][shift][F9] - LED does not react to buttonDoes "./MyGPIOtest" without sudo works? If not, then sudo gives some permissions that debugger already has, but IDE and simple command line do not have? Normally, gpio group should be enough, so you should investigate why sudo makes the difference in your case. ---------------------------------------------------------------------- GuidoJ · 2021-03-03 11:39 Thanks, avra! Without sudo the LED does not react, so sudo (root rights) are needed. That is also stated in the documentation of the PascalIO Package. I did some tracing an added some more code. The error occurs at FpOpen('/sys/class/gpio//gpio12/direction', O_WRONLY); Error 9: Bad file number. I checked UserID, GroupID and ProcessID with and without debugging, but they where the same. Is there a way to run the program from the IDE with root privileges? Maybe via "run"->"run parameters"->"launching application"? ---------------------------------------------------------------------- MarkMLl · 2021-03-03 12:13 Quote from: GuidoJ on March 03, 2021, 12:39:24 pmWithout sudo the LED does not react, so sudo (root rights) are needed. That is also stated in the documentation of the PascalIO Package. There's something wrong there, since you've already said that you're in the gpio group. QuoteI did some tracing an added some more code. The error occurs at FpOpen('/sys/class/gpio//gpio12/direction', O_WRONLY); Error 9: Bad file number. I checked UserID, GroupID and ProcessID with and without debugging, but they where the same. Does that actually exist? I was looking at those devices in a slightly different context a few days ago https://forum.lazarus.freepascal.org/ index.php/topic,53365.msg395471.html#msg395471 and there definitely wasn't a gpio12 on my Rpi. # ls -l /sys/class/gpio ...the leading # is a convention that indicates that your shell login is root, you'll usually get there using sudo su or similar. QuoteIs there a way to run the program from the IDE with root privileges? Maybe via "run"->"run parameters"->"launching application"? Ouch. Short answer: no, longer answer (again, slightly different context) https://forum.lazarus.freepascal.org/index.php/topic,53541.ms g396133.html#msg396133 What you can do however is run your program using gdbserver as root i.e. something like (in my case) # gdbserver :2345 ./Watchxxx-x86_64-linux-gtk2 In the IDE you'll need Tools -> Options -> Debugger -> Debugger backend -> Debugger type and path set to gdbserver, and Debugger_Remote_Port set to 2345 to match the command. You might also need to install gdbserver if it's not on your system already... that's fairly foolproof but I've had the occasional problem with it at the GPIO level. I've just tried using /usr/bin/sudo -A -k -E as the "Launching application" without success, even though that works as part of the build sequence. I'm afraid I'm out shortly for a few hours so if you choose to try that I won't be able to advise until later. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-03 15:13 Hi Mark! That's quite a handful... but looking into remote debugging is on my list anyway  QuoteDoes that actually exist?root@raspberrypi:/home/pi# ls -l /sys/class/gpio insgesamt 0 -rwxrwx--- 1 root gpio 4096 Mär  3 13:09 export lrwxrwxrwx 1 root gpio    0 Mär  3 13:09 gpiochip0 -> ../../devices/platform/soc/fe200000.gpio/gpio/gpiochip0 lrwxrwxrwx 1 root gpio    0 Mär  3 13:09 gpiochip504 -> ../../devices/ platform/soc/soc:firmware/soc:firmware:gpio/gpio/gpiochip504 -rwxrwx--- 1 root gpio 4096 Mär  3 13:09 unexport But, as the code works with root rights, the filename should be OK. I will look into remote debugging tomorrow morning (that's CET). Greetings from germany, Guido ---------------------------------------------------------------------- MarkMLl · 2021-03-03 16:39 Quote from: GuidoJ on March 03, 2021, 04:13:24 pmThat's quite a handful... but looking into remote debugging is on my list anyway  'Fraid so :-) OK, I think I see one of the problems. With the important caveat that I've not looked at the specific library/package that you're using, I think you're missing a step. Watch: markMLl@raspberrypi:/sys/class/gpio$ ls -l total 0 -rwxrwx--- 1 root gpio 4096 Mar  3 16:21 export lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0 lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip100 -> ../../devices/gpiochip1/gpio/gpiochip100 lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip504 -> ../../devices/ platform/soc/soc:firmware/soc:firmware:expgpio/gpio/gpiochip504 -rwxrwx--- 1 root gpio 4096 Mar  3 16:23 unexport markMLl@raspberrypi:/sys/class/gpio$ echo 12 > export markMLl@raspberrypi:/sys/class/gpio$ ls -l total 0 -rwxrwx--- 1 root gpio 4096 Mar  3 16:24 export lrwxrwxrwx 1 root gpio    0 Mar  3 16:24 gpio12 -> ../../devices/platform/soc/3f200000.gpio/gpiochip0/gpio/gpio12 lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0 lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip100 -> ../../devices/gpiochip1/gpio/gpiochip100 lrwxrwxrwx 1 root gpio    0 Feb 26 15:11 gpiochip504 -> ../../devices/ platform/soc/soc:firmware/soc:firmware:expgpio/gpio/gpiochip504 -rwxrwx--- 1 root gpio 4096 Mar  3 16:23 unexport markMLl@raspberrypi:/sys/class/gpio$ ls -l gpio12/direction -rwxrwx--- 1 root gpio 4096 Mar  3 16:24 gpio12/direction markMLl@raspberrypi:/sys/class/gpio$ cat gpio12/direction in It's that echo 12 > export that's enabling gpio12 (an i/o line associated with the physical gpiochip0 device) in the context of the API that uses the pseudo-files in /sys/class/gpio. As you'll see if you browse the "thread from Hell" that I linked to, the overall naming etc. is a problem. You might find these useful if you start prodding the pseudo-files directly: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i (* Read a single line from the designated file, trimming leading and trailing  whitespace from the result. Return a blank (zero-length) line on error.*)function Cat(const fn: string): string; var  fd: text; begin  result := '';  try    Assign(fd, fn);    Reset(fd);    try      try      Read(fd, result)      except        result := ''      end;      result := Trim(result)    finally      Close(fd)    end  except  endend { Cat } ;  (* Send the string passed as the parameter, trimming trailing control characters  but no other whitespace, to the designated file; normally appending a single  newline as terminator. Return false on error.*)function Echo(str: string; const fn: string; noNl: boolean= false): boolean; var  fd: text; begin  result := true;  while (str <> '') and (str[Length(str)] < #$20) do    SetLength(str, Length(str) - 1);  try    Assign(fd, fn);    Rewrite(fd);    try      try        Write(fd, str);        if not noNl then          WriteLn(fd);      except        result := false      end    finally    Close(fd)    end  except    result := false  endend { Echo } ;  I've not explored debugging this stuff on an RPi, and I suspect that you don't really need to use sudo because your normal user is in the gpio group. My rather rushed experiments with Lazarus+sudo+debugging on a PC earlier weren't particularly successful. I can say however that using gdbserver is successful on a PC debugging stuff that needs elevated privilege to create low-numbered sockets (Linux is more retrictive that Windows in this area. Hadjab MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-04 07:35 Hi Mark! PascalIO does exactly what you suggested, only encapsulated in a lot of functions. They create and destroy the files in every call, therefore the file ../gpio12 is visible only if you stop the program at the correct moment. I did this and... root@raspberrypi:/home/pi# ls -l /sys/class/gpio insgesamt 0 -rwxrwx--- 1 root gpio 4096 Mär  3 16:34 export lrwxrwxrwx 1 root gpio    0 Mär  4 08:12 gpio12 -> ../../devices/platform/soc/fe200000.gpio/gpiochip0/gpio/gpio12 lrwxrwxrwx 1 root gpio    0 Mär  3 16:34 gpiochip0 -> ../../devices/platform/soc/fe200000.gpio/gpio/gpiochip0 lrwxrwxrwx 1 root gpio    0 Mär  3 16:34 gpiochip504 -> ../../devices/ platform/soc/soc:firmware/soc:firmware:gpio/gpio/gpiochip504 -rwxrwx--- 1 root gpio 4096 Mär  3 16:34 unexport I found a workaround: If I start the lazarus IDE as root my program works from within the IDE! Not a nice thing to do, but is does the trick. Next stop "remote debugging"  ...and maybe looking into some other GPIO packages. ---------------------------------------------------------------------- MarkMLl · 2021-03-04 07:51 Quote from: GuidoJ on March 04, 2021, 08:35:47 amPascalIO does exactly what you suggested, only encapsulated in a lot of functions. They create and destroy the files in every call, therefore the file ../gpio12 is visible only if you stop the program at the correct moment. I did this and... That's lousy design IMO. Apart from anything else it wastes a lot of processor time parsing names in the /sys/class/gpio tree... but what do I know :-) If you look for example at https://elinux.org/RPi_GPIO_Code_Samples which is a well-respected site, you will see that while programs that start and then terminate (e.g. C run from the command line) do a single-shot state change and then unexport on termination, the Lazarus/FPC example exports the pin at startup, changes state as required, and keeps hold of the pin as long as the GUI program is running. There are other implications to device/pin ownership and direction, and it's entirely possible to write a program that changes its UI based on which pins are instantaneously input and which are output (and which are neither, because they've not been exported). QuoteIf I start the lazarus IDE as root my program works from within the IDE! Not a nice thing to do, but is does the trick. It should definitely not be necessary to do that. I'll try to take a look at it a bit later in the day. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-04 08:02 QuoteThat's lousy design IMO.My thought exactly! ---------------------------------------------------------------------- GuidoJ · 2021-03-04 13:20 Hi Mark! I'm sorry to say, but the remote debugging stuff is way out of my league right now. Too many unknown concepts and conventions. I'll stick with the root rights for the IDE and continue learning about Linux and the Raspi hardware. I'll revisit remote debugging much later. Thank you for your help! ---------------------------------------------------------------------- MarkMLl · 2021-03-04 13:47 Quote from: GuidoJ on March 04, 2021, 02:20:29 pmI'm sorry to say, but the remote debugging stuff is way out of my league right now. Too many unknown concepts and conventions. I'll stick with the root rights for the IDE and continue learning about Linux and the Raspi hardware. I'll revisit remote debugging much later. You DEFINITELY do not need to run the IDE as root. I've now got Lazarus/FPC on a test RPi, and I'm successfully single-stepping through code that reads/writes GPIO bits using the sysfs API (i.e. the pseudo-files in /sys/class/gpio). My usual user ID is a member of the gpio group, apart from that nothing special. In my case I'm SSHing into the RPi and tunnelling Lazarus through the link, but I'd certainly not expect that to be the magic factor that got something working. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-04 15:26 Does is work, when you are not singlestepping? That's where my problem started. ---------------------------------------------------------------------- MarkMLl · 2021-03-04 15:50 Quote from: GuidoJ on March 04, 2021, 04:26:38 pmDoes is work, when you are not singlestepping? That's where my problem started. Most if not all of the time :-) I /might/, /possibly/, have seen it falling straight through (i.e. no GUI display) on one or perhaps two occasions. My suspicion is that not all of the function keys etc. are getting through to the IDE, i.e. Raspbian (or whatever it's called these days) might be intercepting some of them for its own use. I've got a note in my source that some of the GPIO manipulation failed to work using gdbserver and that I ended up running the program (not the IDE) as root to check one final detail... I mention that for completeness. I've got occasional lockups when setting a breakpoint inside button handlers etc., but that's unconnected. MarkMLl ---------------------------------------------------------------------- dseligo · 2021-03-04 22:25 Quote from: MarkMLl on March 04, 2021, 02:47:47 pmtunnelling Lazarus through the link What do you mean by that? ---------------------------------------------------------------------- MarkMLl · 2021-03-05 07:53 Quote from: dseligo on March 04, 2021, 11:25:36 pmQuote from: MarkMLl on March 04, 2021, 02:47:47 pmtunnelling Lazarus through the link What do you mean by that? SSH has the capability of tunnelling X11 network traffic, you need this in ssh_config Host * #   ForwardAgent no ForwardX11 yes ... Then all you have to do is type in the name of the IDE (I usually go via a shell script which has both the Lazarus and FPC version numbers in it) and it will appear on your local screen. Not very efficient particularly if an X11 program generates excessive input device (mouse etc.) traffic, but it's fine for headless development systems. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-07 12:35 Just to give you an update: I spend the last few days figuring out, how to install FPC 3.2.0 and Lazarus 2.0.12 on my Raspberry PI 4. It turned out, I had to compile from the sources. For now, apart from one minor error, Lazarus 2.0.12 seems to work. ---------------------------------------------------------------------- MarkMLl · 2021-03-07 14:22 Quote from: GuidoJ on March 07, 2021, 01:35:06 pmJust to give you an update: I spend the last few days figuring out, how to install FPC 3.2.0 and Lazarus 2.0.12 on my Raspberry PI 4. It turned out, I had to compile from the sources. For now, apart from one minor error, Lazarus 2.0.12 seems to work. I admit that that's normally how I do it, I normally start off with the FPC project's tarball (rather than whatever comes with the distro) and was only able to find 3.0.2 the other day. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-07 15:48 Another strange concept - at least after 35 years of windows. I started with turbo pascal for windows  Amazon have delivered a Raspberry PI zero w to me. Now I can start looking into remote debugging. I plan on using the PI zero for my heating project. ---------------------------------------------------------------------- MarkMLl · 2021-03-07 16:19 Remember that if you can run Linux on it, you can run Lazarus/FPC/gdb on it. At that point if you can SSH into it you can effectively do /local/ debugging. I can't speak for gdbserver to a non-local process, so suggest that you try it locally first. The major gotchas are (a) do not modify or rebuild your program between starting the program using gdbserver and using the IDE to start debugging and (b) the command line parameters are applied to gdbserver+program: not in the IDE. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-08 08:20 Hi Mark! I build three installation files for FPC 3.2.0 and Lazarus 2.0.12   fpc-laz_3.2.0_armhf.deb   fpc-src_3.2.0_armhf.deb   lazarus-project_2.0.12-0_armhf.deb see -> https://wiki.freepascal.org/Build_current_FPC_and_Lazarus_for_Raspbian I you like, I can prepare a download for you. ---------------------------------------------------------------------- MarkMLl · 2021-03-08 09:07 I'm fine thanks. Been doing it since something like Lazarus 0.9.24. MarkMLl ---------------------------------------------------------------------- GuidoJ · 2021-03-18 15:41 Another update: I have a basic webserver running that reads out and displays some (currently 4) 1-wire temperature sensors, is able to switch a relay, and handles some configuration settings. My PI zero now has Raspbian Light installed - very compact; I don't really need the GUI for my application. I switched from PascalIO to Raspbians pigpio package and now handle the GPIO pins via shell calls: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses ..., Unix, ...;[..]function SetPin(pinNo, State:integer):longint;var  st : string;begin  st:=format('pigs w %d %d', [pinNo, State]);  result:=fpSystem(st);end;[..] That may be much slower, but - as I want to react to a weather forecast - split second timing is not an issue. The function above can do about 130 changes per second on a Pi4; more than adequate. The calls to "pigs" do not require root privileges and debugging from within the IDE works fine.