Lazarus on Raspberry Pi




The Raspberry Pi is a credit-card-sized single-board computer. It has been developed in the UK by the Raspberry Pi Foundation with the intention of stimulating the teaching of basic computer science in schools. Raspberry Pis are also used for multiple other purposes that are as different as media servers, robotics and control engineering.

The Raspberry Pi Foundation recommends Raspbian Wheezy as standard operating system. Alternative systems running on RPI include RISC OS and various Linux distributions, as well as Android.

Lazarus runs natively under the Raspbian operating system.

Installing and compiling Lazarus

Simple installation under Raspbian

Raspberry Pi 1

In the Raspbian OS it is easy to install Lazarus and Free Pascal. In order to do this simply open a terminal window and type:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install fpc
sudo apt-get install lazarus

This installs a precompiled, stable version of FPC and Lazarus on the Raspberry Pi. Of course, a network connection is required. Installation may take about 30 minutes, but major portions of this process take place automatically. After installation you may instantly start Lazarus from the “Programming” section of the LXDE start menu.

If you need a newer version, or if Lazarus complains about a broken leakview, here.

Raspberry Pi 2 

Since June 2015 the regular “out of the box” installation method also works for Raspberry Pi 2 Model B. The version that gets installed is, however, quite old. For those looking to build the latest FPC and Lazarus IDE see this article.

Lazarus on Raspberry Pi

Cross compiling for the Raspberry Pi from Windows

1. Using fpcup

One way is to use fpcup to set up a cross compiler; follow these instructions: fpcup#Linux_ARM_cross_compiler

2. Using scripts

Alternatively, for a more manual approach using batch files, you can follow these steps.

2.1 Prerequisites

FPC 2.7.1 or higher installed with sourcecode
Install the Windows version from the Linaro binutils for linux gnueabihf into %FPCPATH%/bin/win32-armhf-linux [1]

2.2 Example Build Script (adapt paths as needed)

set PATH=C:\pp\bin\i386-win32;%PATH%;
set FPCMAKEPATH=C:/pp
set FPCPATH=C:/pp
set OUTPATH=C:/pp271
%FPCMAKEPATH%/bin/i386-win32/make distclean OS_TARGET=linux CPU_TARGET=arm  CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
 
%FPCMAKEPATH%/bin/i386-win32/make all OS_TARGET=linux CPU_TARGET=arm CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
if errorlevel 1 goto quit
%FPCMAKEPATH%/bin/i386-win32/make crossinstall CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" OS_TARGET=linux CPU_TARGET=arm FPC=%FPCPATH%/bin/i386-win32/ppc386.exe INSTALL_BASEDIR=%OUTPATH%
 
:quit
pause

With the resulting ppcrossarm.exe and ARM RTL you will be able to build a cross Lazarus version as usual and compile FPC projects for the Raspberry Pi and other armhf devices. Remember that not all – especially Windows – libraries are available for Linux arm.

Compiling from sources

You may want to compile Lazarus from subversion sources. See Michell Computing: Lazarus on the Raspberry Pi for details.

Compiling from sources on Raspberry with Gentoo (and other distro)

If you want to install the latest stable release of fpc and, additional and isolated, the trunk fpc compiler: you can read the following guide. It was written using gentoo but this guide will be useful with any distro: Install fpc on Raspberry with Gentoo

Accessing external hardware

One of the goals in the development of Raspberry Pi was to facilitate effortless access to external devices like sensors and actuators. There are five ways to access the I/O facilities from Lazarus and Free Pascal:

  1. Direct access using the BaseUnix unit
  2. Access through encapsulated shell calls
  3. Access through the wiringPi library.
  4. Access through Unit rpi_hal.
  5. Access through Unit PiGpio.
  6. Access through the PascalIO library.

1. Native hardware access

Simple test program for acessing the GPIO port on Raspberry Pi

Test circuit for GPIO access with the described program

Simple demo implementation of the circuit from above on a breadboard

This method provides access to external hardware that doesn’t require additional libraries. The only requirement is the BaseUnix library that is part of Free Pascal’s RTL.

Switching a device via the GPIO port

The following example lists a simple program that controls the GPIO pin 17 as output to switch an LED, transistor or relais. This program contains a ToggleBox with name GPIO17ToggleBox and for logging return codes a TMemo called LogMemo.

For the example, the anode of a LED has been connected with Pin 11 on the Pi’s connector (corresponding to GPIO pin 17 of the BCM2835 SOC) and the LED’s cathode was wired via a 68 Ohm resistor to pin 6 of the connector (GND) as previously described by Upton and Halfacree. Subsequently, the LED may be switched on and off with the application’s toggle box.

The code requires to be run as root, i.e. either from a root account (not recommended) or via su.

Controlling unit:

unit Unit1;
 
{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Unix, BaseUnix;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    LogMemo: TMemo;
    GPIO17ToggleBox: TToggleBox;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure GPIO17ToggleBoxChange(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
const
  PIN_17: PChar = '17';
  PIN_ON: PChar = '1';
  PIN_OFF: PChar = '0';
  OUT_DIRECTION: PChar = 'out';
 
var
  Form1: TForm1;
  gReturnCode: longint; {stores the result of the IO operation}
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormActivate(Sender: TObject);
var
  fileDesc: integer;
begin
  { Prepare SoC pin 17 (pin 11 on GPIO port) for access: }
  try
    fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
  { Set SoC pin 17 as output: }
  try
    fileDesc := fpopen('/sys/class/gpio/gpio17/direction', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, OUT_DIRECTION[0], 3);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
 
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
  fileDesc: integer;
begin
  { Free SoC pin 17: }
  try
    fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
 
procedure TForm1.GPIO17ToggleBoxChange(Sender: TObject);
var
  fileDesc: integer;
begin
  if GPIO17ToggleBox.Checked then
  begin
    { Swith SoC pin 17 on: }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_ON[0], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    finally
      gReturnCode := fpclose(fileDesc);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    end;
  end
  else
  begin
    { Switch SoC pin 17 off: }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_OFF[0], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    finally
      gReturnCode := fpclose(fileDesc);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    end;
  end;
end;
 
end.

Main program:

program io_test;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1
  { you can add units after this };
 
{$R *.res}
 
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Lazarus on Raspberry Pi schematic

Reading the status of a pin

Demo program for reading the status of a GPIO pin

Test circuit for GPIO access with the described program

Possible implementation of this test circuit

Of course it is also possible to read the status of e.g. a switch that is connected to the GPIO port.

The following simple example is very similar to the previous one. It controls the GPIO pin 18 as input for a binary device like a switch, transistor or relais. This program contains a CheckBox with name GPIO18CheckBox and for logging return codes a TMemo called LogMemo.

For the example, one pole of a push-button has been connected to Pin 12 on the Pi’s connector (corresponding to GPIO pin 18 of the BCM2835 SOC) and via a 10 kOhm pull-up resistor with pin 1 (+3.3V, see wiring diagram). The other pole has been wired to pin 6 of the connector (GND). The program senses the status of the button and correspondingly switches the CheckBox on or off, respectively.

Note that the potential of pin 18 is high if the button is released (by virtue of the connection to pin 1 via the pull-up resistor) and low if it is pressed (since in this situation pin 18 is connected to GND via the switch). Therefore, the GPIO pin signals 0 if the button is pressed and 1 if it is released.

This program has again to be executed as root.

 

For more detail: Lazarus on Raspberry Pi


© 2015 Powered By Engineering Projects Team, Raspberry Pi Projects

Scroll to top