Creating nRF51x22 Embedded Targets

In my previous post I demonstrated the use of a Free Pascal embedded target for the nRF52832 Nordic Semiconductor SoC processor.  This chip also has a little brother, the nRF51422 and it’s variant the nRF51822.  Unfortunately, they aren’t currently supported as embedded targets by Free Pascal.  So I have returned to looking into the feasibility of implementing them.

Last year, I asked about support for these chips on the Free Pascal mailing list and was kindly created a patch by Michael Ring giving provisional support for them.  Unfortunately, I ran out of time to work on this and in the meantime the Nordic Semiconductor SDK and Free Pascal have gone through several version changes.

Ideally, the current processor SVD should be used to generate new support files, but to get up and running as quickly as possible, I have adapted Michael’s original patch to work with  Free Pascal trunk and structured it consistently with the new nRF52832 support.

I have also adapted my demo for the nRF52832 to run on the nRF51422 and tested it with my the nRF51-DK.  The only change to the source code is to the pin numbers of the board’s LEDs.  The build setup is identical to that of the nRF52-DK, with only minor changes to the flashing script:

nrfjprog --recover -f NRF51
nrfjprog --program Test.hex --verify --chiperase -f NRF51
nrfjprog --rbp ALL -f NRF51
nrfjprog -r -f NRF51

The new last line forces a reset for the board, which happens automatically on the nRF52-DK, but not with the nRF51-DK.  To use this program within the Lazarus IDE the custom project options need to be set to:


Otherwise this behaves identically to the nRF52832 version.  The test program is available here and the experimental patch for Free Pascal here.  Hopefully, I will be able to develop this into a stable solution for supporting these targets with the help of the excellent Free Pascal developer community.

Free Pascal with nRF52832 Embedded Target

In addition to targeting all of the mainstream desktop OS environments, Free Pascal is also capable of generating code for bare metal architectures. This is supported by cross compiler builds with the target operating system parameter (-T) set to ’embedded’, in combination with the target CPU (-P) and architecture instruction set (-Cp) parameters identifying the required processor.

I want to be able create embedded programs for the Nordic Semiconductor ARM SoC’s the nRF52832 and nRF51822.  Fortunately, Free Pascal already contains support for the nRF52832 in the current trunk version (3.1.1) and that is what I will be using here.  The nRF51822 will have to be the subject of a future post!

The process of creating a cross-compiler I have already looked at in my post ‘Cross-compiling to Pi Zero’.  The procedure is exactly the same for an embedded target, except for the embedded parameter and the fact that only a minimal RTL is required.  This minimal RTL creation is controlled by the make file options ‘buildbase’ and ‘installbase’.  So the actual building and installing commands for a nRF52832 cross compiler are as follows (all parameters on a single line):

make buildbase CROSSINSTALL=1 OS_TARGET=embedded CPU_TARGET=arm 
            SUBARCH=armv7em CROSSOPT="-O2 -gw2" CROSSBINDIR=/usr/bin/ 

sudo make installbase CROSSINSTALL=1 OS_TARGET=embedded CPU_TARGET=arm 
            SUBARCH=armv7em CROSSOPT="-O2 -gw2" 
            BINUTILSPREFIX=arm-none-eabi- PREFIX=/usr

They can replace the commands given in the script for the Pi Zero as it is identical in all other respects.  Once the cross compiler is installed, a program may be compiled for the nRF52832 with the following command line:

fpc -Tembedded -Parm -Wpnrf52832 -CpARMV7EM -XParm-none-eabi- 
                                             -Oonostackframe Test.lpr

Note the key parameter ‘-Wpnrf52832’ which identifies the exact embedded target to build for.  There is a very useful command line parameter for a Free Pascal cross compiler:

ppcrossarm -iu

Which lists all of the supported embedded targets for that particular compiler.  This is a good check that the cross compiler was created with the correct command line options.

To transfer the program to the target board I use nrfjprog which can be installed from the RF5x-Command-Line-Tools-Linux64.  The actual commands to perform the transfer are:

