PLCnext on Instagram  PLCnext on YouTube Github PLCnext CommunityStore PLCnext Community

 

 How to create a Blog Entry

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

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.csproj

    VS Code pushes the application to the default path:

     {Workspace}bin/Release/netcoreapp3.0/linux-arm/publish

    In 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 target.

    cd ~/fromScratch/bin/Release/netcoreapp3.0/linux-arm/publish
    scp fromScratch   This email address is being protected from spambots. You need JavaScript enabled to view it.:/opt/plcnext/apps
    scp fromScratch.pdb  This email address is being protected from spambots. You need JavaScript enabled to view it.:/opt/plcnext/apps

    Login and start the application on the device.

    ssh This email address is being protected from spambots. You need JavaScript enabled to view it.
    ~/apps/./fromScratch

    The 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)
    ...
    Aborted

    We 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/./fromScratch

    Our 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.

Comments  

# mboers 2020-01-17 19:43
Excellent post, thank you!