Program SlimLine Raspberry in "C"

The module SlimLine Raspberry in addition to programming according to the regulations IEC61131 in PLC style, in the environment LogicLab o CODESYS, it can be programmed in "C" and / or "C ++" language, thus being able to access the enormous amount of software available on the Internet. For those who use the environment LogicLab and wants to add new functions and FBs written in "C" and / or "C ++" language can read this article. Any compiler can be used for application development, in this article we will use the well-known IDE Codelite.

Toolchain installation

To be able to compile executable programs on Raspberry need to download the toolchain cross-compilation of Raspbian da GitHub, unpack the file into an example system folder /home/elsist/dev. Now add the folder to the PATH system, editing the file etc/profile inserting at the bottom the link to the toolchain in the folder to which it was transferred, hereinafter the link for the systems to 32 bits on the upper line and 64 bits on the lower line.

export PATH=/home/elsist/dev/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH
export PATH=/home/elsist/dev/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH

After modifying the file to make it active, it is necessary to execute the command from a terminal source /etc/profile, you can verify that the PATH is active with the command printenv. If everything is correct you can compile a simple program HelloWorld and run it. Create a file with a text editor main.c with the following content:

#include <stdio.h>
int main()
{
    printf("Hello World!\r\n");
    return 0;
}

Compile the program with the command arm-linux-gnueabihf-gcc main.c -g -o hello, the executable file will be created hello that transferred to the Raspberry can be executed. Even if we now have everything we need to compile a program it is preferable to rely on an IDE that allows to manage the development of complex applications in a simpler way, in the following we will use Codelite.

IDE installation

Codelite is a free open source IDE available for Windows, Linux and MacOS to work with the C language, the program can be downloaded from Official site. I omit all the installation instructions which in addition to being very simple are available on an infinite number of guides available on the Internet. Although the program is available for Windows, I recommend installing it on a Linux machine as having to develop applications for Raspberry you already have all the basic libraries available.

Now create a new Workspace to add a new project to, in the project set the Raspberry toolchain compiler, right click on the project name, choose Settings->General->Compiler and set Cross GCC (arm-linux-gnueabihf). Now compile the project and in the folder Debug o Release the project will generate the executable file. that transferred to the Raspberry module it will be possible to execute it. A demonstration program is provided for download PTP168 with some projects Codelite already ready.

CodeLite Screenshot

Transfer program to Raspberry

The build command compiles the program that is saved in the folder Debug o Release (Based on build selection) created within the project folder. Now using an SFTP you need to transfer it to the Raspberry module for execution. There are many graphical SFTP clients suitable for this purpose, the best known is Filezilla, but it is more convenient to simply act from a terminal window using the command scp combining it with the command sshpass (If the command sshpass it is not present, it must be installed).

In order to access the system you need to acquire the SHA256 authentication key, then execute the command from a terminal window ssh <Username>@<Host> (Example ssh [email protected]) and confirm with yes. The access password will be requested and the key will be added to the known hosts (File /home/user.ssh/known_hosts). If the host system is replaced, the key must be deleted with the command ssh-keygen -R <Host> and generate a new key.

Now assuming that the executable file HelloWorld compiled both in the folder /home/HelloWorld/Release that the Raspberry module has credentials pi:raspberry and IP address 192.168.0.180, wanting to transfer the executable to the folder /home/pi you need to use the command sshpass followed by the login password

sshpass -p 'raspberry' scp /home/HelloWorld/HelloWorld/Release/HelloWorld [email protected]:/home/pi

Codelite can automatically execute the command at the end of the compilation scp transferring the file to the module Raspberry, to set it you need to right click on the project name, choose menu Settings->Pre/Post Build Commands->Post Build and enter the command line defined above. In the projects present in the demonstration, you need to modify the post build command to transfer the program to your Raspberry module.

"HelloWorld" project

This project prints the classic message Hello World! on the console.

HelloWorld (Ptp168)
// #include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello world\n");
    return 0;
}

// [End of file]

"CPhrAccess" project

The program activates the watchdog (See article) and manages a digital I / O extension module connected to the bus. The library is provided for the development of applications that access the system hardware and extension modules libeS8CoreMng. To include the library in the project right click on the project name in the menu Settings->Compiler->Include Paths define the folder "./Lib/eS8CoreMng/Include”Where the library is located. The library uses threads management so in order to compile the project you need to right click on the project name in the menu Settings->Linker->Linker Options the parameters -pthread -lrt.