nrfjprog --recover -f NRF52
nrfjprog --program Test.hex --verify --chiperase -f NRF52
nrfjprog --rbp ALL -f NRF52

On the nRF52-DK, which is the test platform I am using, the program starts running as soon as the board resets at the end of the transfer.  Obviously the build and transfer commands can be contained in a single make files so the day-to-day workflow feels very similar to using GCC, just with much faster build times.

However, this being Free Pascal, it is possible to forget about explicitly executing make from the command-line and instead we can use the various Lazarus project options to perform the same operations when the Lazarus build command is executed (Shift F9).  Even the nrfjprog steps may be invoked using the ‘Execute After’ compiler settings, so that we never have to leave the IDE!  For anyone interested, my ‘proof of concept’ test program (simple nRF5x SDK ‘Blinky’ translation) is available here.


First Steps with the MtM Kit

Before I can start work on developing my own software for the MtM motion sensor kit, I need to connect the hardware to my laptop via USB tethering.  The interface board (MtAid01) provides a micro USB port, but this is purely used to supply power and does not implement a debugging connection.  However the MtAid01 board does provide a Segger J-Link ‘Serial Wire Debug’ interface to which J-Link capable hardware can be connected.

As it happens, the Nordic nRF51-DK, which I have previously worked with, includes a J-Link chipset and provides a serial wire debug interface to enable it to be connected to an external module, bypassing the onboard ARM SoC.  Therefore, my working setup consists of a USB connection between my laptop and the nRF51-DK board; then a serial wire connection to the MtAid01; into which is plugged the MtConnect04S module containing the actual chip to be programmed!


Fortunately, MtM provide a useful overview of setting up the wiring for this in their blog post:  ‘Connect MtConnect03 with nRF51 DK’.  The revision of the base board shown is an older model of the MtAid01 than the one I have, but it is close enough to work out the correct connections as the pins are consistently labelled.

To actually use this connection to flash the nRF51822 on either the nRF51-DK or the MtConnect04S requires software to transfer the system binary image.  On Ubuntu, the operating system automatically shows a mounted volume called JLINK when J-Link hardware is plugged into a USB port.  This can be used to flash the chip by simply copying the binary image ‘hex’ files to this mount point!

However, for more fine grained control over the flashing process and to be able to write command scripts, I have opted to install two additional command line utilities: nrfjprog and mergehex.  These programs are available from Nordic Semiconductor for Linux, Windows and OSX.  In my case I downloaded the RF5x-Command-Line-Tools-Linux64.  I copied these programs to ‘/opt/nRF5x-Tools’ which I temporarily add to my system PATH when I need them.

To test this is all fully working I downloaded the sample ‘blinky application’ provided in the MtM blog article ‘How to program the flash of MtConnect04S’. along with the S110 Nordic Semiconductor SoftDevice to provide BLE services. Using these, I was able to successfully flash a MtConnect04S with the following script:

rm -f temp.hex
mergehex -m s110_nrf51822_7.3.0_softdevice.hex 
                                  20160105_blinky_arm.hex -o temp.hex
nrfjprog --recover -f NRF51
nrfjprog --program temp.hex --verify --chiperase -f NRF51
nrfjprog --rbp ALL -f NRF51
nrfjprog -r -f NRF51

Here mergehex prepends the BLE softdevice (s110_nrf51822_7.3.0_softdevice.hex) to the application (20160105_blinky_arm.hex) and then copies them to a temporary file (temp.hex).  This is then flashed to the target system with nrfjprog.  Finally, to test the unit disconnected from the nRF51-DK, I attached the coin battery module (MtAid02) to the now flashed MtConnect04S processor module.  When switched on, this successfully continued to run the LED blinking software.


Un-boxing an MtM IOT Kit

Inspired by the release of the BBC Micro:bit, I have started to look again at ARM based low power boards.  I am interested in their usefulness for fencing training aids and as a possible platform for use in wireless scoring systems.  Whilst researching this, I came across the IOT Developer Kits from MtM Tech, a Taiwanese electronics company.

unbox1 unbox2 unbox3unbox4 unbox5 unbox6

