Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b298b58
Initial plan
Copilot Nov 6, 2025
9b74b83
Add fundamentals documentation: getting-started, gpio-basics, protoco…
Copilot Nov 6, 2025
85be084
Add reading-datasheets guide and protocol documentation including UART
Copilot Nov 6, 2025
833984e
Add platform guides, glossary, troubleshooting, project setup, and de…
Copilot Nov 6, 2025
24108f0
Update main Documentation README with new structure and navigation
Copilot Nov 6, 2025
9668133
Fix variable name inconsistency in gpio.md code example
Copilot Nov 6, 2025
b6fbe45
Remove unicode emojis from section titles and reorganize structure
Copilot Nov 13, 2025
e571139
Remove unicode emojis from all documentation files
Copilot Nov 13, 2025
1a5e30c
Restructure protocol documentation with consistent format: what it is…
Copilot Dec 18, 2025
5e2bb42
Remove backup file accidentally committed
Copilot Dec 18, 2025
5edae09
Fix critical API issues, broken links, stale content, and address all…
Copilot Apr 2, 2026
4fda4a7
Fix markdownlint errors in protocol documentation
Copilot Apr 2, 2026
faca762
Fix markdownlint errors in Documentation/fundamentals/ files
Copilot Apr 2, 2026
40385c1
Fix markdownlint errors in documentation files
Copilot Apr 2, 2026
c830b31
Fix markdownlint errors in documentation files
Copilot Apr 2, 2026
0f7ff03
Fix markdownlint errors in troubleshooting.md
Copilot Apr 2, 2026
369d73e
Fix MD060/table-column-style markdownlint errors in documentation
Copilot Apr 2, 2026
83ba5b0
Fix driver auto-detection docs, systemctl command, I2C leak, markdown…
Copilot Apr 2, 2026
2559a0f
Fix broken link to non-existent Visual Studio IoT page
joperezr Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 109 additions & 95 deletions Documentation/README.md

Large diffs are not rendered by default.

577 changes: 577 additions & 0 deletions Documentation/deployment/containers.md

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions Documentation/deployment/cross-compilation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# How to Deploy an IoT App
Comment thread
joperezr marked this conversation as resolved.

This provides information how to prepare a Publish Profile and deploy an application to a development board.

## Using Visual Studio

1. Once you have an application setup in Visual Studio, right-click the project in the Solution Explorer and select Publish...
2. In the Pick a publish target dialog, select Folder, choose a folder to publish your application files and click Create Profile. The example below shows a path of C:\PublishedApps.
3. A default profile, FolderProfile.pubxml, will now be created and added to your project. You can view it in the Solution Explorer under your project > Properties > PublishProfiles folder.
4. It is a good practice to rename your profile to something you can relate with your project. In the Publish Window, click the Actions dropdown and select Rename Profile. A Rename Profile dialog prompts you to rename your profile. Click Save after renaming.
5. You can configure the profile's settings by clicking Configure... in the Publish Window. A Profile Settings dialog prompt includes a few options. **Notes**:
* Prior to Visual Studio 2019, the Target Runtime doesn't offer a selection for Linux ARM or Windows ARM. When using an older version of Visual Studio, you will need to manually open the profile's XML and change the RuntimeIdentifier element to **linux-arm** or **win-arm** shown below:

```csharp
<RuntimeIdentifier>linux-arm</RuntimeIdentifier>
or..
<RuntimeIdentifier>win-arm</RuntimeIdentifier>
or both..
<RuntimeIdentifiers>linux-arm;win-arm</RuntimeIdentifiers>
```

