Program Examples:Shared Objects/zh-hans
语言: | English • 中文(简体) |
---|
以下示例演示如何在Linux中编译共享对象并在运行时将其与softMC进行链接。
下面有5个示例文件:C源文件,C头文件,CPP源文件,CPP头文件和makefile。
源文件和头文件实现一个简单的程序,给出2个整数作为参数,并返回其总和或差。
该程序不包括主函数,因此程序只能编译为库,而不是可执行程序。
Contents
示例程序
C 源文件: 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");
}
/*
* This function is called when module is unloaded:
* 1) at "ounload"
* 2) at "reset all"
*/
__attribute__ ((__destructor__))
void exit_func(void)
{
/*
* Make cleanup here, kill threads, release resources, etc.
*/
}
C 头文件: Example.h
void print_hello(void);
CPP 源文件: 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;
}
/*
* This function is called when module is unloaded:
* 1) at "ounload"
* 2) at "reset all"
*/
__attribute__ ((__destructor__))
void exit_func(void)
{
/*
* Make cleanup here, kill threads, release resources, etc.
*/
}
CPP头文件: CPP_Example.h
void print_hello_cpp(void);
IMPORTANT | |
在声明将从MC-Basic上下文中使用的函数名时,必须使用大写字母,如SHARED_OBJECT_SUM和SHARED_OBJECT_SUB的示例中所示。 用户函数必须用extern“C”封装,以避免CPP破坏名称 |
printf和fprintf等函数的输出字符串通常显示在Linux终端中,但在softMC的情况下,行为是不同的。
printf和cout的输出被丢弃,而fprintf和cerr的输出字符串被引导到被称为“nohup”的对象,并且稍后可被用户读取。
要显示nohup的内容,请执行以下操作:
1. 使用ssh或串口控制台连接到softMC。
2. 在Linux终端中:
-bash-3.2$ cat /var/home/mc/nohup.out .... .... Hello! This is just an example A cpp example
获取编译器
使用编译器和链接器来构建共享对象,由makefile中的CC变量定义。
您需要任何linux安装(如Ubuntu)才能运行softMC编译器。
剪切并粘贴以下命令到Linux命令行::
cd ~
wget --no-check-certificate http://servotronix.com/html/softMC_Tool_Chain/0B-jc7OYLo3AYaGFfN2ZkTUNJdHM.tar
tar -zxvf 0B-jc7OYLo3AYaGFfN2ZkTUNJdHM.tar
完整的softMC工具链将安装到您的主目录中 ~/OSELAS.Toolchain-2011.03.1
如果您正在使用64位Linux,请安装以下软件包:
sudo apt-get install libc6-i386
sudo apt-get install zlib1g:i386
Makefile
请注意,makefle CC变量分配有一个完整的gcc编译器路径。 这个特定的gcc是我们用来构建softMC的工具链的一部分。 编译要与softMC链接的共享对象时,建议使用OSELAS.Toolchain-2011.03.1工具链。
示例中的CFLAGS和CPPFLAGS变量可能会导致编译错误。但您可以删除那些妨碍编译成功的内容,但不建议这样做。更好的选择是修复编译错误
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)
为了使makefile适应您的需要,请将变量“C_SOURCE”和“CPP_SOURCE”的分配更改为项目中源文件的名称以及变量“TARGET”的赋值。
IMPORTANT | |
softMC只能处理限制为8.3约定的大写字母文件名,最多8个字符,后跟一个点,后跟扩展名PRG或LIB或O(当然在本例中为.O) 在分配TARGET变量时请记住 |
编译成功后,您将在工作目录中找到文件EXAMPLE.O,或者将任何字符串分配给变量“TARGET”。
将共享对象复制到softMC
您可以通过两种不同的方式将共享对象复制到softMC::
1. 使用scp,将文件直接复制到softMC。
在Linux终端类型中:
my_user@my_computer:~/working_directory$ scp EXAMPLE.O mc@mc.ip.add.ress:/FFS0/SSMC
其中mc.ip.add.ress是sfotMC的ip地址,例如 192.168.7.152.
or
2. 使用ControlStudio的文件管理器将文件EXAMPLE.O拖放到softMC。
将共享对象与softMC链接
共享对象现在位于softMC内。 现在我们要在运行时将softMC与共享对象链接起来,并使用它。 链接共享对象在CONFIG.PRG上下文中用'oload'命令完成。 将下行添加到您的CONFIG.PRG::
oload EXAMPLE.O
现在我们需要声明共享对象的内容以及如何使用它。 这是由PROTO.PRO文件完成的。 请将以下行添加到PROTO.PRO文件中:
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
当然,'SHARED_OBJECT_SUM'是在Example.c中实现的一个函数。 您将需要指定您自己的功能的原型。
使用ControlStudio将编辑好的CONFIG.PRG和PROTO.PRO发送到softMC并键入ControlStudio终端“reset all”。
如果进程成功,您现在可以从共享对象中调用函数。 在ControlStudio终端键入:
-->
-->
-->
-->?SHARED_OBJECT_SUM(5, 6)
11
-->
-->
-->?SHARED_OBJECT_SUB(5, 6)
-1
-->
将MC-Basic字符串传递给C函数
例如,可以将字符串对象发送到C函数进行解析。 为了做到这一点,你需要在代码中加入以下声明::
typedef int INT32;
typedef unsigned int UINT32;
typedef pthread_mutex_t* SEMM_ID;
typedef int FUNCPTR; /* ptr to func returning int */
/* defining MC Basic SYS String */
typedef struct {
INT32 type; /* string type */
INT32 scope; /* string variable scope */
INT32 temp; /* memory release flag */
INT32 alloc_size; /* number of bytes allocated */
INT32 occup_size; /* number of bytes occupied */
INT32 num_chars; /* number of characters */
UINT32 counter; /* assignment counter */
SEMM_ID mutex; /* mutex */
unsigned char* data; /* pointer to string */
FUNCPTR FuncUpdateString; /* pointer to callback function */
INT32 FuncUpdateStringParam; /* parameter of callback function */
} SYS_STRING;
在接收字符串的C函数的声明中,指定字符串参数:
int MY_C_FUNCTION(int some_var, SYS_STRING* some_str)
在将从MC-Basic到C函数的接口声明的import_c命令中,声明:
import_c MY_C_FUNCTION(byval as long, byval as string) as long
从共享对象中使用Linux sys.log
为了可以在Linux logger sys.log中记录消息,你需要在代码中加入以下声明::
/************************** 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);
/******************************************************************************************/
要发送一条消息到sys.log调用sys_log与fmt作为一个printf格式的字符串。 有关sys.log和一个例子的更全面的解释可以在Linux sys.log.中找到。
下载
提取Shared_Object.ZIP以查找上述示例
File:Shared Object.zip
该示例对应于在GIT中的提交的SHA-1: 5228016ac44122213dcb05d781b15c8e05054d5b in GIT.