They use a stackable modular design similar in concept to Arduino shield boards, but considerably smaller, each unit being approximately 3cm square.  The units I am evaluating are a pair of MtM’s Motion Sensors kits.  Each of these consists of a MtAid01 extension board; a MtConnect04S processor and BLE board; a MtSense03 motion sensor board and a MtAid02 battery board.

What caught my eye, is that the CPU component is a Nordic Semiconductor nRF51 series chip, compatible with that in the nRF51-DK board that I tested last year with Free Pascal.  The Nordic board however, does not contain motion sensors, which for my purposes, restricted it’s usefulness.  By contract, with the MtM modular design I can combine the various electronics required for a particular project in a manner rather like playing with Lego!


For comparison in my last photograph, I have placed the MTM developer kit next to a Raspberry Pi Zero on the left and a BBC Micro:bit on the right.  As you can see it is very similar to the Micro:bit in overall dimensions, although it should be pointed out that the larger base board of the MTM kit, the MtAid01, is only required during programming and can be removed for normal use, making it clearly the smallest of the three devices.

My next step will be to setup a nRF51-DK to function as a programming and debugging interface for the MtM kit.  After that I will need to build a Free Pascal cross compiler to generate the CPU binaries to perform the control logic.  I will post my progress periodically here and I will also publish the build instructions and the source to any utilities I create here and on Bitbucket.

Raspberry Pi Lazarus Revisited

Much has changed since my original post about building Lazarus on the Raspberry Pi. Firstly, the Raspberry Pi now consists of quite a family of boards with very different characteristics; the Raspbian operating system has matured greatly and the Free Pascal and Lazarus projects have passed through several releases each.

I have been building Free Pascal and to a lesser extent Lazarus off and on over the last couple of years on the Pi and it is always a challenge!  There are older versions available in the Raspian repository which may be installed via apt-get, but they are quite well behind the current trunk releases of both projects; to the extent that it can make cross-platform portability quite difficult if you have used any of the newer features now available in the later versions.

As I am currently preparing for a project that will target several ARM processors, I thought I would take the opportunity to document as fully as I can the steps required to get a working Pascal IDE on the Raspberry Pi as an ARM reference board.

When working on a Raspberry Pi, it is important to realise that the computing resources available are really at the minimum end of what Lazarus, in particular, was designed to run with.  This is less of a problem on the Pi 2 and 3, but can cause real frustration on the A’s, B’s and Zeros.

I would recommend starting with a fresh install of Raspian to reduce the chances of conflicts or missing dependencies.  These instructions were tested with the ‘2016-09-23-raspbian-jessie’ image.  Before attempting the build process there are several development libraries that have to be installed for Lazarus to compile.  Subversion is also required to fetch the up-to-date sources of both the compiler and IDE:

sudo apt-get install subversion

The developer packages required by Lazarus can be installed by (removing returns):

sudo apt-get install -y libx11-dev libgdk-pixbuf2.0-dev libcairo2-dev 
gir1.2-coglpango-1.0 libpangox-sudo apt-get install -y libx11-dev 
libgdk-pixbuf2.0-dev libcairo2-dev gir1.2-coglpango-1.0 
libpangox-1.0-dev xorg-dev libgtk2.0-dev libpango1.0-dev1.0-dev 
xorg-dev libgtk2.0-dev libpango1.0-dev

If the target machine is ARM6 (i.e. not a Pi 2 or 3), memory restrictions will cause the build processes to fail at several points.  To get round these problem two steps are required.  Firstly the memory split between the CPU and GPU must be altered to give most of the RAM to the GPU.  This can be changed by:

sudo raspi-config

Then select ‘7 Advanced Options’ and ‘A3 Memory Split’, choose the option for 16Mb.

Secondly, the default SWAP file size of 100Mb is too small for the Lazarus make process.  It can be extended by editing the ‘/etc/dphys-swapfile’ configuration file, changing the ‘CONF_SWAPSIZE=100’ option from 100 to 2000. Obviously, you must have sufficient empty space on your SD card.  I am currently using 16Gb class 10 cards.