* Deployment Mode Options:
* **Framework Dependent** - App relies on the presence of a shared system-wide version of .NET Core on the target system. This will create a smaller size package.
* **Self-contained** - .NET Core and required libraries will be bundled with your application creating a larger size package. IoT devices are usually constrained by memory resources. There is a useful NuGet package available that helps trim unused files. Reference [Microsoft.Packaging.Tools.Trimming](https://www.nuget.org/packages/Microsoft.Packaging.Tools.Trimming/) for more information.
* While there are more options available that can be modified, this only shows the basics. It is recommended to read more in the provided **References** section below.
6. You can view the contents by double-clicking the profile. The content should look similar to the XML below after your modifications.
* Example:

```xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishDir>C:\PublishedApps</PublishDir>
<RuntimeIdentifier>linux-arm</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<_IsPortable>false</_IsPortable>
</PropertyGroup>
</Project>
```

7. You can now publish your application by clicking Publish in the Publish Window. All folders/files should now be packaged in the specified publish folder.
8. Your application is now ready for deployment to the target device.

## Using .NET Core CLI

1. Once you have an application setup, navigate to the directory where the project is located and run the `dotnet publish` command. Below shows a few common options and example.
* -c defines the build configuration (Debug or Release).
* -o specifies the output path where application will be packaged.
* -r publishes the application for given runtime (e.g. linux-arm, win-arm, etc.) being targeted.

```shell
dotnet publish -c Release -o C:\DeviceApiTester -r linux-arm
```

2. Your application is now ready for deployment to the target device.

## How to Copy an IoT App to Target Device

The application can be deployed to a target device once the Publish Profile and related files have been packaged. There are various tools for transferring files depending on the platform being used. Below are a few popular tools available.

* [PuTTy](https://www.putty.org/)
* PSCP (provided with PuTTy install)
* [FileZilla](https://filezilla-project.org/)

## References

* [Have Your Pi and Eat It Too: .NET Core 2.1 on Raspberry Pi](https://channel9.msdn.com/Events/dotnetConf/2018/S314)
* [Visual Studio publish profiles for ASP.NET Core app deployment](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/visual-studio-publish-profiles?view=aspnetcore-2.2)
* [Deploy an app to a local folder using Visual Studio](https://docs.microsoft.com/en-us/visualstudio/deployment/quickstart-deploy-to-local-folder?view=vs-2017)
* [Deploy .NET Core apps with Visual Studio](https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-vs?tabs=vs156)
* [How to: Edit Deployment Settings in Publish Profile (.pubxml) Files and the .wpp.targets File in Visual Studio Web Projects](https://go.microsoft.com/fwlink/?LinkID=208121)
* [.NET Core application deployment](https://docs.microsoft.com/en-us/dotnet/core/deploying/)
* [dotnet publish](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21)
* [.NET Core RID Catalog](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog)
152 changes: 152 additions & 0 deletions Documentation/deployment/systemd-services.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# How to start app automatically on boot using systemd

## Create your app

For the purpose of this document let's assume you have deployed your app under:

`
/home/pi/myiotappfolder/myiotapp
`

The app name is `<myiotapp>` in this documentation you would replace the entire string including the carrots in your files.

To run this you will need to make your app run as root please read the section on [Security Considerations](#security-considerations)

Make sure to make your app ```<myiotapp>``` is executable by using the command:

```shell
# Requires root permissions
chmod +x <myiotapp>
```

## Create systemd.service unit

For this example a script titled `<myiotapp>.service` will be used. The folder that this application is ran from is `/home/pi/myiotappfolder` Please replace accordingly with your app name or the location you decide to save your script. Remember to add the `.service` as the file extension

Here is an example systemd.service file that you can use as a template. Make sure to use a Unix end of line when creating the systemmd.service file.

```shell
[Unit]
#The # is a comment line
#Documentation https://www.freedesktop.org/software/systemd/man/systemd.service.html

#Place short description here
Description=My IOT Device Service

#This will not start execution of this file until the network connection is made
#It can be replaced with other parameters of your choosing
After=network.target

[Service]
#Default: Startup type
Type=Simple

#Edit this with your file name. In this example the app executable is in the /home/pi/myiotappfolder
#The file we are running and made executable is <myiotapp>
#ExecStart runs this executable script
ExecStart=/home/pi/myiotappfolder/myiotapp

#Optional: Saves the output and error log of the terminal to a .log file in a directory of your choosing.
StandardOutput=file:/home/pi/myiotapp.log
StandardError=file:/home/pi/myiotapp-error.log

#Optional: To cleanly end the file on stop use this command. This sends a terminal interrupt command on the executable script
KillSignal=SIGINT

#Automatically restart on kill
Restart=always

[Install]
WantedBy=multi-user.target

```

The systemmd service file which we will call `<myiotapp>.service` must be saved to `/etc/systemd/system` to be ran on boot.

Note that you must have admin priviliges to save a file to the system etc folder. You can use the following to copy the service in a terminal to this folder:

```shell
# Requires root permissions
cp <myiotapp>.service /etc/systemd/system
```

Once in the folder make the file executable by going to the directory and then use the chmod command:

```shell
# Requires root permissions
chmod +x <myiotapp>.service
```

### Notes

Please use care and refer to the manual when using this code
You may also look at the other scripts under /etc/systemd/system for reference.

## Test your service

This will start the service but will not run it on boot.

```shell
# Requires root permissions
systemctl start <myiotapp>.service
```

Now you can look at the log file you created to see the output of the terminal. `/home/pi/myiotapp.log`

Or you can check the status of the service by using in a terminal:

```shell
# Requires root permissions
systemctl is-active status <myiotapp>.service
Comment thread
joperezr marked this conversation as resolved.
Outdated
```

To stop the service run:

```shell
# Requires root permissions
systemctl stop <myiotapp>.service
```

## To make your service automatically run on boot

```shell
# Requires root permissions
systemctl daemon-reload
systemctl enable myscript.service
Comment thread
joperezr marked this conversation as resolved.
Outdated
```

## To disable your service

Run this in terminal to disable the program on boot:

```shell
# Requires root permissions
systemctl daemon-reload
systemctl disable myscript.service
```

## Security considerations

Your app will be running with root permissions.

Please ensure only root can write to the files related with your app.
That includes any binary dependencies or any other scripts which you app may run.

Not doing so may add a risk of elevation of privileges to your device.

```shell
# The commands below should be run as root (i.e. sudo)

# Owner of every dependency and app should be root
chown -R root:root /your/app/directory/

# permissions for dependencies (files) should be rw for owner, read or none for anyone else
chmod -R 644 /your/app/directory/*

# your app additionally will need executable permissions which you may have accidentally removed with previous command
chmod 755 /your/app/directory/yourapp

# permissions for directories/subdirectories
chmod 755 /your/app/directory
chmod 755 /your/app/directory/subdirectory
```
Loading
Loading