CPhrAccess (Ptp168)
// *****************************************************************************
// PROGRAM "CPhrAccess"
// *****************************************************************************
// A simple programs that shows how to access to peripheral modules attached to
// the SlimLine extension BUS.
// -----------------------------------------------------------------------------

#include <stdio.h>
#include <PhrFcts.h>
#include <Library.h>
#include <WatchDog.h>
#include <PhrI2cBus.h>
#include <SystemTime.h>
#include <LastError.h>
using namespace Elsist; //Defines namespace

// -----------------------------------------------------------------------------
// MAIN PROGRAM
// -----------------------------------------------------------------------------

int main(int argc, char **argv)
{
    // Define variables.
    
    int8_t Result; //Function result
    uint8_t PModules; //Peripheral modules
    uint32_t DInputs; //Digital inputs
    static uint32_t DOutputs; //Digital outputs
    static uint32_t TimeBf; //Time buffer (uS)

    // -------------------------------------------------------------------------
    // SYSTEM INITIALIZATION
    // -------------------------------------------------------------------------
    // A welcome message is displayed.

    printf("Elsist PTP168A000, CPhrAccess, Library:%s\n", eGetLibVersion());

    // Initialize the library, this must be done before use any function.
    // Function returns 0 if Ok or the error code.

    if ((Result=eLibInit()) != 0) {printf("eLibInit error %d\n", Result); return(0);}

    // Defines wich I2C device has been to used to manage the extension bus,
    // and initializes it. Function returns 0 if Ok or the error code.
    
    Result=ePhrI2cBusInit((char_t*)"/dev/i2c-4");
    switch(Result)
    {
        // Error on bus initializing there's some hardware problem.

        case -1: printf("Bus init error: %d\n", Result); return(0);
        
        // System has been restarted by a watchdog intervention.
        // "Result" returns the number of subsequent watchdog interventions.

        default:
        if (Result == 0) printf("System power up\n");
        if (Result != 0) printf("System has been rebooted for %d times\n", Result);
        
        // After a defined number of system reboots by watchdog interventions,
        // a decision must be taken. In this example the program is stopped.
        
        if (Result > 2)
        {
            printf("Too wdog reboot\n");
            eResetWDog(); //Watchdog reset, it reinits the reboot counter
            return(0);
        }
    }

    // Set the peripheral bus ready, this activates all the attached modules.
    // Set also the wdog timeout to 2 seconds. Time range (1 to 60000 mS).
    
    while (!ePhrI2cBusReady(true, 2000)); //Set ready signal on peripheral bus

    // -------------------------------------------------------------------------
    // PROGRAM LOOP
    // -------------------------------------------------------------------------
    // This is the main program loop, here all the program tasks has to be done
    // in this example the 8 digital outputs of an extension module are managed.

    while(true)
    {
        // The watchdog control has been set so it must be refreshed. If it's
        // not refreshed in the time set the system is rebooted.

        eWDogRefresh(); //Refresh the watchdog circuit

        // Read how many modules are attached to the bus, if no modules ends.

        PModules=eGetModulesOnPhrI2cBus(); //Peripheral modules
        if (PModules == 0) return(0);

        // Supposing to have a logic I/O module (With address 0) attached to the bus
        // are reading the inputs and managed the outputs.

        if (!eIsPhrI2cBusExtModuleAv(0)) return(0); //Exit if module not present
        if (!eGetPhrDI(0, DI_MODE::DI_8_LL, &DInputs))
            {printf("eGetPhrDi error: %u\n", eGetLastError()); return(0);}

        // Copy Di00 input status on Do00 output.

        if (DInputs&eBITPATTERN(0)) eBITSET(DOutputs, 0); else eBITRESET(DOutputs, 0);

        // Blink the Do01 outputs.

        if (TimeBf == 0) TimeBf=eGetSysTime(); //Initialize the reference time
        if ((eGetSysTime()-TimeBf) > eSEC(1))
        {
            TimeBf=eGetSysTime(); //Time buffer (uS)
            if (DOutputs&eBITPATTERN(1)) eBITRESET(DOutputs, 1); else eBITSET(DOutputs, 1);
        }

        // Transfer the value on the extension module digital outputs.

        if (!eSetPhrDO(0, DO_MODE::DO_8_LL, &DOutputs))
            {printf("eSetPhrDO error: %u\n", eGetLastError()); return(0);}
    }
}

// [End of file]
Was this article helpful?