Now the make process should work on all Pi’s except the model A.  I have not attempted to build this on a model A myself, but I suspect it might not be possible due to the lower available RAM and given the trouble I have had getting this to compile on a model B.

The build process requires a working folder to store the source code and generate the binary output files.  This can be anywhere the user has write permissions to.  My normal practice is to have a folder called FreePascal that I store in my home folder within a ‘Projects’ folder.  So the full path to the Lazarus folder on a Raspberry Pi would be:


and the current trunk version of Free Pascal here:


These paths may be exchanged for any other preference, but the following scripts would need adapting accordingly.

Building Free Pascal
The compiler is self hosted, meaning it is built using itself!  To start things off, there must be an initial Free Pascal seed compiler.  Not only that, but it must be the prior official release version, so 3.1.1 (the current trunk version) requires 3.0.0.  Unfortunately there is no version 3 available for Raspian.  The latest version in the repository is 2.6.4 in the package ‘fp-compiler-2.6.4’.  So before 3.1.1 can be built a 3.0.0 seed compiler must be compiled first!  A seed compiler need not be installed, indeed just the raw executable is the only file required as it will build any other units itself from the available sources.  The compiler package can be downloaded without installing with this command:

sudo apt-get -d install fp-compiler-2.6.4

The actual file will be here:


A deb file is a special type of archive. It can be uncompressed and within it, there will be a file called ‘data.tar.xz’.  This is also an archive of the package files.  Extract this to a temporary folder and search for the file ‘ppcarm’.  This is the actual compiler program needed to start the 3.0.0 build process. Copy this file to:


Using Subversion, the 3.0.0 source code can be downloaded onto the Pi with:

cd /home/pi/Projects/FreePascal/
svn co 3.0.0

The 3.0.0 compiler can then be built with (all make options on a single line):

cd /home/pi/Projects/FreePascal/3.0.0
make clean all OPT="-dARMHF -O-" 

The additional pass-through options needed (OPT=”-dARMHF -O-“) ensures the inclusion of hard float support in the compiler and prevents 2.6.4 using optimisations that would fail on 2.6.4 during the build cycle.  This process will take a long time, go and have some lunch/tea/beer!  Once it has finished, check that there is a working 3.0.0 compiler:

/home/pi/Projects/FreePascal/3.0.0/compiler/ppcarm -l

Copy this new executable file to ‘/home/pi/Projects/FreePascal/ppcarm.6hf.3.0.0’ with:

cp /home/pi/Projects/FreePascal/3.0.0/compiler/ppcarm 

The rest of the 3.0.0 files are no longer needed (unless you wish to install this version) so they can be deleted with:

cd /home/pi/Projects/FreePascal/
sudo rm -r 3.0.0

Moving on to the trunk build, first download the latest Free Pascal source code:

cd /home/pi/Projects/FreePascal/
svn co 3.1.1

This can then be built with the 3.0.0 seed compiler:

cd /home/pi/Projects/FreePascal/3.1.1
make clean all OPT=-dARMHF 

This will also take a long time.  When it has finished, install the new compiler with:

cd /home/pi/Projects/FreePascal/3.1.1
sudo make install PP=compiler/ppcarm PREFIX=/usr
sudo rm -f /usr/bin/ppcarm
sudo ln -s /usr/lib/fpc/3.1.1/ppcarm /usr/bin/ppcarm

Check that this is working with:

fpc -l

The Free Pascal source code can optionally be installed with:

sudo make sourceinstall PREFIX=/usr
sudo rm -f /usr/share/fpcsrc
sudo ln -sf /usr/share/src/fpc-3.1.1/fpc /usr/share/fpcsrc

Finally a new configuration file can be created with:

sudo /usr/lib/fpc/3.1.1/samplecfg /usr/lib/fpc/3.1.1 /etc

Building Lazarus
As with the compiler the first step for Lazarus is to create a working folder and fetch the source code with Subversion:

cd /home/pi/Projects/FreePascal
 svn co Lazarus

Building Lazarus is then straight forward with:

cd /home/pi/Projects/FreePascal/Lazarus
make clean all

