Difference between revisions of "Program Examples:Shared Objects"

From SoftMC-Wiki
Jump to: navigation, search
Line 11: Line 11:
  
 
#include "Example.h"
 
#include "Example.h"
 
 
  
 
/**************************    Linux sys.log Declarations    ******************************/
 
/**************************    Linux sys.log Declarations    ******************************/
Line 205: Line 203:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
==Using Linux sys.log from Shared Object context==
 +
It is possible to log messages in the Linux logger sys.log. In order to do so you need to include in your code the following declarations:
 +
<syntaxhighlight lang="c">
 +
 +
/**************************    Linux sys.log Declarations    ******************************/
 +
 +
/* MC Modules */
 +
#define MODULE_NON 0
 +
#define MODULE_MOTION 1
 +
#define MODULE_RTS 2
 +
#define MODULE_TRANSLAT 3
 +
#define MODULE_SERCOS 4
 +
#define MODULE_ROBOT 5
 +
#define MODULE_TRACER 6
 +
#define MODULE_SYSTEM 7
 +
#define MODULE_MEMORY 8
 +
#define MODULE_FILE_SYSTEM 9
 +
#define MODULE_CLI 10
 +
#define MODULE_RBOOTP 11
 +
#define MODULE_ETHERCAT 12
 +
#define MODULE_FASTDATA 13
 +
#define MODULE_UAC 14
 +
#define MODULE_MC_BASIC 15
 +
#define MODULE_CANOPEN 16
 +
 +
 +
/* MC Log Level */
 +
#define LOG_LEVEL_NON 0
 +
#define LOG_LEVEL_ERROR 1
 +
#define LOG_LEVEL_WARNING 2
 +
#define LOG_LEVEL_NOTE 3
 +
#define LOG_LEVEL_DEBUG 4
 +
#define LOG_LEVEL_ALL 5
 +
 +
extern int sys_log(int sub_system, int _debug_level, const char * fmt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10);
 +
 +
/******************************************************************************************/
 +
</syntaxhighlight>
 +
 +
Another example can be found in [[Program_Examples:sys_log|Linux sys.log]].
  
 
The example corresponds to commit SHA-1: 14db936d64092d07d22663912172b404c3489bd8 in GIT.
 
The example corresponds to commit SHA-1: 14db936d64092d07d22663912172b404c3489bd8 in GIT.
Line 210: Line 248:
 
== See Also ==
 
== See Also ==
 
* [[MC-Basic:IMPORT_C|IMPORT_C]]
 
* [[MC-Basic:IMPORT_C|IMPORT_C]]
 +
* [[Program_Examples:sys_log|Linux sys.log]]

Revision as of 12:06, 31 December 2014

The following example demonstrates how to compile a shared object in Linux and link it with softMC at run-time.

Below there are 5 example files: A C source file, a C header file, a CPP source file, a CPP header file and a makefile.
The source and header files implement a simple program that is given 2 integers as arguments and returns their sum or difference.
This program DOESN'T include a main function, therefore the program can be compiled only into a library, and not an executable.

Example Program

C Source file: Example.c

#include <stdio.h>

#include "Example.h"

/**************************    Linux sys.log Declarations    ******************************/

/* MC Modules */
#define MODULE_NON	 	 0
#define MODULE_MOTION		 1
#define MODULE_RTS		 2
#define MODULE_TRANSLAT		 3
#define MODULE_SERCOS		 4
#define MODULE_ROBOT		 5
#define MODULE_TRACER		 6
#define MODULE_SYSTEM		 7
#define MODULE_MEMORY		 8
#define MODULE_FILE_SYSTEM	 9
#define MODULE_CLI		10
#define MODULE_RBOOTP		11
#define MODULE_ETHERCAT		12
#define MODULE_FASTDATA		13
#define MODULE_UAC		14
#define MODULE_MC_BASIC		15
#define MODULE_CANOPEN		16


