Raspberry Pi 3 Setup Guide
A guide to running Flight Software Development Kit software on the Raspberry Pi (2 & 3).
Introduction
The following guide walks you through the steps required to configure a Raspberry Pi to run flight software developed using the FSDK.
It has been written specifically for the Raspberry Pi 2 & 3. Other models of Raspberry Pi may require different steps. For simplicity we will refer to the Raspberry Pi as the "Pi" throughout this document.
The guide begins by explaining how to install the Raspberry Pi OS and configure the various drivers that are supported in the FSDK. It then goes on to describe how to build flight software for the Pi, how to run it on the device, and how to interact with it using TMTCLab.
Installing Raspberry Pi OS
You first need to flash the Raspberry Pi operating system (OS) on the Pi. Complete the following steps to install Raspberry Pi OS:
Insert a microSD card into your PC using a relevant adapter. Ensure that the SD card is between 8GB and 32GB in size.
Download, install and run Raspberry Pi Imager by following the steps shown here.
Select 'Choose Device' and 'Raspberry Pi 3'. Then select 'Choose OS'>'Raspberry Pi OS (32-bit)'.
Select 'Choose Storage' and select your microSD card from the list of options, then select Next.
When prompted whether you’d would like to apply OS customisation settings, select 'Edit Settings'.
Select
Complete all fields in the 'General' tab, and toggle 'Enable SSH' and select
'Use password authentication' on the 'Services' tab. If you choose to
overwrite any of the existing default values on these tabs, be sure to keep
a note of the new values as you will need them later, specifically the
hostname, username and password. Then select Save>`Yes` to apply the OS customisation settings.
Click 'Yes' to confirm that you want to write to the selected microSD card and select Continue.
After completing all of the above steps, the OS will now be flashed to your microSD card.
Lastly, eject your card from the PC and insert it into your Pi’s microSD card slot.
Connecting to the Pi using SSH
You can now power up the Pi and connect to it.
The simplest way to interact with the Pi from your Ubuntu machine is with SSH on the command line. Follow the steps below to connect and interact with the Pi using SSH.
Apply power to the Pi using one of the micro USB ports or the power port.
The Pi will take several minutes to fully boot and connect to the internet. A green LED on the Pi should flash before eventually turning off after several minutes. Once the LED has turned off, the board has booted successfully.
Connect to the device using SSH by running the following command in the terminal. If you changed the username and/or hostname in the OS configuration steps above, then use the custom values instead of pi and raspberrypi respectively:
ssh pi@raspberrypi
When prompted, input the password. By default this should be raspberry. If you changed the password in the OS configuration steps above, use the password you set.
You should now be connected and able to run commands on the Pi remotely.
|
Firewall settings on your Ubuntu machine and router may interfere with SSH. If you are unable to connect to the Pi using SSH after following the steps above, ensure that your firewall settings allow you to communicate with devices over SSH. |
Configuring drivers on the Pi
We provide a variety of different Deployments that can be run on the Pi which are shipped with FSDK.
One of these Deployment Types, demo_pi, can be found in the fsdk-22.2/OBSW/demo_pi directory. This Deployment is configured to make use of various drivers on the Pi that we
currently provide support for. These drivers include its I2C driver, its SPI driver, and its Serial (UART) driver.
For software to communicate with these drivers on the device, they first need to be enabled in the kernel.
Configuring the I2C and SPI drivers
To enable the I2C and SPI drivers:
Connect to the Pi over SSH by running the following command in a terminal:
ssh pi@raspberrypi
In the same terminal, Open the Pi’s configuration tool by running the following command:
sudo raspi-config
Select 'Interface Options'>`I2C`>`Yes` to enable I2C.
Select 'Interface Options'>`SPI`>`Yes` to enable SPI.
Select Finish to close the configuration tool.
If prompted whether you would like to reboot the device, select 'Yes'. Wait until the Pi has fully rebooted then reconnect to it again over SSH.
To confirm that the I2C and SPI drivers are enabled, run the following command in the terminal:
lsmod
If successfully enabled, i2c_bcm2835 and spi_bcm2835 should be included in the list reported by lsmod.
Configuring the Serial driver
There are two different Serial (UART) drivers available on the Pi - UART0 which is the PL011 UART, and UART1 which is the mini UART.
The mini UART is more limited than the PL011 UART as it relies on other parts of the System on Chip (SoC) to operate. PL011, however, is a standalone UART driver, so it offers all the functionality from a typical UART driver.
|
If you wish to know more about the details of these two drivers refer to the BCM2835 datasheet. |
By default, the PL011 UART is configured to work in conjunction with the on board bluetooth/wireless module as it offers better performance than the mini UART - an important factor when working with wireless protocols.
If you do not require use of the Bluetooth/wireless functionality and/or you require a reliable Serial connection over the GPIO header, we recommend you follow the following steps to reconfigure the PL011 UART to be used as the GPIO header’s primary UART.
To configure the PL011 UART as the primary UART:
Disable the Bluetooth module by running the following command in the terminal. This sets PL011 as the primary UART.
cat dtoverlay=disable-bt >> /boot/firmware/config.txt
Disable the system service that initialises the modem by running the following command in the terminal:
sudo systemctl disable hciuart
Now that the bluetooth module has been disabled, configure the primary UART (now the PL011 UART) to be used for the GPIO header instead of the serial console.
Open the Pi’s configuration tool by running the following command in the terminal:
sudo raspi-config
Select 'Interface Options'>`Serial Port`.
When asked whether you would like a login shell to be accessible over serial, select 'No'.
When asked whether you would like the serial port hardware to be enabled, select 'Yes'.
To close the configuration tool, click 'Finish'.
If prompted whether you would like to reboot the device, select 'Yes'. Wait until it has fully rebooted then reconnect to it over SSH.
To confirm that the PL011 UART has successfully been configured as the primary UART, run the following command in the terminal:
ls -l /dev/serial*
If successfully configured, /dev/serial0 → ttyAMA0 should be displayed in the output of the ls command.
|
|
With these steps all complete, your Pi should now be properly configured to enable access to its onboard I2C, SPI and Serial drivers.
Downloading the Pi Toolchain
To build flight software binaries that can run on the Pi, you need to use the correct toolchain.
FSDK includes the pi2.mk and the pi3.mk build configuration located at: fsdk-22.2/OBSW/Source/build_system/config. This build configuration specifies that binaries should be built using the arm-linux-gnueabi toolchain for the Pi 2 and the arm-linux-gnueabihf toolchain for the Pi 3. These toolchains can be downloaded and installed using the apt library.
Pi 2 Toolchain
sudo apt-get install gcc-arm-linux-gnueabi
Pi 3 Toolchain
sudo apt-get install gcc-arm-linux-gnueabihf
Building Flight Software for the Pi
With the toolchain successfully downloaded and installed you can build flight software to run on the Pi.
The following steps will guide you through this process using the demo_pi Deployment.
Navigate to the demo_pi example Deployment in the fsdk-22.2/OBSW/source/demo_pi directory.
Remove the ArduCAM and GPIO component instances from the deployment.xml model and add the I2CMaster component instance.
Show the component instances removed from the deployment.xml model.
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file describes the demo_pi deployment.
-->
<ModelElement xmlns="http://www.brightascension.com/schemas/gen1/model"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Deployment name="demo_pi">
<Description>
This is an example deployment of GenerationOne for the Raspberry PI.
</Description>
<!-- Component type imports -->
<Import>
<!-- The component types used by this deployment -->
<Use type="Version" />
<Use type="storage.Storage" />
<Use type="ConfigManager" />
<Use type="io.driver.OSTime" />
<Use type="storage.config.FileConfigStore" />
<Use type="storage.fs.PosixFS" />
<Use type="storage.FileStorageProvider" />
<Use type="storage.FileSystemManager" />
<Use type="event.EventDispatcher" />
<Use type="io.net.tcp.TCPServer" />
<Use type="io.net.PacketStream" />
<Use type="io.net.SpacePacket" />
<Use type="io.net.pus.PUSCore" />
<Use type="io.net.pus.PUSHK" />
<Use type="io.net.pus.PUSEvent" />
<Use type="io.net.pus.PUSLDT" />
<Use type="io.net.pus.PUSAMS" />
<Use type="io.net.CFDP" />
<Use type="tmtc.TMBeacon" />
<Use type="tmtc.TMDebug" />
<Use type="tmtc.TMTCEvent" />
<Use type="io.net.ParamTransfer" />
<Use type="component.AAS.AASTarget" />
<Use type="component.PAS.PASTarget" />
<Use type="subsys.OBT" />
<Use type="Dummy" />
<Use type="logging.CommandLogger" />
<Use type="logging.EventLogger" />
<Use type="DataPool" />
<Use type="Sampler" />
<Use type="Aggregator" />
<Use type="Monitor" />
<Use type="logging.DataLogger" />
<Use type="auto.EventAction" />
<Use type="auto.TimeAction" />
<Use type="io.bus.spi.SPIMaster" />
<Use type="io.bus.i2c.I2CMaster" />
- <Use type="subsys.ArduCAM" />
- <Use type="io.driver.GPIO" />
</Import>
<!-- Component deployment -->
<Deploy>
<!-- Component Groups -->
<ComponentGroup name="cdh">
<Description>
Command and data handling group.
</Description>
<Documentation>
<Text>
Contains the components used to assist with the function of the
spacecraft such as loggers, autonomous components and TMTC components.
</Text>
</Documentation>
</ComponentGroup>
<ComponentGroup name="cdh.logging">
<Description>
Group containing the logging components.
</Description>
<Documentation>
<Markdown>
For demo_linux, the included logging components are:
- BaseLogger (used for logging data)
- EventLogger (used to log raised events)
- TCLogger (used for logging Telecommands)
</Markdown>
</Documentation>
</ComponentGroup>
<ComponentGroup name="cdh.tmtc">
<Description>
Group containing the components that handle TMTC.
</Description>
<Documentation>
<Text>
TMTC Components are used to connect the comms stack to the components
so that action/parameter/event interactions can occur.
</Text>
</Documentation>
</ComponentGroup>
<ComponentGroup name="comms">
<Description>
The communications stack group.
</Description>
<Documentation>
<Markdown>
Contains the components used to form the comms stack.
For demo_linux, this includes:
- TCP Client
- PacketStream
- SpacePacket
- PUS components
</Markdown>
</Documentation>
</ComponentGroup>
<ComponentGroup name="comms.pus">
<Description>
Group containing the PUS components.
</Description>
<Documentation>
<Text>
PUS components are used to provide functionality that corresponds to
the PUS standard. See ECSS-E-70-41A.
</Text>
</Documentation>
</ComponentGroup>
<ComponentGroup name="comms.services">
<Description>
Group containing the service proxy components.
</Description>
<Documentation>
<Text>
Service proxies allow services to be provided to external systems and
allow this deployment to access services provided externally.
</Text>
</Documentation>
</ComponentGroup>
<ComponentGroup name="core">
<Description>
Group containing the core components for the deployment.
</Description>
<Documentation>
<Text>
Contains components integral to the functionality of the OBSW.
</Text>
</Documentation>
</ComponentGroup>
<ComponentGroup name="platform">
<Description>
Group containing the components integral to the platform being deployed.
</Description>
<Documentation>
<Text>
For demo_linx, no platform specific hardware or software is required,
however DummySubsys can be used to simulate TMTC with a component.
</Text>
</Documentation>
</ComponentGroup>
<!-- Component Instances -->
<Component name="Version" type="Version" />
<Component name="core.Storage" type="storage.Storage" />
<Component name="core.ConfigurationManager" type="ConfigManager" />
<Component name="core.Time" type="io.driver.OSTime" />
<Component name="core.OBT" type="subsys.OBT">
<Connections>
<Services>
<Service name="time" component="core.Time" service="time" />
</Services>
</Connections>
</Component>
<Component name="core.FileSystem" type="storage.fs.PosixFS" />
<Component name="core.FileConfigStore" type="storage.config.FileConfigStore">
<Connections>
<Services>
<Service name="fs" component="core.FileSystem" service="fs" />
</Services>
</Connections>
</Component>
<Component name="core.FileStorageProvider" type="storage.FileStorageProvider">
<Connections>
<Services>
<Service name="fs" component="core.FileSystem" service="fs" />
</Services>
</Connections>
</Component>
<Component name="core.FileSystemManager" type="storage.FileSystemManager">
<Connections>
<Services>
<Service name="fs" component="core.FileSystem" service="fs" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="decompress" priority="3" />
</Tasks>
</Component>
<Component name="core.EventDispatcher" type="event.EventDispatcher">
<Tasks>
<PeriodicTask name="dispatcher" period="1.0" priority="2" />
</Tasks>
</Component>
<Component name="comms.TCPServer" type="io.net.tcp.TCPServer">
<Tasks>
<PeriodicTask name="receive" priority="3" />
<SporadicTask name="receiveTimeout" priority="3" />
</Tasks>
</Component>
<Component name="comms.PacketStream" type="io.net.PacketStream">
<Connections>
<Services>
<Service name="stream" component="comms.TCPServer" service="data" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="receive" priority="3" />
<SporadicTask name="receiveTimeout" priority="3" />
</Tasks>
</Component>
<Component name="comms.SpacePacket" type="io.net.SpacePacket">
<Connections>
<Services>
<Service name="spacePacket" component="comms.PacketStream" service="packet" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="transmitTimeout" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="receiveTimeout" priority="3" />
</Tasks>
</Component>
<Component name="comms.pus.PUSCore" type="io.net.pus.PUSCore">
<Connections>
<Services>
<Service name="pusPacket" component="comms.SpacePacket" service="dataPacket" channel="0" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="transmitTimeout" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="receiveTimeout" priority="3" />
</Tasks>
</Component>
<Component name="comms.pus.PUSHK" type="io.net.pus.PUSHK">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="0" />
<Service name="pusReceive" component="comms.pus.PUSCore" service="dataPacket"
channel="0" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
</Tasks>
</Component>
<Component name="comms.pus.PUSEvent" type="io.net.pus.PUSEvent">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="1" />
<Service name="pusReceive" component="comms.pus.PUSCore" service="dataPacket"
channel="1" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
</Tasks>
</Component>
<Component name="comms.pus.PUSLDT" type="io.net.pus.PUSLDT">
<Connections>
<Services>
<Service name="pusPacket" component="comms.pus.PUSCore" service="dataPacket" channel="2" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="transmitTimeout" priority="3" />
<SporadicTask name="transmitTransferTimeout" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="receiveTimeout" priority="3" />
<SporadicTask name="receiveTransferTimeout" priority="3" />
</Tasks>
</Component>
<Component name="comms.pus.PUSToAAS" type="io.net.pus.PUSAMS">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="4" />
<Service name="pusReceive" component="comms.pus.PUSCore" service="dataPacket"
channel="4" />
<Service name="target" component="comms.services.AASTarget" service="remote" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="requestCompleteTarget" priority="3" />
</Tasks>
</Component>
<Component name="comms.CFDP" type="io.net.CFDP">
<Connections>
<Services>
<Service name="fs" component="core.FileSystem" service="fs" />
<Service name="ut" component="comms.SpacePacket" service="dataPacket" channel="1" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="timer" priority="3" />
<SporadicTask name="remoteRequestComplete" priority="3" />
</Tasks>
</Component>
<Component name="comms.services.AASTarget" type="component.AAS.AASTarget" />
<Component name="comms.pus.PUSToPAS" type="io.net.pus.PUSAMS">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="5" />
<Service name="pusReceive" component="comms.pus.PUSCore" service="dataPacket"
channel="5" />
<Service name="target" component="comms.services.PASTarget" service="remote" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="requestCompleteTarget" priority="3" />
</Tasks>
</Component>
<Component name="comms.services.PASTarget" type="component.PAS.PASTarget" />
<Component name="comms.pus.PUSToParamTransfer" type="io.net.pus.PUSAMS">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="6" />
<Service name="pusReceive" component="comms.pus.PUSCore" service="dataPacket"
channel="6" />
<Service name="target" component="comms.ParamTransfer" service="remote" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
<SporadicTask name="requestCompleteTarget" priority="3" />
</Tasks>
</Component>
<Component name="comms.ParamTransfer" type="io.net.ParamTransfer">
<Connections>
<Services>
<Service name="ldt" component="comms.pus.PUSLDT" service="dataPacket" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
<SporadicTask name="receive" priority="3" />
</Tasks>
</Component>
<Component name="cdh.tmtc.TMBeacon" type="tmtc.TMBeacon">
<Connections>
<Services>
<Service name="hkHandler" component="comms.pus.PUSHK" service="hkReporting" />
</Services>
</Connections>
<Tasks>
<PeriodicTask name="send" period="5.0" priority="2" />
</Tasks>
</Component>
<Component name="cdh.tmtc.TMDebug" type="tmtc.TMDebug">
<Connections>
<Services>
<Service name="pusSend" component="comms.pus.PUSCore" service="dataPacket" channel="3" />
</Services>
</Connections>
<Tasks>
<SporadicTask name="transmit" priority="3" />
</Tasks>
</Component>
<Component name="cdh.tmtc.TMTCEvent" type="tmtc.TMTCEvent">
<Connections>
<Components>
<Component name="eventHandler" component="comms.pus.PUSEvent" />
</Components>
</Connections>
</Component>
<Component name="cdh.logging.TCLogger" type="logging.CommandLogger">
<Connections>
<Services>
<Service name="timestamp" component="core.Time" service="time" />
</Services>
</Connections>
<Tasks>
<PeriodicTask name="store" period="10.0" priority="2" />
</Tasks>
</Component>
<Component name="platform.DummySubsys1" type="Dummy" />
<Component name="platform.PlatformSPI" type="io.bus.spi.SPIMaster">
<Description>
The main SPI bus for interfacing to the test SPI
</Description>
</Component>
- <Component name="platform.PlatformI2C" type="io.bus.i2c.I2CMaster">
- <Description>
- Platform I2C bus
- </Description>
- </Component>
- <Component name="platform.ArduCAM" type="subsys.ArduCAM">
- <Connections>
- <Services>
- <Service name="arduChip" component="platform.PlatformSPI" service="data" channel="0" />
- <Service name="sensor" component="platform.PlatformI2C" service="data" channel="0" />
- <Service name="fs" component="core.FileSystem" service="fs" />
- </Services>
- </Connections>
- <Tasks>
- <SporadicTask name="capture" priority="3" />
- </Tasks>
- </Component>
- <Component name="platform.GPIO" type="io.driver.GPIO" />
+ <Component name="BSC" type="io.bus.i2c.I2CMaster">
+ <Description>
+ The Broadcomm Serial Controller which controls the platform I2C bus.
+ </Description>
+ </Component>
<Component name="cdh.logging.EventLogger" type="logging.EventLogger">
<Connections>
<Services>
<Service name="timestamp" component="core.Time" service="time" />
</Services>
</Connections>
<Tasks>
<PeriodicTask name="store" period="10.0" priority="2" />
</Tasks>
</Component>
<Component name="cdh.DataPool" type="DataPool">
<Connections>
<Services>
<Service name="time" component="core.Time" service="time" />
</Services>
</Connections>
<ParameterAliases>
<ParameterBlock blockName="poolParameters">
<ComponentParameter name="DummySubsys1" component="platform.DummySubsys1"
parameter="dummyParam8" />
<ComponentParameter name="DummySubsys1" component="platform.DummySubsys1"
parameter="dummyParam16" />
<ComponentParameter name="DummySubsys1" component="platform.DummySubsys1"
parameter="dummyParam32" />
</ParameterBlock>
</ParameterAliases>
</Component>
<Component name="cdh.BeaconAggregator" type="Aggregator" />
<Component name="cdh.BaseSampler" type="Sampler">
<Connections>
<Components>
<Component name="DataPool" component="cdh.DataPool" />
</Components>
</Connections>
<Tasks>
<PeriodicTask name="sample" period="5.0" priority="2" />
</Tasks>
</Component>
<Component name="cdh.BaseAggregator" type="Aggregator" />
<Component name="cdh.BaseMonitor" type="Monitor">
<Tasks>
<PeriodicTask name="refresh" period="5.0" priority="2" />
</Tasks>
</Component>
<Component name="cdh.logging.BaseLogger" type="logging.DataLogger">
<Connections>
<Services>
<Service name="timestamp" component="core.Time" service="time" />
</Services>
</Connections>
<Tasks>
<PeriodicTask name="sample" period="10.0" priority="2" />
<PeriodicTask name="store" period="60.0" priority="2" />
</Tasks>
</Component>
<Component name="cdh.EventAction" type="auto.EventAction" />
<Component name="cdh.TimeAction" type="auto.TimeAction">
<Connections>
<Services>
<Service name="time" component="core.Time" service="time" />
</Services>
</Connections>
<Tasks>
<PeriodicTask name="main" period="1.0" priority="2" />
</Tasks>
</Component>
</Deploy>
</Deployment>
</ModelElement>
Generate the Deployment, specifying the relevant build config. The following command is used to generate the Deployment for the Pi 3:
codegen deployment generate demo_pi --build-config pi3
Build the demo_pi Deployment by running the following command:
make -C demo_pi/ force target
This builds all the component instances within the Deployment using the toolchain you installed in the previous section. It also generates a Spacecraft Database (SCDB) for interacting with tmtclab.
The resultant binaries for the Deployment can be found in the demo_pi/pi3/bin directory.
The SCDB can be found in the demo_pi/doc directory.
Running Flight Software on the Pi
To run the binaries on the Pi, they first need to be copied over to the device.
This section demonstrates this process using the Default binary generated in the previous section.
Open a terminal in the demo_pi directory and run the following command to copy the binary to the Pi:
scp bin/pi3/demo_pi pi@raspberrypi:
Use SSH to connect to the Pi as described previously:
ssh pi@raspberrypi
The scp command copied the demo_pi binary to the pi user’s home directory. This is the same directory which the ssh shell starts in.
Run the following command to execute the binary file:
./demo_pi
This should run the binary on the device resulting in the following output being printed to the console:
INF: Main.c:67 Platform initialisation successful
INF: Deployment.c:36 Deployment initialisation successful
With the binary running, you can interact with it using tmtclab:
Open a terminal in the fsdk-22.2/GNDSW/TMTCLab directory and run the following command to start tmtclab:
./runLab.cmd
Load the Deployment's SCDB into tmtclab. The SCDB can be found in the demo_pi/doc directory.
Connect to the Deployment using the Pi’s IP address and the port specified in the Deployment's TCPServer initialization data. If unchanged from default values, this should be 51423.
Invoke the Version component instance's dumpVersion Action.
Verify that the following output is printed to the Pi’s console with the date and time that your binary was built:
INF: Version.c:126 Version: Version: 0.1 build 4D61646520696E20466C696768746B697400
INF: Version.c:132 Version: Build date: May 28 2024
INF: Version.c:134 Version: Build time: 11:55:26
You have now successfully built, run, and interacted with a Deployment on the Pi.