If this process stops with some thing like this:

Error: (xxx) Can't call the resource compiler "/usr/bin/fpcres", 
                                           switching to external mode

This will be due to exhausting the SWAP file which will need extending further as described above.  It is interesting to watch the build processes’ memory use with the ‘top’ command running in a second shell.  You can actually see the memory drop to zero as the swap file is exhausted at that point.

I don’t usually install Lazarus into the system folders as I regularly have to rebuild the IDE due to my use of various packages.  So instead, I run the program directly from the working folder. I do, however, create a desktop menu entry to integrate the application into the PIXEL desktop as described below.

Pre-built Seed Compilers
To save you many hours of your life, here are the two ARM6HF seed compilers as described above:

The first is extracted from the standard Raspian install and the second was built by the first stage of this process on a model B.  Using the ppcarm.6hf.3.0.0 file you can skip the first two stages of the Free Pascal build process and do something more worthwhile with your time!


Finishing Touches
The memory split applied at the beginning can now be reversed using raspi-config.  You need not reduce the SWAP file size unless you are pressed for space on your SD card.  I also like to create a Lazarus menu entry for the GUI.  In PIXEL, there is now a menu editor available on the ‘Preferences’ menu.  Browse to the ‘startlazarus’ program for the command option.  I like to use the icon ‘…/images/icons/Lazarus.png’ for the menu entry as I prefer the paw print graphic to the Cheater’s head, but that is just a personal preference!

Grid InQuest II RPI1 Build

I have finally got Lazarus built on a Pi model B!  The build process is identical to that on the Pi 2, except there is insufficient memory to complete the process.  To overcome this, I have reduced the GPU memory allocation to 16Mb and increased the Swap file size to 2Gb.  Without these changes, the Lazarus make command will fail with ‘Can’t call the resource compiler’ errors.  In fact this is caused by the process exhausting all available RAM and SWAP space.  You can watch this happening by having the ‘top’ command running in a second command shell whilst the build proceeds.

I have also used this new model B test platform to build a Grid InQuest II archive for the ARM 6 based Raspberry Pi’s.  I will test this on a Pi Zero and Model A tomorrow.  The archive itself is available on BitBucket here:

I will write a full description of my new build procedure in a further post later this week.

Grid InQuest II RPI2 Build

I have uploaded the test build for the Raspberry Pi 2 I mentioned in my previous post. In addition to the desktop application, I have built the dynamic library and the command line utilities.  The archive for this is available on BitBucket here:

As previously noted, the desktop application is usable, but sluggish in performance compared to an Intel based system.  However, the library and command line tools work well on Raspbian.  The dynamic library in particular could be useful for python programmers wanting to implement local coordinate systems within their Pi projects.


The current build will not run on any ARM 6 based Pis although it should work on a Pi 3, although this is untested.  I am currently working on a build system for ARM 6 and when I have this fully working, I will release an archive for use on model A’s, B’s and Zeros.

Grid InQuest II on Raspberry Pi

Although not an officially supported target, I have managed to get the Grid InQuest II source code to compile and run on a Raspberry Pi 2 running the new PIXEL desktop.  The load time is quite long and the globe display rather sluggish, but it otherwise works as expected.  There may be other issues concerning floating point precision, but at first glance it appears to be returning valid results.


I will build an experimental release package later this week, although I must stress again that this will be purely experimental and currently unsupported.  In addition, I expect it may only work for Pi model 2’s and 3’s.

I will also revise my build instructions in another post for Lazarus on the Raspberry Pi to reflect the current status.  Unfortunately, it is still far from simple to get a working up-to-date Free Pascal compiler and Lazarus IDE installed on a Raspbian desktop.


Cross-compiling to Pi Zero

I am currently preparing for an IOT type project and whilst waiting for the test hardware I thought I would practice setting up an ARM CPU development environment using a Raspberry Pi Zero.  However, instead of building the compiler on the Pi, this time I want to build a cross-compiler on my laptop and then copy my built projects to the Pi for testing.  This has the advantage of using the laptop for the development process, vastly improving compile times at the expense of making debugging a little more complex.  It is also the typical workflow used for developing software for embedded devices.