/* MC Log Level */
#define LOG_LEVEL_NON		0
#define LOG_LEVEL_ERROR		1
#define LOG_LEVEL_WARNING	2
#define LOG_LEVEL_NOTE		3
#define LOG_LEVEL_DEBUG		4
#define LOG_LEVEL_ALL		5

extern int sys_log(int sub_system, int _debug_level, const char * fmt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10);

/******************************************************************************************/



int SHARED_OBJECT_SUM(int arg1, int arg2)
{
	sys_log(MODULE_NON, LOG_LEVEL_ERROR, "%s: arg1 = %d, arg2 = %d\n", (int)__FUNCTION__, arg1, arg2, 0,0,0,0,0,0,0);
	print_hello();

	return arg1 + arg2;
}

void print_hello(void)
{
	fprintf(stderr, "Hello! This is just an example\n");
}

C Header file: Example.h

void print_hello(void);

CPP Source file: CPP_Example.c

#include <iostream>

#include "CPP_Example.h"

extern "C" {

int SHARED_OBJECT_SUB(int arg1, int arg2)
{
	print_hello_cpp();

	return arg1 - arg2;
}

} // extern "C" {

void print_hello_cpp(void)
{
	std::cerr << "A cpp example" << std::endl;
}

CPP Header file: CPP_Example.h

void print_hello_cpp(void);
IMPORTANT.svgIMPORTANT
When declaring function names that will be used from MC-Basic context you must use UPPERCASE letters, as in the example of SHARED_OBJECT_SUM and SHARED_OBJECT_SUB.
User functions must be wrapped with extern "C" to avoid CPP mangled names


Output strings of functions like printf and fprintf are usually displayed in the Linux terminal, however in the softMC case the behavior is different.
The outputs of printf and cout are discarded while output strings of fprintf and cerr are directed to an object called 'nohup' and can later be read by the user.
To display the contents of nohup do the following:

1. Connect to the softMC using ssh or serial console.
2. In the Linux terminal type:

-bash-3.2$ cat /var/home/mc/nohup.out
....
....
Hello! This is just an example
A cpp example


Makefile

The compiler to be used in order to build the shared object is defined by the CC variable in the makefile. Please notice that it is assigned with a complete path to gcc compiler. This specific gcc is a part of the tool chain we use to build softMC.

When compiling shared objects to be linked with softMC it is advised to use this tool chain.
You can download it from:
--- LINK ...
If you copy the tool chain to your user's directory, /home/my_user, you don't have to change the CC variable assignment in the makefile.

The CFLAGS and CPPFLAGS variables in the example might cause compilation errors. It is not advised, but you can remove those that prevent a successful compilation. The better option is to fix the compilation errors.

The makefile syntax:

CC=~/OSELAS.Toolchain-2011.03.1/i586-unknown-linux-gnu/gcc-4.5.2-glibc-2.13-binutils-2.21-kernel-2.6.36-sanitized/bin/i586-unknown-linux-gnu-gcc
CXX=~/OSELAS.Toolchain-2011.03.1/i586-unknown-linux-gnu/gcc-4.5.2-glibc-2.13-binutils-2.21-kernel-2.6.36-sanitized/bin/i586-unknown-linux-gnu-g++
CFLAGS=-c -g -ansi -pedantic -Wall -Werror
CPPFLAGS=-c -g -ansi -pedantic -Wall -Werror

LD_LIBRARY_PATH := .:$(LD_LIBRARY_PATH)

C_SOURCE=Example.c
CPP_SOURCE=CPP_Example.cpp

C_OBJECTS=$(C_SOURCE:.c=.o)
CPP_OBJECTS=$(CPP_SOURCE:.cpp=.o)

TARGET=EXAMPLE.O

$(TARGET): $(C_OBJECTS) $(CPP_OBJECTS)
	$(CC) -shared -o $@ $(C_OBJECTS) $(CPP_OBJECTS)

$(C_OBJECTS): $(C_SOURCE)
	$(CC) $(CFLAGS) -c $(C_SOURCE)

