HomeDownloadDocumentationTutorials
 

HowTo: Create an Example using Linux and GCC

1. Introduction

The way described here, needs a Windows installation for running the configuration tool and shared directories between Windows and Linux. This method is deprecated, as the new configuration tool natively runs on Linux now.

2. Download and Install the Apparatus Framework

Download the framework from this web page and install it by running the MSI under Windows. Please choose the tool installation path APFW_CFG_TOOL_LOC during the installation procedure. Create the EXAMPLE_PATH after the MSI has finished manually as listed in the following table. Of course you can choose your own locations, if you like. The installation is step by step documented in the (Documentation - Installation) section of this page.

Examples of locations:

APFW_CFG_TOOL_LOC C:\Program Files\bbv Software Services
EXAMPLE_PATH C:\Documents and Settings\USER\My Documents\ApFw

3. Share and Substitute the Needed Folders

For compiling under Linux we need to share and substitute two folders. Choose two free drive letters e.g. T:\ and U:\.

Folders to share and substitute under Windows:

APFW_CFG_TOOL_LOC\Apparatus Framework T:\ APFW_SHARE
EXAMPLE_PATH U:\ EXAMPLE_SHARE

Note

For folder sharing do a right-click on the corresponding folder and chose (Properties - Sharing). Fill e.g. U into (Share name:). Under (Permissions) add your domain account or everyone with {Full Control} access rights. Keep in mind you have to do this twice. Make sure the Windows firewall doesn’t prevent file sharing.

For substitution start the DOS-Shell and type e.g.:

subst U: "C:\Documents and Settings\USER\My Documents\ApFw"
subst T: "C:\Program Files\bbv Software Services\Apparatus Framework".

For substitution at system startup you can add those two entries to a batch file and add it to the start menu of Windows (All Programs - Startup).

4. Create a Linux Example

Open the ApFw configuration tool in the start menu of Windows (Programs - bbv Apparatus Framework - Configuration Tool). Make sure (Build - Repository) points to APFW_SHARE\Source\Repository. Use the Linux template for a new project. For doing that, go to (Build - Templates...) and choose {Apparatus Framework for Linux} under (Hardware) and press (OK). Now you can do modifications in the configuration tree. Tick e.g. {Apparatus Framework – Examples for the Apparatus Framework – Roulette example} in the config tool. Saving the project under EXAMPLE_SHARE\EXAMPLE_PRJ.acc will not only generate and copy the necessary make and header files for compiling under Linux, but also create the sub directories EXAMPLE_PRJ_build and EXAMPLE_PRJ_install.

Note

The files under EXAMPLE_SHARE\EXAMPLE_PRJ_install\include\pkgconf will be deleted by (Build - Clean) in the ApFw configuration tool or the 'make clean' command in a Linux shell! For generating them again, press (File - Save) in the configuration tool (under Windows) again. Probably you have to deselect and re-select a tick e.g. {Examples for the Apparatus Framework}.

5. Compiling the Apparatus Framework Library under Linux

Now it comes to the point, where we mount our created shares under Linux. For doing that, start a root shell and type the following commands.
Create two new mount points by creating directories:

mkdir /U
mkdir /T

Mount the drives:

mount -t cifs -o domain=DOMAIN -o username=ACCOUNT //WINDOWS_HOST/t /T
mount -t cifs -o domain=DOMAIN -o username=ACCOUNT //WINDOWS_HOST/u /U

Note

For better understanding the paths APFW_SHARE and EXAMPLE_SHARE are written directly with the share drive letters T and U in the command lines above, as they have to be executed. If you have chosen different letters, please adjust them as necessary. If you do mistakes, you could un-mount a drive by typing 'umount' in combination with the appropriate mount point.

Change now to the directory for building the project:

cd /U/EXAMPLE_PRJ_build

In here we call 'make' for building the project.

Open a second shell and go to the directory /U/EXAMPLE_PRJ_install/bin. If everything has worked fine, you will find the test programs PingPong.exe and Roulette.exe. You can execute these programs now.

./PingPong.exe
./Roulette.exe

Now you are ready to create your own project using Apparatus Framework functionality.

6. Create your own Project

Create the following files in the same directory as the EXAMPLE_PRJ.acc is located.