There is an excellent description of this build procedure on Big Dan’s Blog.  His focus is on building a 2.6.4 compiler for use with Lazarus 1.6.  There is also a slightly dated page describing it on the Free Pascal WIKI.  I am only interested in producing command line programs using the current Free Pascal trunk (3.1.1), so I currently don’t need to build Lazarus as well although I may well come back to this at some point.

Before building the cross-compiler I need to have the matching GNU BinUtils.  It is possible to get pre-built binaries, but it is not difficult to build them from source as required.  As of writing, the latest version is 2.27 and it is available here.  The source needs to be extracted into a working folder and the following commands executed there:

./configure --target=arm-linux --disable-werror
sudo make install

There is a slight complication in that an additional parameter is required for the assembler when used to generate binaries for the Pi.  It defines the required hardware interface version for the output binary (v5 in this case).  The solution suggested in the WIKI is to wrap the assembler in a script that adds this option automatically when the assembler is called.  To do this, I rename the actual binary:

mv /usr/local/bin/arm-linux-as /usr/local/bin/arm-linux-as-bin

Then create a Bash script to replace the ‘arm-linux-as’ file:

/usr/local/bin/arm-linux-as-bin -meabi=5 $@

Now that the required binary tools are in place I can move on to building Free Pascal from source.  Here is my script for doing this and installing the cross-compiler:

# Mount a ram drive to act as a fast temporary working area.
sudo mount -o size=8G -t tmpfs none /scratch

# Export the checkout to working folder. 
svn export --force /home/paul/Projects/FreePascal/3.1.1 /scratch/fpctmp

# Change to fpc working folder.
cd /scratch/fpctmp 
# Build the Arm hard float cross compiler for Raspberry Pi.
make crossall OS_TARGET=linux CPU_TARGET=arm CROSSOPT="-dFPC_ARMHF -CX 
# Install the cross compiler.s
sudo make crossinstall OS_TARGET=linux CPU_TARGET=arm 
     INSTALL_BASEDIR=/usr/lib/fpc/3.1.1 CROSSOPT="-dFPC_ARMHF -CX 

# Remove working folder.
sudo umount /scratch

This script is very similar to the one I use to build my main host compiler.  I am working on Kubuntu 16.10 and I use a temporary RAM Drive to improve the overall build time.  The make parameters describe the the target environment.  For Raspberry Pi Zero this is Linux on an Arm V6 CPU with hardware floating point support.

The default install location is ‘/usr/lib/fpc/3.1.1/ppcrossarm’, to use this without having to state the path I created a link at ‘/usr/bin/ppcrossarm’.  This also makes it callable from the main fpc compiler with cross-compile options.  The installation can be verified by calling ‘ppcrossarm -i’ on the command line, which should output:

Free Pascal Compiler version 3.1.1

Compiler date : 2016/11/09
Compiler CPU target: arm

A small test program similar to the one given in the WIKI page can be built and executed for the host computer with the following commands:

fpc info.pas

DATE 2016/11/08

The same program can be built for the Raspberry Pi with the following:

fpc -Tlinux -Parm -CfVFPV2 info.pas

And then executed from the Pi command Line via SSH:

pi@raspberrypi:~ $ ./info
DATE 2016/11/08                                                                
FPCTARGETCPU arm                                                               
FPCTARGETOS Linux                                                              

Lastly, I can use my desktop Lazarus as the working IDE and build for the Pi by setting the ‘Config and Target’ project options as shown in the screen shot below. Note that the ‘-CfVFPV2’ option must be added into the ‘Custom Options’ page as well.

Lazarus Cross-Compile Options

It is even possible to automate the transfer of the binary executable to the Pi Zero with the following command:

sshpass -p 'raspberry' scp test pi@rpi0.local:~

The SSHPASS command enables the automatic submission of the password.  SCP performs the actual copy via the SSH protocol.  SSHPASS is frowned upon for security reasons, but in this case, I am not worried about anyone knowing the passwords on my Pi’s!  SSHPASS can be installed on Ubuntu with:

