Makers Blog

Getting started with C# and .Net Core 3.0 on PLCnext

Kay Suttkus 17 January 2020 min. read
961 views 0 comments

The following post shows a workflow how to develop a .Net Core application for a PLCnext target.
It is containing two steps:

  1. Create a Hello World application with VS Code.
  2. Publish the application to the controller.

In this example I’m using Debian 9 on my development machine and an AXC F 2152 with version: PLCnext Linux 2019.9.

Create a C# Hello World application with VS Code

To begin we start with creating a new .Net Core console application.

The very first steps are to install VS Code and add C# extensions like C# for VS Code and IntelliCode.They are well documented, please check the links below:
VS Code Getting started
VS Code Working with C#

Also note the Makers Blog article by Björn Sauer Install the .NET Core runtime 3.0.0 on the AXC F 2152 to setup the environment on the controller.

First we create a directory, which we are using as workspace. Enter to this folder and start VS Code.

cd ~
mkdir fromScratch
cd fromScratch
code .

Than follow the steps in Get started with C# and Visual Studio Code until to Add a class. We don’t need any classes in our example.

At last you should see this in your VS Code:

Now we make some changes in the main method to keep the application running and to have some possibilities to have user inputs.

using System;

namespace fromScratch
    class Program
        static void Main(string[] args)
            Console.WriteLine("Hello World!");
            string foo = String.Empty;
            while (foo != "y")
                Console.WriteLine("Enter (y) to close the app.");
                foo= Console.ReadLine();

We have to change the console settings in the launch.json to debug our program:

 "console": "externalTerminal"

As default VS Code uses the internal console. It works as read only and can’t handle Console.ReadLine().

Finally the result should look like this:

Publish the application to the controller

After we finished the coding we could move forward to publish our code to the target. There are many different ways and options to publish .Net Core applications. I prefer the way to publish an app as self contained and trimmed. The main reason is the limited memory space on the PLCnext target.

  1. We must modify the fromScratch.csproj to define a single file application. If we change the project to single file application it is necessary to set the runtime identifier to the development machine. Add the following properties to the .csproj file:<PublishSingleFile>true</PublishSingleFile> <RuntimeIdentifier>linux-x64</RuntimeIdentifier> See also: .Net Core RID Catalog
  2. Open a new Terminal in VS Code and publish the application.dotnet publish -c Release -r linux-arm fromScratch.csprojVS Code pushes the application to the default path: {Workspace}bin/Release/netcoreapp3.0/linux-arm/publishIn the publish folder are two files. These files are all you need to execute the application on a Linux Arm target. The size of the file is 78.3 MB which is quite big.There is another option available to minimize the size.
  3. We have to modify the fromScratch.csproj again to trim the final binary. Add the PublishTrimmed property to the .csproj file:<PublishTrimmed>true</PublishTrimmed>The final project file should look like this after adding the properties:<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.0</TargetFramework> <PublishSingleFile>true</PublishSingleFile> <RuntimeIdentifier>linux-x64</RuntimeIdentifier> <PublishTrimmed>true</PublishTrimmed> </PropertyGroup> </Project>Now the binary has a size of 30.9 MB and is ready to use on the PLCnext.
  4. The last step is copying the application to the target and try to launch it. We open the publish folder and copy the files on the ~/fromScratch/bin/Release/netcoreapp3.0/linux-arm/publish scp fromScratch admin@ scp fromScratch.pdb admin@ and start the application on the device.ssh admin@ ~/apps/./fromScratchThe result is a exception from the Globalization, which reminds us to enable the Globalization.Invariant flag.Process terminated. Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support. at System.Environment.FailFast(System.String) ... AbortedWe could enable this parameter and try to launch again:
    (By the way thanks to Andreas Orzelski and his post in the Makers Blog.)export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true ~/apps/./fromScratchOur fromScratch should start and comes up with:The Globalization exception can be avoided by including the flag into the project file:<ItemGroup> <RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true"/> </ItemGroup>Now we can publish the project again and the application will start as expected.


The Makers Blog shows applications and user stories of community members that are not tested or reviewed by Phoenix Contact. Use them at your own risk.


Please login/register to comment


Leave a Reply

Never miss a new article
Sign up for the newsletter
Never miss news about PLCnext Technology
Get interesting content via newsletter four times a year
Receive exclusive information before all other users