$(CPP_OBJECTS): $(CPP_SOURCE)
	$(CXX) $(CPPFLAGS) -c $(CPP_SOURCE)

clean:
	rm $(C_OBJECTS) $(CPP_OBJECTS) $(TARGET)

In order to adapt the makefile to your needs, please change the assignment of the variables 'C_SOURCE' and 'CPP_SOURCE' to the name of the source files in your project, and the assignment of the variable 'TARGET'.

IMPORTANT.svgIMPORTANT
softMC can handle only UPPERCASE file names limited to 8.3 convention, meaning, up to 8 characters, followed by a dot, followed by the extensions PRG, or LIB or O (of course in our case it will be .O)
Bear that in mind when assigning the TARGET variable

After a successful compilation you will find in the working directory the file EXAMPLE.O, or whatever string was assigned to the variable 'TARGET'.

copy the shared object to softMC

You can copy the shared object to softMC in 2 different ways:
1. Using scp, copy the file directly to softMC.
In the Linux terminal type:

my_user@my_computer:~/working_directory$ scp EXAMPLE.O mc@mc.ip.add.ress:/FFS0/SSMC

Where mc.ip.add.ress is the sfotMC's ip address, for example, 192.168.7.152.
or
2. Use the ControlStudio's file manager to drag and drop the file EXAMPLE.O to the softMC.

Link the shared object with softMC

The shared object now resides within softMC. Now we want to link softMC with the shared object during run-time, and use it. Linking the shared object is done with 'Load' command in CONFIG.PRG context. Please add to your CONFIG.PRG the line:

oload EXAMPLE.O

Now we need to declare about the shared object's contents and how to use it. This is done by the PROTO.PRO file. please add the following lines to your PROTO.PRO file:

import_c SHARED_OBJECT_SUM(byval as long, byval as long) as long
import_c SHARED_OBJECT_SUB(byval as long, byval as long) as long

Of course, 'SHARED_OBJECT_SUM' is a function implemented in Example.c. You will need to specify the prototypes of your own functions.
Using ControlStudio send the edited CONFIG.PRG and PROTO.PRO to softMC and type in the ControlStudio terminal 'reset all'.

If the process was successful, you are now able to invoke functions from the shared object. Type in the ControlStudio terminal:

-->
-->
-->
-->?SHARED_OBJECT_SUM(5, 6)
11
-->
-->
-->?SHARED_OBJECT_SUB(5, 6)
-1
-->

Using Linux sys.log from Shared Object context

It is possible to log messages in the Linux logger sys.log. In order to do so you need to include in your code the following declarations:

/**************************    Linux sys.log Declarations    ******************************/

/* MC Modules */
#define MODULE_NON	 	 0
#define MODULE_MOTION		 1
#define MODULE_RTS		 2
#define MODULE_TRANSLAT		 3
#define MODULE_SERCOS		 4
#define MODULE_ROBOT		 5
#define MODULE_TRACER		 6
#define MODULE_SYSTEM		 7
#define MODULE_MEMORY		 8
#define MODULE_FILE_SYSTEM	 9
#define MODULE_CLI		10
#define MODULE_RBOOTP		11
#define MODULE_ETHERCAT		12
#define MODULE_FASTDATA		13
#define MODULE_UAC		14
#define MODULE_MC_BASIC		15
#define MODULE_CANOPEN		16


/* MC Log Level */
#define LOG_LEVEL_NON		0
#define LOG_LEVEL_ERROR		1
#define LOG_LEVEL_WARNING	2
#define LOG_LEVEL_NOTE		3
#define LOG_LEVEL_DEBUG		4
#define LOG_LEVEL_ALL		5

extern int sys_log(int sub_system, int _debug_level, const char * fmt, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10);

/******************************************************************************************/

Another example can be found in Linux sys.log.

The example corresponds to commit SHA-1: 14db936d64092d07d22663912172b404c3489bd8 in GIT.

See Also