test.cpp

        #include "ApparatusFramework/KernelServices/Kernel.h"
        #include "ApparatusFramework/KernelServices/Task.h"
        #include "ApparatusFramework/DiagnosticServices/Logger.h"
        
        #include "PingPongTask.h"
        #include "PingPongMsg.h"
        
        
        int main()
        {
          Logger::Create();
          Kernel::Create(10);
        
        
          Logger::Default()->printLogText("PingPongMain Start\n");
          Kernel::Default()->startKernel();
         
          // Create Tasks
          PingPongTask task1(task1Id, task1Priority, taskName1);
          PingPongTask task2(task2Id, task2Priority, taskName2);
          
          // Start Tasks (Please start all the tasks after you have constructed them.)
          task1.startTask();
          task2.startTask();
        
          Msg* pMsg = new PingPongMsg;
          pMsg->m_msgId = 0;
          Task::sendMsgToTask(&task1, pMsg);
          for (;;) 
          {
            Kernel::Default()->delayFor(1000);
          }
        } 

PingPongTask.h

        #ifndef PING_PONG_TASK_H
        #define PING_PONG_TASK_H
        
        #include "ApparatusFramework/KernelServices/Kernel.h"
        #include "ApparatusFramework/KernelServices/Task.h"
        
        
        const TaskId task1Id = 11;
        const TaskPriority task1Priority = 11;
        const char taskName1[] = "task1";
        
        const TaskId task2Id = 12;
        const TaskPriority task2Priority = 12;
        const char taskName2[] = "task2";
        
        
        class PingPongTask : public Task 
        {
          public:
            PingPongTask(const TaskId taskId, const TaskPriority taskPriority, const char taskName[]);
            virtual void runBody();
        
          private:
            static int msgCounter;
        };
        
        
        #endif //#define PING_PONG_TASK_H  

PingPongTask.cpp

        #include "ApparatusFramework/KernelServices/Task.h"
        #include "ApparatusFramework/DiagnosticServices/Logger.h"
        #include "ApparatusFramework/KernelServices/apfw_assert.h"
        #include "PingPongTask.h"
        #include "PingPongMsg.h"
        
        
        int PingPongTask::msgCounter=0;
        
        
        PingPongTask::PingPongTask(const TaskId taskId, const TaskPriority taskPriority, const char taskName[]) : 
          Task(taskId, taskPriority, 0, 10, taskName)
        {
        }
        
        
        void PingPongTask::runBody()
        {
          int id=taskId();
          Task* task;
          if(id==task1Id)
              task=Kernel::Default()->getTaskWithId(task2Id);
          else
                task=Kernel::Default()->getTaskWithId(task1Id);
          Msg* pMsg;
          for(;;)
          {
            pMsg = waitMsg();
            APFW_ASSERT(pMsg!=0);
            pMsg->Release(pMsg);
            Logger::Default()->printLogText("PingPong: Task nr. %d receive message nr. %d \n",id,msgCounter);
            delayFor(100);
            pMsg = new PingPongMsg;
            pMsg->m_msgId = ++msgCounter;
            sendMsg(task, pMsg);
          }
        }      

PingPongMsg.h

        #ifndef PING_PONG_H
        #define PING_PONG_H
        
        #include "ApparatusFramework/KernelServices/Msg.h"
        
        class PingPongMsg : public Msg 
        {
        public:
          Msg* clone(){return new PingPongMsg(*this);};
          void dump() const {Logger::Default()->printLogText("<PingPongMsg>\n");};
        };
        
        #endif //PING_PONG_H      

makefile

        CC=g++
        CFLAGS=-I./Linux_install/include -c -Wall
        LDFLAGS=-L./Linux_install/lib
        SOURCES=test.cpp PingPongTask.cpp
        OBJECTS=$(SOURCES:.cpp=.o)
        LIBS=-lApFw -lpthread
        EXECUTABLE=test

        all: $(SOURCES) $(EXECUTABLE)
  
        $(EXECUTABLE): $(OBJECTS) 
            $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBS)

        .cpp.o:
            $(CC) $(CFLAGS) $< -o $@

        clean:
            rm -rf *o test      

7. Compile the Test Project

Go to /U and type 'make' for building the test project. After compiling you can execute the binary by typing

./test

Have fun!