sudo apt-get install sshpass


Pi Zero USB Connection

One advantage of a Raspberry Pi Zero over the other members of the Pi family is that it can be powered off it’s ‘USB’ port instead of it’s ‘PWR IN’ connector, thus requiring only a single USB cable to connect it to a host computer.  I have previously connected a Pi Model B using an ethernet cable as described in my post ‘Return to the Raspberry Pi!’, but the USB method makes for a far easier setup.  However to use the USB as a network interface requires some configuration on the Pi Zero.

To start with I imaged a micro SD card with a clean copy of Rasbian Lite.  Then to enable the network interface over USB a couple of configuration files need to be edited in the Pi’s boot partition.  You can do this by inserting the SD card into another computer and accessing the files there.  The two files for editing are config.txt and cmdline.txt.  Firstly, config.txt needs a single line adding to the end of the existing file:


Editing cmdline.txt can be a little tricky.  The entire contents must be on a single line (so don’t press return).  Also options must be entered separated by a single space. At the very end of the file enter a space after rootwait then add:


Now return the SD card to the Pi Zero and plug this into the host computer via the USB cable.  The Pi will startup and the computer should detect it as a network-able device.  On my system I needed to tweak the connection properties to change the IP4 settings method to ‘Shared to other computers’.

Previously, direct ethernet cabling to a Model B required the manual setup of static IP addresses on the Pi’s themselves.  This is no longer needed as Raspbian now includes a multicast domain name service Avahi, which implements the Bonjour protocol originally designed by Apple and is supported on all Macs and recent Linux distributions.  Windows will require additional drivers for this to work with Windows hosts.

The Avahi service will create a special network name, ‘raspberrypi.local’ by default, which can be used in place of the Pi’s IP address.  The ‘.local’ top level domains are specifically reserved for this type of local network usage.  The first part of the name is defined by the Pi’s hostname.  You can test this is working with ping:

ping raspberrypi.local
PING raspberrypi.local ( 56(84) bytes of data.
64 bytes from ( icmp_seq=1 ttl=64 time=0.262 ms
64 bytes from ( icmp_seq=2 ttl=64 time=0.263 ms
64 bytes from ( icmp_seq=3 ttl=64 time=0.275 ms
[1]+ Stopped ping raspberrypi.local

Once this connection is established, it can be used for SSH sessions in much the same way as any other network connection.  However, in my case, I have previously connected a different Pi with the same network name.  This upset SSH as you can see below:

ssh pi@raspberrypi.local
The ECDSA host key for raspberrypi.local has changed,
and the key for the corresponding IP address
is unknown. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
Someone could be eavesdropping on you (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
Please contact your system administrator.
Add correct host key in .ssh/known_hosts to get rid of this message.
Offending ECDSA key in .ssh/known_hosts:14
  remove with:
  ssh-keygen -f "/home/paul/.ssh/known_hosts" -R raspberrypi.local
ECDSA host key for raspberrypi.local has changed and you have requested 
strict checking.
Host key verification failed.

As I want to be able to work with multiple Pi’s in this manner, the best solution is to give them each a unique name, rather than have to regenerate the keys every time I want to use SSH.  The simplest way to do this is with the Raspbian command-line configuration tool raspi-config.  This requires root privileges so must be started with:

sudo raspi-config

The option to change the hostname is in the ‘Advanced Options’, ‘A2 Hostname’.  I changed mine to ‘rpi0’.  A restart is required for the hostname to be updated.  Once reconnected I could then use SSH as expected:

paul@laptop01:~$ ssh pi@rpi0.local
 The authenticity of host 'rpi0.local' can't be established.
 ECDSA key fingerprint is SHA256:---------------------------------.
 Are you sure you want to continue connecting (yes/no)? yes
 Warning: Permanently added 'rpi0.local' to the list of known hosts.
 pi@rpi0.local's password:

The programs included with the Debian GNU/Linux system are free;
 the exact distribution terms for each program are described in the
 individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
 permitted by applicable law.
 pi@rpi0:~ $