first commit
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
##############################################################################
|
||||
# Copyright: Copyright CODESYS Development GmbH
|
||||
# Program: Extension API for the Linux SL products
|
||||
##############################################################################
|
||||
|
||||
##########################
|
||||
This is the SDK of the Linux SL products to create an own additional CODESYS runtime component
|
||||
whose functions that can be called from a CODESYS IEC library.
|
||||
##########################
|
||||
|
||||
##########################
|
||||
Prerequisites:
|
||||
- A CODESYS Installation to create an IEC library on a windows machine
|
||||
- Some buildtools to create a shared object (linux dynamic library), that can be run with the CODESYS Control SL runtimes
|
||||
- some kind of GCC (for X64 / ARM / AARCH64, depending on your target system)
|
||||
- make
|
||||
- m4
|
||||
- sed
|
||||
- dos2unix
|
||||
##########################
|
||||
|
||||
##########################
|
||||
If you want to start a new project, follow these steps:
|
||||
|
||||
On the linux system (where you want to build the component)
|
||||
1) Install the required tools (see prerequisites), e.g. with
|
||||
sudo apt-get install build-essential m4 sed dos2unix make
|
||||
|
||||
2) Copy the SDK to a place of your choice, e.g. in your home directory.
|
||||
Later we call this directory the "<SDKDIR>", so please remember this location!
|
||||
Hint: As we are using the tool "make": dont use paths with whitespaces. Make does not like that at all!
|
||||
|
||||
3) Create a folder next to the sdk where you want to start your project, e.g. "CmpFirstTest"
|
||||
mkdir ~/CmpFirstTest
|
||||
Later we call this directory the "<PROJECT DIR>", so please remember this location!
|
||||
|
||||
4) Now create a new project with the following command, and use the makefile from the <SDKDIR>:
|
||||
make -f <SDKDIR>/makefile newproject
|
||||
e.g.:
|
||||
make -f ../sdk/makefile newproject
|
||||
This creates a makefile within your folder, you might want to take a look at it later ;-)
|
||||
Your workspace now might look like this:
|
||||
|
|
||||
|- SKD <SDKDIR>
|
||||
| |- include (dir)
|
||||
| |- m4 (dir)
|
||||
| |- src (dir)
|
||||
| |- makefile
|
||||
| |- makefile_template
|
||||
| |- README
|
||||
|
|
||||
|- CmpFirstTest <PROJECT DIR>
|
||||
|- makefile
|
||||
|
||||
|
||||
5) Now take a look at the generated makefile.
|
||||
If you are compiling for X64, you dont need to change anything
|
||||
If you are compiling for another architecture, you need to set a proper cross compiler via the variable CC (and probably more CFLAGS, INCLUDES and LDLIBS)
|
||||
|
||||
|
||||
On the Windows system (where CODESYS is installed)
|
||||
1) Open your CODESYS IDE and create a new library unsing the "Empty library" template (do not use the "External CODESYS library" template).
|
||||
Set the title in the project information to e.g.: "CmpFirstTest"
|
||||
and store it under the same filename, e.g. "CmpFirstTest.library".
|
||||
These two must match, otherwise it wont be possible to generate the shared object!
|
||||
|
||||
2) Add "externally linked" functions to your library as you wish. You can make a Function "externally linked" by right clicking
|
||||
on the new function ->Properties->Build and select "External implementation".
|
||||
This function must include "_cext" in its name, otherwise it wont be loaded by the runtime!
|
||||
E.g.: TestFunction_cext
|
||||
|
||||
3) Now create the runtime system files by selecting Build->"Generate runtime system files".
|
||||
Choose a suitable path as output directory.
|
||||
Enable the checkboxes for "M4 interface file" and "C stub file" as you need to generate both: C and M4 files.
|
||||
Also check that the component name is equal to the name of your library, e.g. "CmpFirstTest"
|
||||
|
||||
4) Save or transfer these generated files (*.c and *Itf.m4 file) to the <PROJECT DIR> on your linux system
|
||||
|
||||
|
||||
On the linux system (at <PROJECT DIR>)
|
||||
1) Go to your <PROJECT DIR> and try to build your component with
|
||||
make all
|
||||
|
||||
2) Now a shared object, with the same name as your IEC library should have been generated in the "out" folder
|
||||
|
||||
3) Now you can transfer, copy or symbolically link that to a location on your target system where libraries are normally found (e.g. /usr/lib )
|
||||
e.g. if you are on the target system:
|
||||
sudo cp out/libCmpFirstTest.so /usr/lib
|
||||
|
||||
4) Stop the runtime on your target e.g. with
|
||||
sudo /etc/init.d/codesyscontrol stop
|
||||
|
||||
5) Open the configuration file CODESYSControl_User.cfg of the runtime, e.g. with nano
|
||||
and add an entry at the section [ComponentManager], where the components are listed:
|
||||
[ComponentManager]
|
||||
Component.1=CmpFirstTest
|
||||
Component.2=CmpSomeOtherComponent
|
||||
Component.3=CmpSomeMoreComponent
|
||||
...
|
||||
|
||||
hints:
|
||||
- the number or index in this setting needs to be incrementing, it might not collide with already existing settings/component indices
|
||||
- if the line starts with ; it is a comment and the setting is not active
|
||||
|
||||
6) Then restart your runtime again, e.g. with
|
||||
sudo /etc/init.d/codesyscontrol start
|
||||
|
||||
7) and check that your component is properly loaded, e.g. check the logfile (via CODESYS IDE), or under codesyscontrol.log
|
||||
cat /var/opt/codesys/codesyscontrol.log
|
||||
you should see a message like this:
|
||||
... Dynamic: <cmp>CmpFirstTest</cmp>, <id>0xffff2000</id> <ver>1.0.0.0</ver>
|
||||
|
||||
-> Congratulations! you made your first component and it runs from the CODESYS Control runtime
|
||||
-> if not: check the FAQs section at the end of this file
|
||||
|
||||
|
||||
On the Windows system (where CODESYS is installed)
|
||||
1) go to the CODESYS project where you want to use your newly created IEC library, and use your library
|
||||
|
||||
2) make a download and check if your code is called (e.g. make a printf there)
|
||||
|
||||
##########################
|
||||
|
||||
|
||||
|
||||
##########################
|
||||
FAQs:
|
||||
1) My component does not build, what is going wrong?
|
||||
- this might have very different reasons. Check what compiler (CC), flags (CFLAGS/LDFLAGS), include paths (INCLUDES) and libraries (LDLIBS) you are setting in your makefile
|
||||
- check if the code you are writing does compile without this SDK stuff
|
||||
- check if the functions in the component are named with "_cext"
|
||||
|
||||
2) My component is not loaded from the runtime?
|
||||
- if you see a message in the log, like:
|
||||
**** ERROR: libCmpFirstTest.so: cannot open shared object file: No such file or directory
|
||||
or
|
||||
**** ERROR: *** Error: Component <cmp>CmpFirstTest</cmp> NOT loaded
|
||||
-> then your shared object is not found. Please double check that you put it somewhere on your linuxsystem, where it can be found (e.g. /usr/lib/)
|
||||
|
||||
3) Can I output some messages from my code? Where is this output?
|
||||
- just use the normal printf() function in your code. This will be output at the "debug logger". To enable the debug logger, just change the file /etc/defaults/codesyscontrol:
|
||||
set these variables:
|
||||
DEBUGOUTPUT=1
|
||||
and
|
||||
DEBUGLOGFILE=/tmp/codesyscontrol_debug.log
|
||||
then restart the runtime. Then you can see the output at this logfile
|
||||
|
||||
|
||||
##########################
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* this is a special header for the SL extension API!!!
|
||||
* <copyright>
|
||||
* Copyright (c) 2017-2020 CODESYS Development GmbH, Copyright (c) 1994-2016 3S-Smart Software Solutions GmbH. All rights reserved.
|
||||
* </copyright>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __CMPERRORS_H__
|
||||
#define __CMPERRORS_H__
|
||||
|
||||
|
||||
#define ERR_OK 0
|
||||
#define ERR_NOTINITIALIZED 0x0003
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* this is a special header for the SL extension API!!!
|
||||
* <copyright>
|
||||
* Copyright (c) 2017-2020 CODESYS Development GmbH, Copyright (c) 1994-2016 3S-Smart Software Solutions GmbH. All rights reserved.
|
||||
* </copyright>
|
||||
*/
|
||||
|
||||
#ifndef __CMPITF_H__
|
||||
#define __CMPITF_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#ifdef _USRDLL
|
||||
#define DLL_DECL _declspec(dllexport)
|
||||
#endif
|
||||
#endif
|
||||
#if defined(LINUX) || defined(QNX)
|
||||
#ifdef _USRDLL
|
||||
#define DLL_DECL __attribute__ ((visibility ("default")))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(DLL_DECL)
|
||||
#define DLL_DECL
|
||||
#endif
|
||||
|
||||
#ifndef CDECL
|
||||
#define CDECL
|
||||
#endif
|
||||
|
||||
#ifndef CDECL_EXT
|
||||
#define CDECL_EXT
|
||||
#endif
|
||||
|
||||
#ifndef STDCALL
|
||||
#define STDCALL __stdcall
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef RTS_UI32 CMPID; /* Component ID to specify a component. Has the vendor ID as a prefix! */
|
||||
typedef RTS_UI32 CLASSID; /* Class ID to specify a specific class (C or C++) */
|
||||
typedef RTS_UI32 OBJID; /* Object ID, typically the instance index starting with 0 */
|
||||
typedef RTS_UI32 ITFID; /* Interface ID to specify a specific interface (C or C++) */
|
||||
|
||||
#define RTS_VENDORID_3S 0x0000
|
||||
#define RTS_ADDVENDORID(VendorID, ID) (((RTS_UI32)(VendorID) << 16 & UINT32_C(0xFFFF0000)) + (ID))
|
||||
#define ADDVENDORID RTS_ADDVENDORID
|
||||
#define RTS_GETVENDORID(ID) ((RTS_UI32)(ID) >> 16 & UINT32_C(0x0000FFFF))
|
||||
#ifdef TRG_64BIT
|
||||
#define RTSITF_GET_SIGNATURE(sign32bit, sign64bit) sign64bit
|
||||
#else
|
||||
#define RTSITF_GET_SIGNATURE(sign32bit, sign64bit) sign32bit
|
||||
#endif
|
||||
|
||||
|
||||
/* Function that can be used for all CAL_ macros to return ERR_NOTIMPLEMENTED */
|
||||
RTS_RESULT CDECL FUNCTION_NOTIMPLEMENTED(unsigned long dummy,...);
|
||||
RTS_RESULT CDECL FUNCTION_NOTIMPLEMENTED2(void *dummy,...);
|
||||
|
||||
/* Structure to handle a mapping of an ID and a name */
|
||||
typedef struct RTS_ID_TO_NAME_
|
||||
{
|
||||
RTS_UI32 id;
|
||||
char *pszName;
|
||||
} RTS_ID_TO_NAME;
|
||||
|
||||
|
||||
struct tagIBase;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*pointer to virtual function table*/
|
||||
void* __VFTABLEPOINTER;
|
||||
} instance_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
instance_struct *pInstance;
|
||||
RTS_IEC_DWORD dwCount;
|
||||
} addref_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
instance_struct *pInstance;
|
||||
RTS_IEC_DWORD dwCount;
|
||||
} release_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
instance_struct *pInstance;
|
||||
RTS_IEC_DWORD iid;
|
||||
RTS_IEC_RESULT *pResult;
|
||||
instance_struct **ppInterface;
|
||||
} queryinterface_struct;
|
||||
|
||||
typedef unsigned long (CDECL *PF_ADDREF)(struct tagIBase *pIBase);
|
||||
typedef unsigned long (CDECL *PF_RELEASE)(struct tagIBase *pIBase);
|
||||
typedef void *(CDECL *PF_QUERYINTERFACE)(struct tagIBase *pIBase, ITFID iid, RTS_RESULT *pResult);
|
||||
|
||||
typedef void (CDECL *PF_IEC_ADDREF)(void);
|
||||
typedef void (CDECL *PF_IEC_RELEASE)(void);
|
||||
typedef void (CDECL *PF_IEC_QUERYINTERFACE)(void);
|
||||
|
||||
/* <SIL2/> */
|
||||
typedef struct tagIBase
|
||||
{
|
||||
int bIEC;
|
||||
int iRefCount;
|
||||
RTS_HANDLE hInstance;
|
||||
PF_ADDREF AddRef;
|
||||
PF_RELEASE Release;
|
||||
PF_QUERYINTERFACE QueryInterface;
|
||||
CLASSID ClassId;
|
||||
} IBase_C;
|
||||
|
||||
typedef struct tagIBase_IEC
|
||||
{
|
||||
int bIEC;
|
||||
int iRefCount;
|
||||
RTS_HANDLE hInstance;
|
||||
PF_IEC_ADDREF *AddRef;
|
||||
PF_IEC_RELEASE *Release;
|
||||
PF_IEC_QUERYINTERFACE *QueryInterface;
|
||||
} IBase_IEC;
|
||||
|
||||
|
||||
#ifndef STATICITF
|
||||
#define STATICITF static
|
||||
#endif
|
||||
|
||||
#ifndef STATICITF_DEF
|
||||
#define STATICITF_DEF
|
||||
#endif
|
||||
|
||||
#if defined(CPLUSPLUS) && defined(__cplusplus)
|
||||
class IBase
|
||||
{
|
||||
public:
|
||||
virtual unsigned long AddRef(IBase *pIBase = NULL) =0;
|
||||
virtual unsigned long Release(IBase *pIBase = NULL) =0;
|
||||
virtual void *QueryInterface(IBase *pIBase = NULL, ITFID iid = 0, RTS_RESULT *pResult = NULL) =0;
|
||||
virtual ~IBase() { };
|
||||
};
|
||||
|
||||
#define DECLARE_ADDREF()\
|
||||
virtual unsigned long AddRef(IBase *pIBase = NULL);
|
||||
|
||||
#define IMPLEMENT_ADDREF()\
|
||||
virtual unsigned long AddRef(IBase *pIBase = NULL)\
|
||||
{\
|
||||
iRefCount++;\
|
||||
return iRefCount;\
|
||||
}
|
||||
|
||||
#define DECLARE_RELEASE()\
|
||||
virtual unsigned long Release(IBase *pIBase = NULL);
|
||||
|
||||
#define IMPLEMENT_RELEASE()\
|
||||
virtual unsigned long Release(IBase *pIBase = NULL)\
|
||||
{\
|
||||
iRefCount--;\
|
||||
if (iRefCount == 0)\
|
||||
{\
|
||||
delete this;\
|
||||
return 0;\
|
||||
}\
|
||||
return iRefCount;\
|
||||
}
|
||||
|
||||
#define IMPLEMENT_RELEASE_NODELETE()\
|
||||
virtual unsigned long Release(IBase *pIBase = NULL)\
|
||||
{\
|
||||
iRefCount--;\
|
||||
if (iRefCount == 0)\
|
||||
{\
|
||||
return 0;\
|
||||
}\
|
||||
return iRefCount;\
|
||||
}
|
||||
#else
|
||||
#define DECLARE_ADDREF\
|
||||
static unsigned long CDECL AddRef(struct tagIBase *pIBase);
|
||||
|
||||
#define IMPLEMENT_ADDREF\
|
||||
static unsigned long CDECL AddRef(struct tagIBase *pIBase)\
|
||||
{\
|
||||
return (pIBase ? ++pIBase->iRefCount : 0);\
|
||||
}
|
||||
|
||||
#define DECLARE_RELEASE\
|
||||
static unsigned long CDECL Release(struct tagIBase *pIBase);
|
||||
|
||||
#define IMPLEMENT_RELEASE\
|
||||
static unsigned long CDECL Release(struct tagIBase *pIBase)\
|
||||
{\
|
||||
return (pIBase ? --pIBase->iRefCount : 0);\
|
||||
}
|
||||
|
||||
#define DECLARE_QUERYINTERFACE\
|
||||
static void *CDECL QueryInterface(IBase *pBase, ITFID iid, RTS_RESULT *pResult);
|
||||
|
||||
typedef IBase_C IBase;
|
||||
#endif
|
||||
|
||||
/* Global function pointer declarations */
|
||||
typedef int (CDECL *PF_EXPORT_FUNCTIONS)(void);
|
||||
typedef int (CDECL *PF_IMPORT_FUNCTIONS)(void);
|
||||
typedef RTS_UI32 (CDECL *PF_GET_VERSION)(void);
|
||||
typedef RTS_RESULT (CDECL *PF_HOOK_FUNCTION)(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2);
|
||||
/* typedef RTS_RESULT (CDECL *PF_REGISTER_API)(const char *pszAPIName, RTS_VOID_FCTPTR pfAPIFunction, int bExternalLibrary, RTS_UI32 ulSignatureID); */
|
||||
typedef RTS_RESULT (CDECL *PF_REGISTER_API)(const CMP_EXT_FUNCTION_REF *pExpTable, RTS_UINTPTR dummy, int bExternalLibrary, RTS_UI32 cmpId);
|
||||
typedef RTS_RESULT (CDECL *PF_GET_API)(char *pszAPIName, RTS_VOID_FCTPTR *ppfAPIFunction, RTS_UI32 ulSignatureID);
|
||||
typedef RTS_RESULT (CDECL *PF_REGISTER_API2)(const char *pszAPIName, RTS_VOID_FCTPTR pfAPIFunction, int bExternalLibrary, RTS_UI32 ulSignatureID, RTS_UI32 ulVersion);
|
||||
typedef RTS_RESULT (CDECL *PF_GET_API2)(char *pszAPIName, RTS_VOID_FCTPTR *ppfAPIFunction, int bExternalLibrary, RTS_UI32 ulSignatureID, RTS_UI32 ulVersion);
|
||||
typedef RTS_RESULT (CDECL *PF_CALL_HOOK)(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2, int bReverse);
|
||||
typedef IBase* (CDECL *PF_CREATEINSTANCE)(CLASSID cid, RTS_RESULT *pResult);
|
||||
typedef RTS_RESULT (CDECL *PF_DELETEINSTANCE)(IBase *pIBase);
|
||||
typedef RTS_HANDLE (CDECL *PF_REGISTER_CLASS)(CMPID CmpId, CLASSID ClassId);
|
||||
typedef RTS_RESULT (CDECL *PF_DELETEINSTANCE2)(CLASSID ClassId, IBase *pIBase);
|
||||
|
||||
typedef struct tagINIT_STRUCT
|
||||
{
|
||||
/* Exported by Component */
|
||||
CMPID CmpId;
|
||||
#ifdef TRG_64BIT
|
||||
RTS_UI32 aligndummy;
|
||||
#endif
|
||||
PF_EXPORT_FUNCTIONS pfExportFunctions;
|
||||
PF_IMPORT_FUNCTIONS pfImportFunctions;
|
||||
PF_GET_VERSION pfGetVersion;
|
||||
PF_CREATEINSTANCE pfCreateInstance;
|
||||
PF_DELETEINSTANCE pfDeleteInstance;
|
||||
PF_HOOK_FUNCTION pfHookFunction;
|
||||
|
||||
/* Import from CM */
|
||||
PF_REGISTER_API pfCMRegisterAPI;
|
||||
PF_GET_API pfCMGetAPI;
|
||||
PF_CALL_HOOK pfCMCallHook;
|
||||
PF_REGISTER_CLASS pfCMRegisterClass;
|
||||
PF_CREATEINSTANCE pfCMCreateInstance;
|
||||
PF_REGISTER_API2 pfCMRegisterAPI2;
|
||||
PF_GET_API2 pfCMGetAPI2;
|
||||
PF_DELETEINSTANCE2 pfCMDeleteInstance2;
|
||||
} INIT_STRUCT;
|
||||
|
||||
#define COMPONENT_ENTRY_NAME "ComponentEntry"
|
||||
|
||||
#if defined(CPLUSPLUS) && defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined(STATIC_LINK) && !defined(MIXED_LINK) && !defined(DYNAMIC_LINK) && !defined(CPLUSPLUS_STATIC_LINK)
|
||||
DLL_DECL int CDECL ComponentEntry(INIT_STRUCT *pInitStruct);
|
||||
#endif
|
||||
typedef int (CDECL *PF_COMPONENT_ENTRY)(INIT_STRUCT *pInitStruct);
|
||||
|
||||
#if defined(CPLUSPLUS) && defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Functions exported from main */
|
||||
RTS_RESULT CDECL MainLoadComponent(char *pszName, char *pszPath, RTS_HANDLE *phModule, PF_COMPONENT_ENTRY* ppfComponentEntry);
|
||||
RTS_RESULT CDECL MainUnloadComponent(char *pszName, RTS_HANDLE hModule);
|
||||
|
||||
|
||||
/* The following functions are always offered by the component manager */
|
||||
int CDECL MainExitLoop(RTS_UINTPTR ulPar);
|
||||
typedef int (CDECL *PFMAINEXITLOOP)(RTS_UINTPTR ulPar);
|
||||
#ifdef STATIC_LINK
|
||||
#define USE_CMExitLoop extern int CDECL MainExitLoop(RTS_UINTPTR ulPar);
|
||||
#define EXT_CMExitLoop extern int CDECL MainExitLoop(RTS_UINTPTR ulPar);
|
||||
#define GET_CMExitLoop ERR_OK
|
||||
#define CAL_CMExitLoop MainExitLoop
|
||||
#define CHK_CMExitLoop TRUE
|
||||
#define EXP_CMExitLoop TRUE
|
||||
#else /* DYNAMIC_LINK */
|
||||
#define USE_CMExitLoop PFMAINEXITLOOP pfMainExitLoop;
|
||||
#define EXT_CMExitLoop extern PFMAINEXITLOOP pfMainExitLoop;
|
||||
#define GET_CMExitLoop s_pfGetAPI("CMExitLoop", (void **)&pfMainExitLoop, 0)
|
||||
#define CAL_CMExitLoop pfMainExitLoop
|
||||
#define CHK_CMExitLoop (pfMainExitLoop != NULL)
|
||||
#define EXP_CMExitLoop s_pfRegisterAPI("CMExitLoop", MainExitLoop, 1, 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* <description>Hook definitions to inform all components with a broadcast via HookFunction() ([0..10000] reserved for core components):
|
||||
* <ul>
|
||||
* <li>CH_INIT_XXX Hooks: Used for initialization of all components.
|
||||
* Future range, not yet defined! = [1..1000]</li>
|
||||
* <li>CH_EXIT_XXX Hooks: Used for deinitialization of all components.
|
||||
* Future range, not yet defined! = [2000..3000]</li>
|
||||
* <li>CH_XXX Hooks: Used for broadcast commands (e.g. cyclic operations).
|
||||
* Future range, not yet defined! = [4000..5000]</li>
|
||||
* </ul>
|
||||
* IMPLEMENTATION NOTE:
|
||||
* Future hooks should be defined in the appropriate range above!
|
||||
* </description>
|
||||
*/
|
||||
|
||||
/*
|
||||
CH_INIT_XXX Hooks: Used for initialization of all components.
|
||||
*/
|
||||
#define CH_INIT_SYSTEM 1
|
||||
/* First call at system startup to initialize all system components.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_SYSTEM2 8
|
||||
/* Second call at system startup to initialize all system components.
|
||||
(used to resolve dependencies between core components)
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT 2
|
||||
/* First call at system startup. Compontents should initialize all local variables.
|
||||
ulParam1: Pointer to int. Parameter name=pbDontCallInitHooksFromCMInit. Content can be set as followed:
|
||||
0 [Default]: CMInitEnd() is called at the end of CMInit().
|
||||
1: CMInitEnd (calling hooks from CH_INIT2 to CH_INIT_COMM) can be called asynchronously by your own
|
||||
component and is not called in the context of CMInit()!
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_POST_INIT 200
|
||||
/* Called right after CH_INIT. Use this hook to run initialization between
|
||||
highly related components (e.g. Register backends or providers to the corresponding components.).
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_PRE_INIT2 250
|
||||
/* Called right before CH_INIT2. Use this hook to finish initialization of a component that is highly
|
||||
related to an other components. E.g. finish initialization after the providers have registered.
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT2 3
|
||||
/* Called after CH_INIT. All components are initialized. Other components can be used.
|
||||
|
||||
NOTE:
|
||||
Events must be created of the provider in this init step!
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_DONE CH_INIT2
|
||||
/* Backward compatibility */
|
||||
|
||||
#define CH_PRE_INIT3 7
|
||||
/* Called after CH_INIT2 and before CH_INIT3. All components are initialized. Other components can be used.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
#define CH_INIT201 CH_PRE_INIT3
|
||||
/* Backward compatibility */
|
||||
|
||||
#define CH_INIT3 4
|
||||
/* Called after CH_INIT201. All components are initialized. Other components can be used.
|
||||
|
||||
NOTE:
|
||||
Event callbacks must be registered by the consumer in this init step! Events are created in CH_INIT2.
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_SYSTEM_TASKS 500
|
||||
/* Called after CH_INIT3. Tasks can be started that are relevant for the IEC applications.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_TASKS 5
|
||||
/* Called after CH_INIT_SYSTEM_TASKS. All components should start their tasks.
|
||||
|
||||
NOTE:
|
||||
The IEC bootprojects are loaded here!
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_COMM 6
|
||||
/* Called after CH_INIT_TASKS. Communication can be started at this point, because all
|
||||
components are ready and running.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_INIT_FINISHED 1000
|
||||
/* Called at the end of the complete initialization sequence. This is called after CH_INIT_COMM and right before the runtime system
|
||||
fall into the cyclic CH_COMM_CYCLE state.
|
||||
|
||||
NOTE:
|
||||
The IEC bootprojects are started here!
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
/*
|
||||
CH_EXIT_XXX Hooks: Used for deinitialization of all components.
|
||||
*/
|
||||
|
||||
#define CH_EXIT_COMM 10
|
||||
/* Called at the beginning of the shutdown sequence to disable all communication channels!
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT_TASKS 11
|
||||
/* Called before CH_EXIT_SYSTEM_TASKS to stop and remove all tasks that are not needed by the IEC application.
|
||||
|
||||
NOTE:
|
||||
IEC applications are unloaded here.
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT_SYSTEM_TASKS 2200
|
||||
/* Called before CH_EXIT3 to stop and remove all running tasks, because at CH_EXIT3 all objects are released and
|
||||
so no task must run after this point.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT3 12
|
||||
/* Called before CH_EXIT2 to store data (e.g. retain data).
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT2 13
|
||||
/* Called before CH_EXIT to store data (e.g. retain data).
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_PRE_EXIT CH_EXIT2
|
||||
/* Backward compatibility */
|
||||
|
||||
#define CH_EXIT 14
|
||||
/* Here all memory of the components should be released.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT_SYSTEM2 17
|
||||
/* Counter part to CH_INIT_SYSTEM2.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT_SYSTEM 15
|
||||
/* Called at the end of the shutdown process for the system components to release memory.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_EXIT_GARBAGEMEMORY 16
|
||||
/* This is the final call for the garbage collector to check, if heap memory was not released.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
/*
|
||||
CH_XXX Hooks: Used for broadcast commands (e.g. cyclic operations).
|
||||
*/
|
||||
#define CH_COMM_CYCLE 20
|
||||
/* Called every main cycle period. Can be used for background executions.
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_ON_IMPORT 23
|
||||
/* Called for components to import new functions from a new loaded component
|
||||
ulParam1: char *: Pointer to component name
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_ON_IMPORT_RELEASE 24
|
||||
/* Called for components to release imported functions from a component that will be unloaded
|
||||
ulParam1: char *: Pointer to component name
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_ON_LOAD_COMPONENT 25
|
||||
/* Called after loading a new component
|
||||
ulParam1: char *: Pointer to component name
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_ON_UNLOAD_COMPONENT 26
|
||||
/* Called before unloading a component
|
||||
ulParam1: char *: Pointer to component name
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
#define CH_ON_REGISTER_INSTANCE 27
|
||||
/* Called after register a new instance
|
||||
ulParam1: CLASSID: ClassId of instance
|
||||
ulParam2: IBase *: Pointer to IBase
|
||||
*/
|
||||
|
||||
#define CH_ON_UNREGISTER_INSTANCE 28
|
||||
/* Called before unregister a new instance
|
||||
ulParam1: CLASSID: ClassId of instance
|
||||
ulParam2: IBase *: Pointer to IBase
|
||||
*/
|
||||
|
||||
#define CH_ON_LICENSE_FCTS_REGISTERED 29
|
||||
/*
|
||||
Called after the functionpointers from the license-library
|
||||
have been registered to the runtime.
|
||||
*/
|
||||
|
||||
#define CH_ON_LICENSE_FCTS_REGISTERED2 290
|
||||
/*
|
||||
Called after CH_ON_LICENSE_FCTS_REGISTERED.
|
||||
*/
|
||||
|
||||
#define CH_ON_LICENSE_FCTS_LEGACY_REGISTERED 30
|
||||
/*
|
||||
Called after the functionpointers from the license-library
|
||||
have been registered to the runtime.
|
||||
*/
|
||||
|
||||
#define CH_SAFEMODE 4000
|
||||
/*
|
||||
Called when a component fails to resolve its required import functions during startup of the runtime system. In this case, the system is not stable any more.
|
||||
Every component should check safety.
|
||||
After entering the safemode, at least the communication should work and so for example a service engineer can investigate the reason for this error.
|
||||
The logger should work too.
|
||||
|
||||
IMPORTANT NOTE:
|
||||
It is important, that the IEC-application(s) are not loaded or at least are not started after entering the safemode! This is still implemented in the CmpApp component.
|
||||
|
||||
ulParam1: Not used
|
||||
ulParam2: Not used
|
||||
*/
|
||||
|
||||
/**
|
||||
* <category>Hook table</category>
|
||||
* <description>
|
||||
* This is the table of all hooks with its corresponding name (see CM_HOOK_TABLE).
|
||||
*
|
||||
* NOTE:
|
||||
* The init and exit hooks are defined here in the order they are executed during startup and shutdown!
|
||||
*
|
||||
* </description>
|
||||
*/
|
||||
#define CM_INIT_HOOK_TABLE { CH_INIT_SYSTEM, "CH_INIT_SYSTEM" },\
|
||||
{ CH_INIT_SYSTEM2, "CH_INIT_SYSTEM2" },\
|
||||
{ CH_INIT, "CH_INIT" },\
|
||||
{ CH_POST_INIT, "CH_POST_INIT" },\
|
||||
{ CH_PRE_INIT2, "CH_PRE_INIT2" },\
|
||||
{ CH_INIT2, "CH_INIT2" },\
|
||||
{ CH_PRE_INIT3, "CH_PRE_INIT3" },\
|
||||
{ CH_INIT3, "CH_INIT3" },\
|
||||
{ CH_INIT_SYSTEM_TASKS, "CH_INIT_SYSTEM_TASKS" },\
|
||||
{ CH_INIT_TASKS, "CH_INIT_TASKS" },\
|
||||
{ CH_INIT_COMM, "CH_INIT_COMM" },\
|
||||
{ CH_INIT_FINISHED, "CH_INIT_FINISHED" }
|
||||
|
||||
#define CM_COMM_CYCLE_HOOK { CH_COMM_CYCLE, "CH_COMM_CYCLE" }
|
||||
|
||||
#define CM_EXIT_HOOK_TABLE { CH_EXIT_COMM, "CH_EXIT_COMM" },\
|
||||
{ CH_EXIT_TASKS, "CH_EXIT_TASKS" },\
|
||||
{ CH_EXIT_SYSTEM_TASKS, "CH_EXIT_SYSTEM_TASKS" },\
|
||||
{ CH_EXIT3, "CH_EXIT3" },\
|
||||
{ CH_EXIT2, "CH_EXIT2" },\
|
||||
{ CH_EXIT, "CH_EXIT" },\
|
||||
{ CH_EXIT_SYSTEM2, "CH_EXIT_SYSTEM2" },\
|
||||
{ CH_EXIT_SYSTEM, "CH_EXIT_SYSTEM" },\
|
||||
{ CH_EXIT_GARBAGEMEMORY, "CH_EXIT_GARBAGEMEMORY" }
|
||||
|
||||
#define CM_EXTENDED_HOOK_TABLE { CH_ON_IMPORT, "CH_ON_IMPORT" }, \
|
||||
{ CH_ON_IMPORT_RELEASE, "CH_ON_IMPORT_RELEASE" }, \
|
||||
{ CH_ON_LOAD_COMPONENT, "CH_ON_LOAD_COMPONENT" }, \
|
||||
{ CH_ON_UNLOAD_COMPONENT, "CH_ON_UNLOAD_COMPONENT" }, \
|
||||
{ CH_ON_REGISTER_INSTANCE, "CH_ON_REGISTER_INSTANCE" }, \
|
||||
{ CH_ON_UNREGISTER_INSTANCE, "CH_ON_UNREGISTER_INSTANCE" }, \
|
||||
{ CH_ON_LICENSE_FCTS_REGISTERED, "CH_ON_LICENSE_FCTS_REGISTERED" }, \
|
||||
{ CH_ON_LICENSE_FCTS_REGISTERED2, "CH_ON_LICENSE_FCTS_REGISTERED2" }, \
|
||||
{ CH_ON_LICENSE_FCTS_LEGACY_REGISTERED, "CH_ON_LICENSE_FCTS_LEGACY_REGISTERED" }, \
|
||||
{ CH_SAFEMODE, "CH_SAFEMODE" } \
|
||||
|
||||
#define CM_HOOK_TABLE {\
|
||||
CM_INIT_HOOK_TABLE,\
|
||||
CM_COMM_CYCLE_HOOK,\
|
||||
CM_EXIT_HOOK_TABLE,\
|
||||
CM_EXTENDED_HOOK_TABLE\
|
||||
}
|
||||
|
||||
/**
|
||||
* <category>Single import of interface functions</category>
|
||||
* <description>
|
||||
* These macros are used by the System-Components to import single interface functions without modifying
|
||||
* the global SysXXXDep.m4 files.
|
||||
*
|
||||
* ATTENTION:
|
||||
* With usage of these macros, the RtsConfiguration cannot resolve this dependency anymore!!!
|
||||
* So use these macros only in Sys-Components and not in standard or customer components!
|
||||
*
|
||||
* Usage:
|
||||
* #include "<Interface>Itf.h"
|
||||
* USE_SINGLE_ITF(<Interface>) or USE_SINGLE_ITF(<Class>, <Interface>)
|
||||
* USE_SINGLE_FUNCTION(<Function>)
|
||||
*
|
||||
* static int CDECL ImportFunctions(void)
|
||||
* {
|
||||
* IMPORT_SINGLE_ITF(<Interface>);
|
||||
* IMPORT_SINGLE_FUNCTION(<Function>);
|
||||
* return ERR_OK;
|
||||
* }
|
||||
* </description>
|
||||
*/
|
||||
#ifdef CPLUSPLUS
|
||||
#define USE_SINGLE_ITF(Interface_) ITF_##Interface_
|
||||
|
||||
#define IMPORT_SINGLE_ITF(Interface_) \
|
||||
{\
|
||||
IBase *pIBase_;\
|
||||
RTS_RESULT Result_;\
|
||||
if (pI##Interface_ == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase_ = (IBase *)s_pfCMCreateInstance(CLASSID_C##Interface_, &Result_); \
|
||||
if (pIBase_ != NULL) \
|
||||
{\
|
||||
pI##Interface_ = (I##Interface_ *)pIBase_->QueryInterface(pIBase_, ITFID_I##Interface_, &Result_); \
|
||||
pIBase_->Release(pIBase_); \
|
||||
}\
|
||||
} \
|
||||
}
|
||||
|
||||
#define EXIT_SINGLE_ITF(Interface_) \
|
||||
{\
|
||||
IBase *pIBase_;\
|
||||
RTS_RESULT exitResult_;\
|
||||
if (pI##Interface_ != NULL) \
|
||||
{ \
|
||||
pIBase_ = (IBase *)pI##Interface_->QueryInterface(pI##Interface_, ITFID_IBase, &exitResult_); \
|
||||
if (pIBase_ != NULL && exitResult_ == ERR_OK) \
|
||||
{ \
|
||||
pIBase_->Release(pIBase_); \
|
||||
if (pIBase_->Release(pIBase_) == 0) /* The object will be deleted here! */ \
|
||||
pI##Interface_ = NULL; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define IMPORT_SINGLE_ITF2(Class_, Interface_) \
|
||||
{\
|
||||
IBase *pIBase_;\
|
||||
RTS_RESULT Result_;\
|
||||
if (pI##Interface_ == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase_ = (IBase *)s_pfCMCreateInstance(CLASSID_C##Class_, &Result_); \
|
||||
if (pIBase_ != NULL) \
|
||||
{\
|
||||
pI##Interface_ = (I##Interface_ *)pIBase_->QueryInterface(pIBase_, ITFID_I##Interface_, &Result_); \
|
||||
pIBase_->Release(pIBase_); \
|
||||
}\
|
||||
} \
|
||||
}
|
||||
|
||||
#define EXIT_SINGLE_ITF2(Class_, Interface_) \
|
||||
{\
|
||||
IBase *pIBase_;\
|
||||
RTS_RESULT exitResult_;\
|
||||
if (pI##Interface_ != NULL) \
|
||||
{ \
|
||||
pIBase_ = (IBase *)pI##Interface_->QueryInterface(pI##Interface_, ITFID_IBase, &exitResult_); \
|
||||
if (pIBase_ != NULL && exitResult_ == ERR_OK) \
|
||||
{ \
|
||||
pIBase_->Release(pIBase_); \
|
||||
if (pIBase_->Release(pIBase_) == 0) /* The object will be deleted here! */ \
|
||||
pI##Interface_ = NULL; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define USE_SINGLE_ITF(Interface_)
|
||||
#define IMPORT_SINGLE_ITF(Interface_)
|
||||
#define EXIT_SINGLE_ITF(Interface_)
|
||||
#define IMPORT_SINGLE_ITF2(Class_, Interface_)
|
||||
#define EXIT_SINGLE_ITF2(Class_, Interface_)
|
||||
#endif
|
||||
|
||||
#define USE_SINGLE_FUNCTION(Function) USE_##Function
|
||||
#define IMPORT_SINGLE_FUNCTION(Function) GET_##Function(0)
|
||||
#define EXIT_SINGLE_FUNCTION(Function)
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CMPITF_H__*/
|
||||
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* this is a special header for the SL extension API!!!
|
||||
* <copyright>
|
||||
* Copyright (c) 2017-2020 CODESYS Development GmbH, Copyright (c) 1994-2016 3S-Smart Software Solutions GmbH. All rights reserved.
|
||||
* </copyright>
|
||||
*/
|
||||
|
||||
#ifndef __RTSSTD_H__
|
||||
#define __RTSSTD_H__
|
||||
|
||||
|
||||
#if defined(__amd64__)
|
||||
#define TRG_X64
|
||||
#define TRG_64BIT
|
||||
#elif defined(__arm__)
|
||||
#define TRG_ARM
|
||||
#elif defined(__aarch64__)
|
||||
#define TRG_ARM
|
||||
#define TRG_64BIT
|
||||
#elif defined(i386)
|
||||
#error "32 bit X86 is not supported!"
|
||||
#else
|
||||
#error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
#define LINUX
|
||||
|
||||
#define CDECL
|
||||
#define __cdecl CDECL /*necessary for sqlite in CmpCAAStorage*/
|
||||
#define STDCALL
|
||||
#define HUGEPTR
|
||||
|
||||
/****** OS *****/
|
||||
#define SYSTARGET_OS_LINUX
|
||||
|
||||
/*** types ***/
|
||||
#ifndef STDINT_H_UINTPTR_T_DEFINED
|
||||
#define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif
|
||||
typedef unsigned short RTS_WCHAR;
|
||||
#define RTS_WCHAR_DEFINED
|
||||
|
||||
#define INTEL_BYTE_ORDER
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* set default register width
|
||||
*/
|
||||
#ifndef RTS_REGISTER_WIDTH
|
||||
#if defined(TRG_C16X) || defined(TRG_DSP)
|
||||
#define RTS_REGISTER_WIDTH 16
|
||||
#elif defined(TRG_64BIT) || defined(TRG_IA64)
|
||||
#define RTS_REGISTER_WIDTH 64
|
||||
#else
|
||||
#define RTS_REGISTER_WIDTH 32
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if RTS_REGISTER_WIDTH == 64 && !defined (SIZEOF_LONG)
|
||||
#if defined (SYSTARGET_OS_WINDOWS) || defined (SYSTARGET_OS_WINDOWS_RTE) || defined (SYSTARGET_OS_WINDOWS_CE)
|
||||
#define SIZEOF_LONG 4
|
||||
#else
|
||||
#define SIZEOF_LONG 8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Redefine UINT32_C(), INT16_C, ...,
|
||||
* as many compilers are defining this in a bad way. They
|
||||
* are using type-casts to get the correct data-width. This
|
||||
* makes it impossible to use for some pedantic C-Compilers.
|
||||
*/
|
||||
#ifdef INT64_C
|
||||
#undef INT64_C
|
||||
#endif
|
||||
#ifdef UINT64_C
|
||||
#undef UINT64_C
|
||||
#endif
|
||||
#ifdef INT32_C
|
||||
#undef INT32_C
|
||||
#endif
|
||||
#ifdef UINT32_C
|
||||
#undef UINT32_C
|
||||
#endif
|
||||
#ifdef INT16_C
|
||||
#undef INT16_C
|
||||
#endif
|
||||
#ifdef UINT16_C
|
||||
#undef UINT16_C
|
||||
#endif
|
||||
#ifdef INT8_C
|
||||
#undef INT8_C
|
||||
#endif
|
||||
#ifdef UINT8_C
|
||||
#undef UINT8_C
|
||||
#endif
|
||||
|
||||
#define INT64_C(x) (RTS_I64_CONST(x))
|
||||
#define UINT64_C(x) (RTS_UI64_CONST(x))
|
||||
#define INT32_C(x) (x ## L)
|
||||
#define UINT32_C(x) (x ## UL)
|
||||
#define INT16_C(x) (x)
|
||||
#define UINT16_C(x) (x ## U)
|
||||
#define INT8_C(x) (x)
|
||||
#define UINT8_C(x) (x ## U)
|
||||
|
||||
#define RTS_IEC_BOOL_C(x) (x)
|
||||
#define RTS_IEC_BYTE_C(x) (UINT8_C(x))
|
||||
#define RTS_IEC_SINT_C(x) (INT8_C(x))
|
||||
#define RTS_IEC_USINT_C(x) (UINT8_C(x))
|
||||
#define RTS_IEC_INT_C(x) (INT16_C(x))
|
||||
#define RTS_IEC_UINT_C(x) (UINT16_C(x))
|
||||
#define RTS_IEC_DINT_C(x) (INT32_C(x))
|
||||
#define RTS_IEC_UDINT_C(x) (UINT32_C(x))
|
||||
#define RTS_IEC_LINT_C(x) (INT64_C(x))
|
||||
#define RTS_IEC_ULINT_C(x) (UINT64_C(x))
|
||||
#define RTS_IEC_WORD_C(x) (UINT16_C(x))
|
||||
#define RTS_IEC_DWORD_C(x) (UINT32_C(x))
|
||||
#define RTS_IEC_LWORD_C(x) (UINT64_C(x))
|
||||
#define RTS_IEC_REAL_C(x) (x)
|
||||
#define RTS_IEC_LREAL_C(x) (x)
|
||||
#ifdef TRG_64BIT
|
||||
#define RTS_IEC_XINT_C(x) (INT64_C(x))
|
||||
#define RTS_IEC_UXINT_C(x) (UINT64_C(x))
|
||||
#define RTS_IEC_XWORD_C(x) (UINT64_C(x))
|
||||
#else
|
||||
#define RTS_IEC_XINT_C(x) (INT32_C(x))
|
||||
#define RTS_IEC_UXINT_C(x) (UINT32_C(x))
|
||||
#define RTS_IEC_XWORD_C(x) (UINT32_C(x))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Define some more exotic types, which are missing
|
||||
* in many versions of stdint.h.
|
||||
*/
|
||||
#if !defined(STDINT_H_UINTPTR_T_DEFINED)
|
||||
/* Note: If your compiler complains about a "redefinition"
|
||||
* or s.th. similar here, you may set the defines
|
||||
* _UINTPTR_T, _PTRDIFF_T, ... in your sysdefines.h.
|
||||
*/
|
||||
#ifndef _UINTPTR_T
|
||||
typedef uint32_t uintptr_t;
|
||||
#define _UINTPTR_T
|
||||
#endif
|
||||
#ifndef _PTRDIFF_T
|
||||
typedef int32_t ptrdiff_t;
|
||||
#define _PTRDIFF_T
|
||||
#endif
|
||||
#ifndef _INTPTR_T
|
||||
typedef ptrdiff_t intptr_t;
|
||||
#define _INTPTR_T
|
||||
#endif
|
||||
#define STDINT_H_UINTPTR_T_DEFINED
|
||||
#endif /*!defined(STDINT_H_UINTPTR_T_DEFINED)*/
|
||||
|
||||
/* Format modifiers for integral types */
|
||||
#ifndef ULONG_MAX
|
||||
# include <limits.h>
|
||||
# ifndef ULONG_MAX
|
||||
# error ULONG_MAX does not exist in limits.h!
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some basic definitions
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0L
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
/*lint -e666 -e506 */
|
||||
#ifndef MIN
|
||||
# define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
#ifndef RTS_SETRESULT
|
||||
# define RTS_SETRESULT(p,r) do { if(p) *(p)=r; } while(0)
|
||||
#endif
|
||||
|
||||
#ifndef RTS_GETRESULT
|
||||
# define RTS_GETRESULT(Return,Result) (Result == ERR_OK ? (Return) : ((Return) ? Result : Result))
|
||||
#endif
|
||||
|
||||
#ifndef LOWWORD
|
||||
# define LOWWORD(p) ((uint16_t)((uint32_t)(p) & 0x0000FFFF))
|
||||
#endif
|
||||
|
||||
#ifndef HIGHWORD
|
||||
# define HIGHWORD(p) ((uint16_t)(((uint32_t)(p)>>16) & 0x0000FFFF))
|
||||
#endif
|
||||
|
||||
|
||||
/* Operations on flags */
|
||||
#ifndef RTS_SETFLAGS
|
||||
#define RTS_SETFLAGS(value, flags) (value |= (flags))
|
||||
#endif
|
||||
#ifndef RTS_SETFLAG
|
||||
#define RTS_SETFLAG(value, flag) RTS_SETFLAGS(value, flag)
|
||||
#endif
|
||||
|
||||
#ifndef RTS_RESETFLAGS
|
||||
#define RTS_RESETFLAGS(value, flags) (value &= ~(flags))
|
||||
#endif
|
||||
#ifndef RTS_RESETFLAG
|
||||
#define RTS_RESETFLAG(value, flag) RTS_RESETFLAGS(value, flag)
|
||||
#endif
|
||||
|
||||
#ifndef RTS_HASFLAGS
|
||||
#define RTS_HASFLAGS(value, flags) ((value & (flags)) == (flags))
|
||||
#endif
|
||||
#ifndef RTS_HASFLAG
|
||||
#define RTS_HASFLAG(value, flag) (value & (flag))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef ALIGN_MEMORY
|
||||
# define ALIGN_MEMORY(pMemory) ((void *)(((((uintptr_t)(pMemory) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*))))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_MEMORY_SIZE
|
||||
# define ALIGN_MEMORY_SIZE(pMemory, iSize) ((iSize) - (((((uintptr_t)(pMemory) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)) - (uintptr_t)(pMemory)))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_MEMORY2
|
||||
# define ALIGN_MEMORY2(pMemory, Modulo) ((void *)((((uintptr_t)(pMemory) + (Modulo) - 1) / (uintptr_t)(Modulo)) * (uintptr_t)(Modulo)))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_MEMORY2_BACK
|
||||
# define ALIGN_MEMORY2_BACK(pMemory, Modulo) ((void *)(((uintptr_t)(pMemory) / (uintptr_t)(Modulo)) * (uintptr_t)(Modulo)))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_MEMORY_SIZE2
|
||||
# define ALIGN_MEMORY_SIZE2(pMemory, iSize, Modulo) ((iSize) - (((((uintptr_t)(pMemory) + (Modulo) - 1) / sizeof(void*)) * (Modulo)) - (uintptr_t)(pMemory)))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
/* NOTE: it seems like this operation can be made without a comparison: */
|
||||
/* #define ALIGN_SIZE(Size, Modulo) (( (Size) + ((Modulo) - 1) ) / (Modulo)) * (Modulo) */
|
||||
# define ALIGN_SIZE(Size, Modulo) /*lint -e{506} */(((Size) % (Modulo)) ? ((Size) + ((Modulo) - ((Size) % (Modulo)))) : (Size))
|
||||
#endif
|
||||
|
||||
#ifndef RTS_VSNPRINTF
|
||||
#if defined(RTS_VSNPRINTF_NOT_AVAILABLE)
|
||||
#define RTS_VSNPRINTF(s,len,format,arglist) vsprintf(s,format,arglist)
|
||||
#else
|
||||
#define RTS_VSNPRINTF(s,len,format,arglist) vsnprintf(s,len,format,arglist)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef va_copy
|
||||
#define va_copy(destination, source) ((destination) = (source))
|
||||
#endif
|
||||
|
||||
|
||||
#define CONCAT(x,y) x##y
|
||||
|
||||
/* Some preprocessors do not allow to place such a macro within other macros */
|
||||
/* and/or pragmas. */
|
||||
#define ____QUOTE____(x) #x
|
||||
#define QUOTE(x) ____QUOTE____(x)
|
||||
|
||||
#ifdef INTEL_BYTE_ORDER
|
||||
# define SWAP16u(x) (x)
|
||||
# define SWAP16s(x) (x)
|
||||
# define SWAP32u(x) (x)
|
||||
# define SWAP32s(x) (x)
|
||||
#elif defined(MOTOROLA_BYTE_ORDER)
|
||||
# define SWAP16u(x) ( (uint16_t)((((x) & 0xFF)<<8) | (((x) & 0xFF00) >> 8)) )
|
||||
# define SWAP16s(x) ( (int16_t)((((x) & 0xFF)<<8) | (((x) & 0xFF00) >> 8)) )
|
||||
# define SWAP32u(x) ( (uint32_t)((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) )
|
||||
# define SWAP32s(x) ((int32_t)((((uint32_t)(x)) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
|
||||
#else
|
||||
#error "No byte order defined for the current target"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "CmpErrors.h"
|
||||
|
||||
#define CAL_CMGETAPI(name) ERR_OK
|
||||
#define CAL_CMEXPAPI(name) ERR_OK
|
||||
|
||||
typedef void HUGEPTR(CDECL *RTS_VOID_FCTPTR)(void);
|
||||
|
||||
|
||||
/*
|
||||
* Runtime system basic typedefinitions.
|
||||
* Defines some types with special meaning. Systems not using standard type sizes
|
||||
* must redefine this types in sysdefines.h and set BASETYPES_DEFINED
|
||||
*/
|
||||
|
||||
#ifndef RTS_I64_CONST
|
||||
#define RTS_I64_CONST(a) (a##LL)
|
||||
#endif
|
||||
#ifndef RTS_UI64_CONST
|
||||
#define RTS_UI64_CONST(a) (a##ULL)
|
||||
#endif
|
||||
|
||||
#ifndef BASETYPES_DEFINED
|
||||
# define BASETYPES_DEFINED
|
||||
|
||||
typedef int8_t RTS_I8; /* Signed 8 bit value */
|
||||
typedef int16_t RTS_I16; /* Signed 16 bit value */
|
||||
#ifndef RTS_I32_DEFINED
|
||||
#define RTS_I32_DEFINED
|
||||
typedef int32_t RTS_I32; /* Signed 32 bit value */
|
||||
#endif
|
||||
|
||||
typedef uint8_t RTS_UI8; /* Unsigned 8 bit value */
|
||||
# define RTS_UI8_MAX (RTS_UI8)(~((RTS_UI8)0))
|
||||
|
||||
typedef uint16_t RTS_UI16; /* Unsigned 16 bit value */
|
||||
# define RTS_UI16_MAX (RTS_UI16)(~((RTS_UI16)0))
|
||||
|
||||
#ifndef RTS_UI32_DEFINED
|
||||
#define RTS_UI32_DEFINED
|
||||
typedef uint32_t RTS_UI32; /* Unsigned 32 bit value */
|
||||
#endif
|
||||
# define RTS_UI32_MAX (RTS_UI32)(~((RTS_UI32)0))
|
||||
|
||||
#ifndef IEEE754TYPES_DEFINED
|
||||
# define IEEE754TYPES_DEFINED
|
||||
typedef float RTS_REAL32; /* 32 bit floating point value */
|
||||
typedef double RTS_REAL64; /* 64 bit floating point value */
|
||||
#define RTS_REAL32_MAX 3.4028234e+38
|
||||
#define RTS_REAL64_MAX 1.7976931348623157e+308
|
||||
#endif
|
||||
|
||||
typedef void* RTS_HANDLE; /* Handle for files, semaphores, ... Usually the native integer type of the platform*/
|
||||
#define RTS_INVALID_HANDLE ((RTS_HANDLE)(~((uintptr_t)0)))
|
||||
|
||||
typedef RTS_UI32 RTS_RESULT; /* Result type for most functions. At least 16 bit. Should be the natural integer of a platform. */
|
||||
|
||||
typedef uintptr_t RTS_UINTPTR; /* Unsigned integral type that can hold a pointer */
|
||||
#define RTS_UINTPTR_MAX (RTS_UINTPTR)(~((RTS_UINTPTR)0))
|
||||
|
||||
typedef intptr_t RTS_INTPTR; /* Signed integral type that can hold a pointer */
|
||||
#define RTS_INTPTR_MAX (RTS_INTPTR)(~((RTS_INTPTR)0))
|
||||
|
||||
typedef ptrdiff_t RTS_PTRDIFF; /* Signed integral type that can hold an array index */
|
||||
#define RTS_PTRDIFF_MAX (RTS_PTRDIFF)(~((RTS_PTRDIFF)0))
|
||||
|
||||
#ifndef RTS_SIZE_DEFINED
|
||||
#define RTS_SIZE_DEFINED
|
||||
typedef size_t RTS_SIZE; /* Unsigned integral type that can hold a buffer offset */
|
||||
#endif
|
||||
#define RTS_SIZE_MAX (RTS_SIZE)(~((RTS_SIZE)0))
|
||||
|
||||
/* Type definition of RTS_SSIZE should be changed to standard datatype ssize_t, if available on any target! */
|
||||
#ifndef RTS_SSIZE_DEFINED
|
||||
#define RTS_SSIZE_DEFINED
|
||||
typedef intptr_t RTS_SSIZE; /* integral type that can hold a buffer offset */
|
||||
#endif
|
||||
#define RTS_SSIZE_MAX (RTS_SSIZE)(~((RTS_SSIZE)0))
|
||||
|
||||
typedef RTS_UINTPTR RTS_TIME; /* Coordinated Universal Time (UTC) */
|
||||
|
||||
typedef int RTS_INT; /* Data type has no constant size, so be careful in sharing shuch datatypes with IEC! */
|
||||
typedef int RTS_BOOL; /* Boolean value (TRUE or FALSE). For best performance use platform specific int.
|
||||
Data type has no constant size, so be carful in sharing shuch datatypes with IEC! */
|
||||
#if defined(RTS_DISABLE_64BIT_SUPPORT) && !defined(SYSINTERNAL_DISABLE_64BIT)
|
||||
#define SYSINTERNAL_DISABLE_64BIT
|
||||
#endif
|
||||
|
||||
#if !defined(BASE64BITTYPES_DEFINED) && !defined(SYSINTERNAL_DISABLE_64BIT)
|
||||
# define BASE64BITTYPES_DEFINED
|
||||
typedef uint64_t RTS_UI64;
|
||||
typedef int64_t RTS_I64;
|
||||
#define RTS_UI64_MAX (RTS_UI64)(~((RTS_UI64)0))
|
||||
#define RTS_I64_MAX (RTS_I64)(~((RTS_I64)0))
|
||||
#endif
|
||||
|
||||
typedef char RTS_CSTRING;
|
||||
typedef char RTS_UTF8STRING;
|
||||
|
||||
# ifndef RTS_WCHAR_DEFINED
|
||||
# define RTS_WCHAR_DEFINED
|
||||
typedef wchar_t RTS_WCHAR; /* wide character value. We expect 2 bytes unicode here! */
|
||||
# endif /*RTS_WCHAR_DEFINED*/
|
||||
|
||||
# ifndef RTS_CWCHAR_DEFINED
|
||||
# define RTS_CWCHAR_DEFINED
|
||||
# ifdef RTS_UNICODE
|
||||
typedef RTS_WCHAR RTS_CWCHAR;
|
||||
# else
|
||||
typedef RTS_CSTRING RTS_CWCHAR;
|
||||
# endif
|
||||
# endif /*RTS_CWCHAR_DEFINED*/
|
||||
|
||||
#ifdef RTS_DEFINE_MODE_T
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_GID_T
|
||||
typedef short gid_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_UID_T
|
||||
typedef short uid_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_ID_T
|
||||
typedef intptr_t id_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_PID_T
|
||||
typedef uintptr_t pid_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_OFF_T
|
||||
typedef uintptr_t off_t;
|
||||
#endif
|
||||
#ifdef RTS_DEFINE_NLINK_T
|
||||
typedef short nlink_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /*BASETYPES_DEFINED*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTSTYPE_I8,
|
||||
RTSTYPE_I16,
|
||||
RTSTYPE_I32,
|
||||
RTSTYPE_UI8,
|
||||
RTSTYPE_UI16,
|
||||
RTSTYPE_UI32,
|
||||
RTSTYPE_REAL32,
|
||||
RTSTYPE_REAL64,
|
||||
RTSTYPE_HANDLE,
|
||||
RTSTYPE_RESULT,
|
||||
RTSTYPE_UINTPTR,
|
||||
RTSTYPE_INTPTR,
|
||||
RTSTYPE_SIZE,
|
||||
RTSTYPE_PTRDIFF,
|
||||
RTSTYPE_INT,
|
||||
RTSTYPE_BOOL,
|
||||
RTSTYPE_UI64,
|
||||
RTSTYPE_I64,
|
||||
RTSTYPE_CSTRING,
|
||||
RTSTYPE_WCHAR,
|
||||
RTSTYPE_CWCHAR
|
||||
}RTS_TYPECLASS;
|
||||
|
||||
typedef union
|
||||
{
|
||||
RTS_I8 i8Value;
|
||||
RTS_I16 i16Value;
|
||||
RTS_I32 i32Value;
|
||||
RTS_UI8 ui8Value;
|
||||
RTS_UI16 ui16Value;
|
||||
RTS_UI32 ui32Value;
|
||||
RTS_REAL32 real32Value;
|
||||
RTS_REAL64 real64Value;
|
||||
RTS_HANDLE handleValue;
|
||||
RTS_RESULT resultValue;
|
||||
RTS_UINTPTR uintptrValue;
|
||||
RTS_INTPTR intptrValue;
|
||||
RTS_SIZE sizeValue;
|
||||
RTS_PTRDIFF ptrdiffValue;
|
||||
RTS_INT intValue;
|
||||
RTS_BOOL boolValue;
|
||||
RTS_UI64 ui64Value;
|
||||
RTS_I64 i64Value;
|
||||
RTS_CSTRING *cstringValue;
|
||||
RTS_WCHAR *wstringValue;
|
||||
RTS_CWCHAR *cwstringValue;
|
||||
}RTS_VALUE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
RTS_TYPECLASS typeClass;
|
||||
RTS_VALUE value;
|
||||
}RTS_TYPEDVALUE;
|
||||
|
||||
|
||||
/*
|
||||
* IEC basic typedefinitions.
|
||||
* Defines all datatypes used in IEC programs. Datatypes must match to CoDeSys compiler.
|
||||
* Systems that overloads standard types must redefine this types in sysdefines.h and set IECBASETYPES_DEFINED
|
||||
*/
|
||||
|
||||
typedef void HUGEPTR(CDECL *RTS_VOID_FCTPTR)(void);
|
||||
|
||||
#ifndef IECBASETYPES_DEFINED
|
||||
#define IECBASETYPES_DEFINED
|
||||
|
||||
# define RTS_IEC_VOID_FCTPTR RTS_VOID_FCTPTR
|
||||
typedef void* RTS_IEC_VOIDPTR;
|
||||
|
||||
typedef RTS_I8 RTS_IEC_BOOL;
|
||||
typedef RTS_I8 RTS_IEC_SINT;
|
||||
typedef RTS_UI8 RTS_IEC_USINT;
|
||||
typedef RTS_UI8 RTS_IEC_BYTE;
|
||||
typedef RTS_I16 RTS_IEC_INT;
|
||||
typedef RTS_UI16 RTS_IEC_UINT;
|
||||
typedef RTS_UI16 RTS_IEC_WORD;
|
||||
typedef RTS_I32 RTS_IEC_DINT;
|
||||
typedef RTS_UI32 RTS_IEC_UDINT;
|
||||
typedef RTS_UI32 RTS_IEC_DWORD;
|
||||
|
||||
typedef RTS_UI32 RTS_IEC_TIME;
|
||||
typedef RTS_UI32 RTS_IEC_TIME_OF_DAY;
|
||||
typedef RTS_UI32 RTS_IEC_TOD;
|
||||
typedef RTS_UI32 RTS_IEC_DATE_AND_TIME;
|
||||
typedef RTS_UI32 RTS_IEC_DT;
|
||||
typedef RTS_UI32 RTS_IEC_DATE;
|
||||
|
||||
typedef RTS_I64 RTS_IEC_LINT;
|
||||
typedef RTS_UI64 RTS_IEC_ULINT;
|
||||
typedef RTS_UI64 RTS_IEC_LWORD;
|
||||
typedef RTS_UI64 RTS_IEC_LTIME;
|
||||
|
||||
typedef RTS_SIZE RTS_IEC_XWORD;
|
||||
typedef RTS_UINTPTR RTS_IEC_UXINT;
|
||||
typedef RTS_PTRDIFF RTS_IEC_XINT;
|
||||
|
||||
typedef RTS_REAL32 RTS_IEC_REAL;
|
||||
typedef RTS_REAL64 RTS_IEC_LREAL;
|
||||
|
||||
typedef RTS_CSTRING RTS_IEC_STRING;
|
||||
# ifdef RTS_UNICODE
|
||||
typedef RTS_WCHAR RTS_IEC_WSTRING;
|
||||
# else
|
||||
typedef RTS_UI16 RTS_IEC_WSTRING;
|
||||
# endif
|
||||
typedef RTS_CWCHAR RTS_IEC_CWCHAR;
|
||||
|
||||
typedef RTS_SIZE RTS_IEC_SIZE;
|
||||
typedef RTS_HANDLE RTS_IEC_HANDLE;
|
||||
typedef RTS_IEC_UDINT RTS_IEC_RESULT;
|
||||
#endif /*IECBASETYPES_DEFINED*/
|
||||
|
||||
|
||||
#ifndef RTS_MEM_REGION_DEFINED
|
||||
#define RTS_MEM_REGION_DEFINED
|
||||
|
||||
/**
|
||||
* <description>
|
||||
* Abstract Memory Region.
|
||||
* </description>
|
||||
*/
|
||||
typedef struct tagRTS_MEM_REGION
|
||||
{
|
||||
/* base address of the region */
|
||||
RTS_UINTPTR base;
|
||||
|
||||
/* region size */
|
||||
RTS_SIZE size;
|
||||
|
||||
} RTS_MEM_REGION;
|
||||
#endif
|
||||
|
||||
#ifndef EXT_FUNCT_REF_DEFINED
|
||||
#define EXT_FUNCT_REF_DEFINED
|
||||
/**
|
||||
* Exported function descriptor
|
||||
*/
|
||||
typedef struct tagCMP_EXT_FUNCTION_REF
|
||||
{
|
||||
/* pointer to an exported function */
|
||||
RTS_VOID_FCTPTR pfExtCall;
|
||||
|
||||
/* name of an exported function */
|
||||
const char* pszExtCallName;
|
||||
|
||||
/* signature */
|
||||
RTS_UI32 signature;
|
||||
|
||||
/* version */
|
||||
RTS_UI32 version;
|
||||
|
||||
} CMP_EXT_FUNCTION_REF;
|
||||
#endif
|
||||
|
||||
/* The CMGetAPI2/CMGetAPI3 importOptions parameter flag which specifies an import */
|
||||
/* as a required function (error if it is unresolved) */
|
||||
#define CM_IMPORT_REQUIRED_FUNCTION 0
|
||||
|
||||
/* The CMGetAPI2/CMGetAPI3 importOptions parameter flag which specifies an import */
|
||||
/* as an external libray function */
|
||||
#define CM_IMPORT_EXTERNAL_LIB_FUNCTION 1
|
||||
|
||||
/* The CMGetAPI2/CMGetAPI3 importOptions parameter flag which specifies an import */
|
||||
/* as an optional function */
|
||||
#define CM_IMPORT_OPTIONAL_FUNCTION 2
|
||||
|
||||
/* Imported function belongs to an external libray */
|
||||
#define ImportIsExternalLibFunction(par) (0 != ((par) & CM_IMPORT_EXTERNAL_LIB_FUNCTION))
|
||||
|
||||
/* Imported function is optional */
|
||||
#define ImportIsOptionalFunction(par) (0 != ((par) & CM_IMPORT_OPTIONAL_FUNCTION))
|
||||
|
||||
#define RTS_SIZEOF sizeof
|
||||
#define RTS_GET_WORD_OFFSET(typesize) (typesize)
|
||||
#define RTS_GET_WORD_SIZE RTS_GET_WORD_OFFSET
|
||||
#define RTS_GET_BYTE_OFFSET(offset) (offset)
|
||||
#define RTS_GET_BYTE_SIZE(size) (size)
|
||||
#define RTS_MEMSET memset
|
||||
#define RTS_ALIGN_4BYTES 4
|
||||
#define RTS_BITS_IN_BYTE 8
|
||||
|
||||
#define RTS_EMPTY_STRING ""
|
||||
#define RTS_IS_EMPTY_STRING(s) ((char *)s == NULL || strcmp((char *)s, RTS_EMPTY_STRING) == 0)
|
||||
|
||||
#define RTS_TIMEOUT_INFINITE (~(RTS_UI32)0)
|
||||
#define RTS_TIMEOUT_DEFAULT (RTS_UI32)(-2)
|
||||
#define RTS_TIMEOUT_NO_WAIT (0)
|
||||
|
||||
#define RTS_INVALID_FILETRANSFER (RTS_UI32)(-1)
|
||||
|
||||
#include "CmpItf.h"
|
||||
|
||||
|
||||
#ifndef COMPONENT_NAME_POSTFIX
|
||||
#define COMPONENT_NAME_POSTFIX
|
||||
#endif
|
||||
|
||||
#endif /*__RTSSTD_H__*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,897 @@
|
||||
divert(-1)
|
||||
% -----------------------------------
|
||||
% Copyright: Copyright CODESYS Development GmbH
|
||||
% -----------------------------------
|
||||
# The following lines ("DO NOT MODIFY...") generate a message in the destination file.
|
||||
# This comment is not aimed at this file.
|
||||
divert`'dnl
|
||||
/***********************************************************************
|
||||
* DO NOT MODIFY!
|
||||
* This is a generated file. Do not modify it's contents directly
|
||||
***********************************************************************/
|
||||
include(`Util.m4')
|
||||
divert(-1)
|
||||
|
||||
changecom(`%')
|
||||
% -----------------------------
|
||||
% Define some diverts that gather information about some special features
|
||||
% and initialize those diversions
|
||||
% -----------------------------
|
||||
define(DIVERT_USE,3)
|
||||
define(DIVERT_USEIMPORT,4)
|
||||
define(DIVERT_USEEXTERN,5)
|
||||
define(DIVERT_INIT,6)
|
||||
define(DIVERT_RENAME_ENTRYFUN,9)
|
||||
define(DIVERT_BEGINCLASSDEF,10)
|
||||
define(DIVERT_CLASSDEF,11)
|
||||
define(DIVERT_CLASSMEMBERS,12)
|
||||
define(DIVERT_ENDCLASSDEF,13)
|
||||
define(DIVERT_ENDMETHODDEF,15)
|
||||
define(DIVERT_URTS_DEFS, 20)
|
||||
define(DIVERT_ENDFILE,100)
|
||||
|
||||
define(`REF_ITF', `GEN_INCLUDE($1)')
|
||||
|
||||
define(`COMPONENT_VERSION',`#define CMP_VERSION UINT32_C(`$1')
|
||||
#define CMP_VERSION_STRING "_VERSION_MAJOR(`$1')._VERSION_SUB0(`$1')._VERSION_SUB1(`$1')._VERSION_SUB2(`$1')"
|
||||
#define CMP_VERSION_RC _VERSION_MAJOR(`$1'),_VERSION_SUB0(`$1'),_VERSION_SUB1(`$1'),_VERSION_SUB2(`$1')')
|
||||
define(`COMPONENT_VENDORID',`#define CMP_VENDORID $1
|
||||
|
||||
#ifndef WIN32_RESOURCES')
|
||||
|
||||
divert(DIVERT_USE)dnl
|
||||
#define USE_STMT \
|
||||
/*lint -save --e{528} --e{551} */ \
|
||||
static volatile PF_REGISTER_API s_pfCMRegisterAPI; \
|
||||
static volatile PF_REGISTER_API2 s_pfCMRegisterAPI2; \
|
||||
static volatile PF_GET_API s_pfCMGetAPI; \
|
||||
static volatile PF_GET_API2 s_pfCMGetAPI2; \
|
||||
static volatile PF_REGISTER_CLASS s_pfCMRegisterClass; \
|
||||
static volatile PF_CREATEINSTANCE s_pfCMCreateInstance; \
|
||||
static volatile PF_CALL_HOOK s_pfCMCallHook; \
|
||||
static const CMP_EXT_FUNCTION_REF s_ExternalsTable[] =\
|
||||
{\
|
||||
EXPORT_EXTREF_STMT\
|
||||
EXPORT_EXTREF2_STMT\
|
||||
{ ((RTS_VOID_FCTPTR)(void *)0), "", 0, 0 }\
|
||||
};\
|
||||
static const CMP_EXT_FUNCTION_REF s_ItfTable[] = EXPORT_CMPITF_STMT; \
|
||||
/*lint -restore */ \
|
||||
static int CDECL ExportFunctions(void); \
|
||||
static int CDECL ImportFunctions(void); \
|
||||
static IBase* CDECL CreateInstance(CLASSID cid, RTS_RESULT *pResult); \
|
||||
static RTS_RESULT CDECL DeleteInstance(IBase *pIBase); \
|
||||
static RTS_UI32 CDECL CmpGetVersion(void); \
|
||||
static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2); \
|
||||
dnl
|
||||
divert(-1)
|
||||
|
||||
|
||||
divert(DIVERT_USEIMPORT)
|
||||
#define USEIMPORT_STMT \
|
||||
/*lint -save --e{551} */ \
|
||||
static volatile PF_REGISTER_API s_pfCMRegisterAPI; \
|
||||
static volatile PF_REGISTER_API2 s_pfCMRegisterAPI2; \
|
||||
static volatile PF_GET_API s_pfCMGetAPI; \
|
||||
static volatile PF_GET_API2 s_pfCMGetAPI2; \
|
||||
static volatile PF_REGISTER_CLASS s_pfCMRegisterClass; \
|
||||
static volatile PF_CREATEINSTANCE s_pfCMCreateInstance; \
|
||||
static volatile PF_CALL_HOOK s_pfCMCallHook; \
|
||||
/*lint -restore */ \
|
||||
dnl
|
||||
divert(-1)
|
||||
|
||||
|
||||
|
||||
divert(DIVERT_USEEXTERN)
|
||||
#define USEEXTERN_STMT \
|
||||
dnl
|
||||
divert(-1)
|
||||
|
||||
divert(DIVERT_RENAME_ENTRYFUN)
|
||||
#ifndef COMPONENT_NAME
|
||||
#error COMPONENT_NAME is not defined. This prevents the component from being linked statically. Use `SET_COMPONENT_NAME'(<name_of_your_component>) to set the name of the component in your .m4 component description.
|
||||
#endif
|
||||
divert(-1)
|
||||
|
||||
divert(DIVERT_BEGINCLASSDEF)
|
||||
#ifdef CPLUSPLUS
|
||||
divert(-1)
|
||||
|
||||
divert(DIVERT_ENDMETHODDEF)
|
||||
#endif /*CPLUSPLUS*/
|
||||
divert(-1)
|
||||
|
||||
divert(DIVERT_ENDFILE)
|
||||
`#endif /*WIN32_RESOURCES*/'
|
||||
`#endif /*_DEP_H_*/'
|
||||
divert(-1)')
|
||||
|
||||
|
||||
% ---------------------------
|
||||
% The SET_COMPONENT_NAME directive should reside at the top of each "Itf" file.
|
||||
% ---------------------------
|
||||
|
||||
define(`SET_COMPONENT_NAME',
|
||||
`define(_COMPONENT_NAME,`$1')dnl
|
||||
`#ifndef _'_UPPERCASE(_COMPONENT_NAME)`DEP_H_'
|
||||
`#define _'_UPPERCASE(_COMPONENT_NAME)`DEP_H_'
|
||||
|
||||
#define COMPONENT_NAME "$1" COMPONENT_NAME_POSTFIX
|
||||
#define COMPONENT_ID ADDVENDORID(CMP_VENDORID, CMPID_$1)
|
||||
#define COMPONENT_NAME_UNQUOTED $1
|
||||
|
||||
divert(DIVERT_RENAME_ENTRYFUN)
|
||||
|
||||
divert(DIVERT_RENAME_ENTRYFUN)
|
||||
|
||||
#if defined(STATIC_LINK) || defined(MIXED_LINK) || defined(DYNAMIC_LINK) || defined(CPLUSPLUS_STATIC_LINK)
|
||||
#define ComponentEntry $1`'__Entry
|
||||
#endif
|
||||
|
||||
divert
|
||||
|
||||
divert(DIVERT_URTS_DEFS)dnl
|
||||
|
||||
divert
|
||||
')
|
||||
|
||||
% -----------------------------
|
||||
% The COMPONENT_SOURCES and COMPONENT_SYSSOURCES macros are to be ignored. They
|
||||
% are used by the configuration tool only.
|
||||
% -----------------------------
|
||||
define(`COMPONENT_SOURCES',`dnl')
|
||||
define(`EXTERNAL_SOURCES',`dnl')
|
||||
define(`EXTERNAL_INCLUDES',`dnl')
|
||||
define(`COMPONENT_INCLUDES',`dnl')
|
||||
define(`COMPONENT_SYSSOURCES',`dnl')
|
||||
define(`CONTRIB_SOURCES',`dnl')
|
||||
define(`CONTRIB_INCLUDES',`dnl')
|
||||
')
|
||||
|
||||
% -----------------------------
|
||||
% The CATEGORY macro is to be ignored. It
|
||||
% is used by the configuration tool only.
|
||||
% -----------------------------
|
||||
define(`CATEGORY',`dnl')
|
||||
')
|
||||
|
||||
% -----------------------------
|
||||
% After all input is read, some macros have to be created
|
||||
% -----------------------------
|
||||
define(`ADD_IMPORTS',`ifdef(`__IMPORTS',`__IMPORTS popdef(`__IMPORTS') ADD_IMPORTS')')
|
||||
define(`CREATE_IMPORT_STMT', dnl
|
||||
`ifdef(`__IMPORTS',`#if defined(STATIC_LINK)
|
||||
#define IMPORT_STMT
|
||||
#else
|
||||
#define IMPORT_STMT \
|
||||
{\
|
||||
RTS_RESULT importResult = ERR_OK;\
|
||||
RTS_RESULT TempResult = ERR_OK;\
|
||||
INIT_STMT \
|
||||
TempResult = GET_LogAdd(CM_IMPORT_OPTIONAL_FUNCTION); \
|
||||
TempResult = GET_CMUtlMemCpy(CM_IMPORT_OPTIONAL_FUNCTION); \
|
||||
ADD_IMPORTS \
|
||||
/* To make LINT happy */\
|
||||
TempResult = TempResult;\
|
||||
if (ERR_OK != importResult) return importResult;\
|
||||
}
|
||||
#endif
|
||||
',`#define IMPORT_STMT INIT_STMT')
|
||||
')
|
||||
|
||||
% -----------------------------
|
||||
% This function emits all export statements inside the macro EXPORT_STMT (one after another)
|
||||
% -----------------------------
|
||||
define(`ADD_EXPORTS',`ifdef(`__EXPORTS',`__EXPORTS popdef(`__EXPORTS') ADD_EXPORTS')')
|
||||
define(`ADD_EXTREF_EXPORTS',`ifdef(`__EXPORTS_EXTREF',`__EXPORTS_EXTREF popdef(`__EXPORTS_EXTREF') ADD_EXTREF_EXPORTS')')
|
||||
define(`ADD_EXTREF_EXPORTS2',`ifdef(`__EXPORTS_EXTREF2',`__EXPORTS_EXTREF2 popdef(`__EXPORTS_EXTREF2') ADD_EXTREF_EXPORTS2')')
|
||||
define(`ADD_EXPORTS_CPLUSPLUS_ONLY',`ifdef(`__EXPORTS_CPLUSPLUS_ONLY',`__EXPORTS_CPLUSPLUS_ONLY popdef(`__EXPORTS_CPLUSPLUS_ONLY') ADD_EXPORTS_CPLUSPLUS_ONLY')')
|
||||
|
||||
% -----------------------------
|
||||
% Define the EXPORT_STMT macro. the content is filled out by ADD_EXPORTS.
|
||||
% -----------------------------
|
||||
define(`CREATE_EXPORT_STMT',dnl
|
||||
`ifdef(`__EXPORTS_EXTREF',dnl
|
||||
`#ifndef _UPPERCASE(_COMPONENT_NAME)_DISABLE_EXTREF
|
||||
#define EXPORT_EXTREF_STMT \
|
||||
ADD_EXTREF_EXPORTS
|
||||
#else
|
||||
#define EXPORT_EXTREF_STMT
|
||||
#endif',`#define EXPORT_EXTREF_STMT')
|
||||
'dnl
|
||||
`ifdef(`__EXPORTS_EXTREF2',dnl
|
||||
`#ifndef _UPPERCASE(_COMPONENT_NAME)_DISABLE_EXTREF2
|
||||
#define EXPORT_EXTREF2_STMT \
|
||||
ADD_EXTREF_EXPORTS2
|
||||
#else
|
||||
#define EXPORT_EXTREF2_STMT
|
||||
#endif',`#define EXPORT_EXTREF2_STMT')
|
||||
'dnl
|
||||
`ifdef(`__EXPORTS',dnl
|
||||
`#if !defined(_UPPERCASE(_COMPONENT_NAME)_DISABLE_CMPITF) && !defined(STATIC_LINK) && !defined(CPLUSPLUS) && !defined(CPLUSPLUS_ONLY)
|
||||
#define EXPORT_CMPITF_STMT \
|
||||
{\
|
||||
ADD_EXPORTS\
|
||||
{ ((RTS_VOID_FCTPTR)(void *)0), "", 0, 0 }\
|
||||
}
|
||||
#else
|
||||
#define EXPORT_CMPITF_STMT \
|
||||
{\
|
||||
{ ((RTS_VOID_FCTPTR)(void *)0), "", 0, 0 }\
|
||||
}
|
||||
#endif',`#define EXPORT_CMPITF_STMT {{ ((RTS_VOID_FCTPTR)(void *)0), "", 0, 0 }}')
|
||||
'dnl
|
||||
`ifdef(`__EXPORTS_CPLUSPLUS_ONLY', `
|
||||
#define EXPORT_CPP_STMT \
|
||||
{\
|
||||
ADD_EXPORTS_CPLUSPLUS_ONLY \
|
||||
}
|
||||
',`#define EXPORT_CPP_STMT')
|
||||
'dnl
|
||||
)
|
||||
|
||||
% -----------------------------
|
||||
% This function emits all init statements inside the macro INIT_STMT (one after another)
|
||||
% -----------------------------
|
||||
define(`ADD_INITS',`ifdef(`__INITS',`__INITS popdef(`__INITS') ADD_INITS')')
|
||||
define(`ADD_INIT_LOCALS',`ifdef(`__INIT_LOCALS',`__INIT_LOCALS popdef(`__INIT_LOCALS') ADD_INIT_LOCALS')')
|
||||
define(`ADD_EXITS',`ifdef(`__EXITS',`__EXITS popdef(`__EXITS') ADD_EXITS')')
|
||||
|
||||
% -----------------------------
|
||||
% Define the INIT_STMT macro.
|
||||
% -----------------------------
|
||||
define(`CREATE_INIT_STMT', dnl
|
||||
`ifdef(`__INITS',``
|
||||
#ifdef CPLUSPLUS
|
||||
#define INIT_STMT' \
|
||||
{\
|
||||
IBase *pIBase;\
|
||||
RTS_RESULT initResult;\
|
||||
if (pICmpLog == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)s_pfCMCreateInstance(CLASSID_CCmpLog, &initResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pICmpLog = (ICmpLog *)pIBase->QueryInterface(pIBase, ITFID_ICmpLog, &initResult); \
|
||||
pIBase->Release(pIBase); \
|
||||
} \
|
||||
} \
|
||||
if (pICMUtils == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)s_pfCMCreateInstance(CLASSID_CCMUtils, &initResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pICMUtils = (ICMUtils *)pIBase->QueryInterface(pIBase, ITFID_ICMUtils, &initResult); \
|
||||
pIBase->Release(pIBase); \
|
||||
} \
|
||||
} \
|
||||
ADD_INITS \
|
||||
}
|
||||
#define INIT_LOCALS_STMT \
|
||||
{\
|
||||
pICmpLog = NULL; \
|
||||
pICMUtils = NULL; \
|
||||
ADD_INIT_LOCALS \
|
||||
}
|
||||
#define EXIT_STMT \
|
||||
{\
|
||||
IBase *pIBase;\
|
||||
RTS_RESULT exitResult;\
|
||||
if (pICmpLog != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)pICmpLog->QueryInterface(pICmpLog, ITFID_IBase, &exitResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pIBase->Release(pIBase); \
|
||||
if (pIBase->Release(pIBase) == 0) /* The object will be deleted here! */ \
|
||||
pICmpLog = NULL; \
|
||||
} \
|
||||
} \
|
||||
if (pICMUtils != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)pICMUtils->QueryInterface(pICMUtils, ITFID_IBase, &exitResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pIBase->Release(pIBase); \
|
||||
if (pIBase->Release(pIBase) == 0) /* The object will be deleted here! */ \
|
||||
pICMUtils = NULL; \
|
||||
} \
|
||||
} \
|
||||
ADD_EXITS \
|
||||
}
|
||||
#else
|
||||
#define INIT_STMT
|
||||
#define INIT_LOCALS_STMT
|
||||
#define EXIT_STMT
|
||||
#endif
|
||||
',`#ifdef CPLUSPLUS
|
||||
#define INIT_STMT \
|
||||
{\
|
||||
IBase *pIBase;\
|
||||
RTS_RESULT initResult;\
|
||||
if (pICmpLog == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)s_pfCMCreateInstance(CLASSID_CCmpLog, &initResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pICmpLog = (ICmpLog *)pIBase->QueryInterface(pIBase, ITFID_ICmpLog, &initResult); \
|
||||
pIBase->Release(pIBase); \
|
||||
} \
|
||||
} \
|
||||
if (pICMUtils == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)s_pfCMCreateInstance(CLASSID_CCMUtils, &initResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pICMUtils = (ICMUtils *)pIBase->QueryInterface(pIBase, ITFID_ICMUtils, &initResult); \
|
||||
pIBase->Release(pIBase); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#define INIT_LOCALS_STMT \
|
||||
{\
|
||||
pICmpLog = NULL; \
|
||||
pICMUtils = NULL; \
|
||||
ADD_INIT_LOCALS \
|
||||
}
|
||||
#define EXIT_STMT \
|
||||
{\
|
||||
IBase *pIBase;\
|
||||
RTS_RESULT exitResult;\
|
||||
if (pICmpLog != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)pICmpLog->QueryInterface(pICmpLog, ITFID_IBase, &exitResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pIBase->Release(pIBase); \
|
||||
if (pIBase->Release(pIBase) == 0) /* The object will be deleted here! */ \
|
||||
pICmpLog = NULL; \
|
||||
} \
|
||||
} \
|
||||
if (pICMUtils != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)pICMUtils->QueryInterface(pICMUtils, ITFID_IBase, &exitResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pIBase->Release(pIBase); \
|
||||
if (pIBase->Release(pIBase) == 0) /* The object will be deleted here! */ \
|
||||
pICMUtils = NULL; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define INIT_STMT
|
||||
#define INIT_LOCALS_STMT
|
||||
#define EXIT_STMT
|
||||
#endif')
|
||||
')
|
||||
|
||||
|
||||
% -----------------------------
|
||||
% The next lines causes the CREATE_IMPORT_STMT, CREATE_EXPORT_STMT
|
||||
% and CREATE_INIT_STMT function to be called after all input has been read
|
||||
% -----------------------------
|
||||
m4wrap(`
|
||||
CREATE_EXPORT_STMT
|
||||
|
||||
#if defined(STATIC_LINK)
|
||||
#define EXPORT_STMT\
|
||||
{\
|
||||
RTS_RESULT ExpResult;\
|
||||
if (NULL == s_pfCMRegisterAPI)\
|
||||
return ERR_NOTINITIALIZED;\
|
||||
ExpResult = s_pfCMRegisterAPI(s_ExternalsTable, 0, 1, COMPONENT_ID);\
|
||||
if (ERR_OK != ExpResult)\
|
||||
return ExpResult;\
|
||||
}
|
||||
#else
|
||||
#define EXPORT_STMT\
|
||||
{\
|
||||
RTS_RESULT ExpResult;\
|
||||
if (NULL == s_pfCMRegisterAPI)\
|
||||
return ERR_NOTINITIALIZED;\
|
||||
ExpResult = s_pfCMRegisterAPI(s_ExternalsTable, 0, 1, COMPONENT_ID);\
|
||||
if (ERR_OK != ExpResult)\
|
||||
return ExpResult;\
|
||||
ExpResult = s_pfCMRegisterAPI(s_ItfTable, 0, 0, COMPONENT_ID);\
|
||||
if (ERR_OK != ExpResult)\
|
||||
return ExpResult;\
|
||||
}
|
||||
#endif
|
||||
|
||||
')
|
||||
m4wrap(`
|
||||
CREATE_IMPORT_STMT
|
||||
')
|
||||
m4wrap(`
|
||||
CREATE_INIT_STMT
|
||||
')
|
||||
|
||||
|
||||
% -----------------------------
|
||||
% Generate an "#include " directive,
|
||||
% replacing the extension ".m4" with ".h"
|
||||
% -----------------------------
|
||||
define(`GET_INCLUDE_FILE', `ifelse(`-1',regexp(`$1',`\.m4$'),`error(`m4:'__file__`('__line__`):The first parameter "'$1`" is not a .m4 file')',dnl
|
||||
`/**
|
||||
* \file 'patsubst(`$1',`\.m4$',`\.h')`
|
||||
*/')')
|
||||
|
||||
define(`GEN_INCLUDE', dnl
|
||||
`ifelse(`-1',regexp(`$1',`\.m4$'), dnl
|
||||
`error(`m4:'__file__`('__line__`):The first parameter "'$1`" is not a .m4 file
|
||||
')',dnl
|
||||
$1,`CmpLogItf.m4', `/*Obsolete include: CmpLogItf.m4*/',dnl
|
||||
$1,`CMUtilsItf.m4', `/*Obsolete include: CMUtilsItf.m4*/',dnl
|
||||
`#include "patsubst(`$1',`\.m4$',`\.h')"')')
|
||||
|
||||
define(`GEN_INIT_STMT', `pushdef(`__INITS',ifelse($1,`CMUtils',`/*Obsolete include CMUtils*/ \
|
||||
',
|
||||
$1,`CmpLog',`/*Obsolete include CmpLog*/ \
|
||||
',
|
||||
`if (pI$1 == NULL && s_pfCMCreateInstance != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)s_pfCMCreateInstance(CLASSID_C$1, &initResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pI$1 = (I$1 *)pIBase->QueryInterface(pIBase, ITFID_I$1, &initResult); \
|
||||
pIBase->Release(pIBase); \
|
||||
} \
|
||||
} \
|
||||
'))')
|
||||
|
||||
define(`GEN_INIT_LOCALS_STMT', `pushdef(`__INIT_LOCALS',`ifelse($1,`CMUtils',`/*Obsolete include CMUtils*/ \
|
||||
',
|
||||
$1,`CmpLog',`/*Obsolete include CmpLog*/ \
|
||||
',
|
||||
`pI$1 = NULL; \
|
||||
')')')
|
||||
|
||||
define(`GEN_EXIT_STMT', `pushdef(`__EXITS',`ifelse($1,`CMUtils',`/*Obsolete include CMUtils*/ \
|
||||
',
|
||||
$1,`CmpLog',`/*Obsolete include CmpLog*/ \
|
||||
',
|
||||
`if (pI$1 != NULL) \
|
||||
{ \
|
||||
pIBase = (IBase *)pI$1->QueryInterface(pI$1, ITFID_IBase, &exitResult); \
|
||||
if (pIBase != NULL) \
|
||||
{ \
|
||||
pIBase->Release(pIBase); \
|
||||
if (pIBase->Release(pIBase) == 0) /* The object will be deleted here! */ \
|
||||
pI$1 = NULL; \
|
||||
} \
|
||||
} \
|
||||
')')')
|
||||
|
||||
define(`GEN_USED_INTERFACES', dnl
|
||||
`ifelse(`-1',regexp(`$1',`\.m4$'), dnl
|
||||
`error(`m4:'__file__`('__line__`):The first parameter "'$1`" is not a .m4 file
|
||||
')',dnl
|
||||
`GEN_INCLUDE($1)'dnl
|
||||
`GEN_INIT_STMT(`'patsubst(`$1',`\Itf.m4$',`'))'dnl
|
||||
`GEN_INIT_LOCALS_STMT(`'patsubst(`$1',`\Itf.m4$',`'))'dnl
|
||||
`GEN_EXIT_STMT(`'patsubst(`$1',`\Itf.m4$',`'))')dnl
|
||||
')
|
||||
|
||||
% -----------------------------
|
||||
% All variations of DEF_*_API
|
||||
% Depending on the Variable DEF_CPP,
|
||||
% we are adding them to __EXPORTS or __EXPORTS_CPP.
|
||||
% -----------------------------
|
||||
define(`PUSH_ITF', dnl
|
||||
`ifdef(`DEF_CPP', dnl
|
||||
`pushdef(`__EXPORTS_CPLUSPLUS_ONLY',` \
|
||||
if (ERR_OK != EXP_`'_COMPONENT_NAME`'$3) \
|
||||
{\
|
||||
if (CHK_LogAdd)\
|
||||
(void)CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_ERROR, ERR_FAILED, 0, "Export of ApiFunction [$3] failed\n"); \
|
||||
return ERR_FAILED;\
|
||||
}')'
|
||||
, dnl
|
||||
`pushdef(`__EXPORTS_EXTREF',`ifelse(`$5',1,`ifelse(`$8',1,`', `{ (RTS_VOID_FCTPTR)$3, "$3", ifelse(eval($#>5),1,$6,0), ifelse(eval($#>6),1,$7,0) },\
|
||||
')',`')')' dnl
|
||||
`pushdef(`__EXPORTS_EXTREF2',`ifelse(`$8',1,`{ (RTS_VOID_FCTPTR)$3, "$3", $6, $7 }, \
|
||||
',`')')' dnl
|
||||
`pushdef(`__EXPORTS',`ifelse(`$5',1,`',`{ (RTS_VOID_FCTPTR)$3, "$3", 0, 0 },\
|
||||
')')' dnl
|
||||
)' dnl
|
||||
)
|
||||
|
||||
define(`PUSH_CLASS_ITF', dnl
|
||||
`ifdef(`DEF_CPP', dnl
|
||||
`pushdef(`__EXPORTS_CPLUSPLUS_ONLY',` \
|
||||
if (ERR_OK != EXP_`'_COMPONENT_NAME`'$3) \
|
||||
{\
|
||||
if (CHK_LogAdd)\
|
||||
(void)CAL_LogAdd(STD_LOGGER, COMPONENT_ID, LOG_ERROR, ERR_FAILED, 0, "Export of ApiFunction [$3] failed\n"); \
|
||||
return ERR_FAILED;\
|
||||
}')'
|
||||
, dnl
|
||||
`pushdef(`__EXPORTS_EXTREF',`ifelse(`$5',1,`ifelse(`$8',1,`',`{ (RTS_VOID_FCTPTR)$3, "$3",ifelse(eval($#>5),1,$6,0),ifelse(eval($#>6),1,$7,0)},\
|
||||
')',`')')' dnl
|
||||
`pushdef(`__EXPORTS_EXTREF2',`ifelse(`$8',1,`{ (RTS_VOID_FCTPTR)$3, "$3", $6, $7 }, \
|
||||
',`')')' dnl
|
||||
`pushdef(`__EXPORTS',`')' dnl
|
||||
)' dnl
|
||||
)
|
||||
|
||||
|
||||
|
||||
define(`DEF_API', dnl
|
||||
`PUSH_ITF($@)' dnl
|
||||
)
|
||||
|
||||
define(`DEF_STATIC_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
)
|
||||
|
||||
define(`DEF_CREATEITF_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_DELETEITF_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_HANDLEITF_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_HANDLEITF_API2',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_HANDLEITF_API_OWNCPP',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_CREATECLASSITF_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_CREATECLASSITF2_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_PRODUCECLASSITF_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_PRODUCECLASSITF_API_OWNCPP',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_DELETECLASSITF_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_DELETECLASSITF2_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_CLASSITF_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_RETURNHANDLECLASSITF_API',
|
||||
`PUSH_CLASS_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_HANDLEITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_STATICITF_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) static $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_ITF_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_ITF_API_OWNCPP',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_ITF_API2',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
define(`DEF_ITF_GLOBAL_API',
|
||||
`PUSH_ITF($@)' dnl
|
||||
`divert(DIVERT_CLASSMEMBERS) virtual $1 $2 `I'$3(_CONCAT(`_MAKE_ITF_PARAMLIST',_TRIM(`$4')));
|
||||
divert(-1)'
|
||||
)
|
||||
|
||||
|
||||
|
||||
define(`SET_INTERFACE_NAME',`
|
||||
ifdef(`_IN_IMPLEMENT',`
|
||||
pushdef(`_INTERFACE_LIST', `$1')
|
||||
pushdef(`_INTERFACECAST_LIST',`
|
||||
else if (iid == ITFID_`I'$1)
|
||||
pItf = dynamic_cast<`I'$1 *>(this);')',
|
||||
`ifelse($1,`CMUtils',`divert(DIVERT_USE)\
|
||||
/*obsolete entry ITF_$1*/ dnl divert(-1)',
|
||||
$1,`CmpLog',`divert(DIVERT_USE)\
|
||||
/*obsolete entry ITF_$1*/ dnl divert(-1)',
|
||||
`divert(DIVERT_USE)\
|
||||
`ITF_'`$1'dnl')
|
||||
ifelse($1,`CMUtils',`divert(DIVERT_USEIMPORT)\
|
||||
/*obsolete entry ITF_$1*/ dnl divert(-1)',
|
||||
$1,`CmpLog',`divert(DIVERT_USEIMPORT)\
|
||||
/*obsolete entry ITF_$1*/ dnl divert(-1)',
|
||||
`divert(DIVERT_USEIMPORT)\
|
||||
`ITF_'`$1'dnl')
|
||||
ifelse($1,`CMUtils',`divert(DIVERT_USEEXTERN)\
|
||||
/*obsolete entry EXTITF_$1*/ dnl divert(-1)',
|
||||
$1,`CmpLog',`divert(DIVERT_USEEXTERN)\
|
||||
/*obsolete entry EXTITF_$1*/ dnl divert(-1)',
|
||||
`divert(DIVERT_USEEXTERN)\
|
||||
`EXTITF_'`$1'dnl')
|
||||
divert(-1)')
|
||||
')
|
||||
|
||||
define(`WRITE_INTERFACE_LIST2',`ifdef(`_INTERFACE_LIST',`, public `I'_INTERFACE_LIST popdef(`_INTERFACE_LIST')WRITE_INTERFACE_LIST2')')
|
||||
define(`WRITE_INTERFACE_LIST',`ifdef(`_INTERFACE_LIST',`define(`_FIRST_INTERFACE_NAME',_INTERFACE_LIST)public `I'_INTERFACE_LIST popdef(`_INTERFACE_LIST')WRITE_INTERFACE_LIST2')')
|
||||
|
||||
define(`WRITE_INTERFACE_CASTS',`ifdef(`_INTERFACECAST_LIST',`_INTERFACECAST_LIST popdef(`_INTERFACECAST_LIST')WRITE_INTERFACE_CASTS')')
|
||||
|
||||
|
||||
define(`TASK',`#ifndef RTS_TASKNAME_`'_UPPERCASE($1)
|
||||
#define RTS_TASKNAME_`'_UPPERCASE($1) "$1"
|
||||
#endif
|
||||
#ifndef RTS_TASKPRIO_`'_UPPERCASE($1)
|
||||
#define RTS_TASKPRIO_`'_UPPERCASE($1) $2
|
||||
#endif
|
||||
ifelse($3,`',`', `#ifndef RTS_TASKGROUP_`'_UPPERCASE($1)
|
||||
#define RTS_TASKGROUP_`'_UPPERCASE($1) $3
|
||||
#endif')
|
||||
')
|
||||
|
||||
define(`TASKPREFIX',`#ifndef RTS_TASKPREFIX_`'_UPPERCASE($1)
|
||||
#define RTS_TASKPREFIX_`'_UPPERCASE($1) "$1"
|
||||
#endif
|
||||
#ifndef RTS_TASKPRIO_`'_UPPERCASE($1)
|
||||
#define RTS_TASKPRIO_`'_UPPERCASE($1) $2
|
||||
#endif
|
||||
ifelse($3,`',`', `#ifndef RTS_TASKGROUP_`'_UPPERCASE($1)
|
||||
#define RTS_TASKGROUP_`'_UPPERCASE($1) $3
|
||||
#endif')
|
||||
')
|
||||
|
||||
define(`TASKPLACEHOLDER',`#ifndef RTS_TASKPLACEHOLDER_`'_UPPERCASE($1)
|
||||
#define RTS_TASKPLACEHOLDER_`'_UPPERCASE($1) ""
|
||||
#endif
|
||||
#ifndef RTS_TASKPRIO_`'_UPPERCASE($1)
|
||||
#define RTS_TASKPRIO_`'_UPPERCASE($1) $2
|
||||
#endif
|
||||
ifelse($3,`',`', `#ifndef RTS_TASKGROUP_`'_UPPERCASE($1)
|
||||
#define RTS_TASKGROUP_`'_UPPERCASE($1) $3
|
||||
#endif')
|
||||
')
|
||||
|
||||
|
||||
% -----------------------------
|
||||
% Get all interfaces, which are implemented by this component.
|
||||
% Differentiate between C++ and C Interfaces.
|
||||
% -----------------------------
|
||||
define(`DO_IMPLEMENT_ITF',`
|
||||
GET_INCLUDE_FILE($1)
|
||||
GEN_INCLUDE($1)
|
||||
ifelse(`$#',1,`',`DO_IMPLEMENT_ITF(shift($@))')
|
||||
divert(-1)
|
||||
include($1)
|
||||
divert
|
||||
')
|
||||
|
||||
|
||||
define(`IMPLEMENT_QUERY_INTERFACE',`define(`QUERY_INTERFACE', `$1')')
|
||||
|
||||
define(`IMPLEMENT_ITF',dnl
|
||||
`undefine(`DEF_CPP')'dnl
|
||||
`IMPLEMENT_ITF_AS(``C'_COMPONENT_NAME', $@)'
|
||||
)
|
||||
define(`IMPLEMENT_CPP_ITF',
|
||||
`define(`DEF_CPP')'
|
||||
`undefine(`_INTERFACE_LIST')undefine(`_INTERFACECAST_LIST')undefine(`_FIRST_INTERFACE_NAME')define(`_IN_IMPLEMENT')define(`_INTERFACE_LIST_INIT')'
|
||||
`DO_IMPLEMENT_ITF($@)'
|
||||
)
|
||||
define(`IMPLEMENT_ITF_AS',
|
||||
`ifdef(`_INTERFACE_LIST_INIT', `',
|
||||
`undefine(`_INTERFACE_LIST')undefine(`_INTERFACECAST_LIST')undefine(`_FIRST_INTERFACE_NAME')'
|
||||
)'
|
||||
`define(`_IN_IMPLEMENT')define(`_INTERFACE_LIST_INIT')'
|
||||
`
|
||||
DO_IMPLEMENT_ITF(shift($@))
|
||||
divert(DIVERT_CLASSDEF)
|
||||
class $1 : WRITE_INTERFACE_LIST
|
||||
{
|
||||
public:
|
||||
$1`() : h'_COMPONENT_NAME`'(RTS_INVALID_HANDLE), iRefCount(0)
|
||||
{
|
||||
}
|
||||
virtual ~$1`()'
|
||||
{
|
||||
}
|
||||
virtual unsigned long AddRef(IBase *pIBase = NULL)
|
||||
{
|
||||
iRefCount++;
|
||||
return iRefCount;
|
||||
}
|
||||
virtual unsigned long Release(IBase *pIBase = NULL)
|
||||
{
|
||||
iRefCount--;
|
||||
if (iRefCount == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return iRefCount;
|
||||
}
|
||||
|
||||
ifdef(`QUERY_INTERFACE', `QUERY_INTERFACE', `
|
||||
virtual void* QueryInterface(IBase *pIBase, ITFID iid, RTS_RESULT *pResult)
|
||||
{
|
||||
void *pItf;
|
||||
if (iid == ITFID_IBase)
|
||||
pItf = dynamic_cast<IBase *>((`I'_FIRST_INTERFACE_NAME *)this);dnl
|
||||
WRITE_INTERFACE_CASTS
|
||||
else
|
||||
{
|
||||
if (pResult != NULL)
|
||||
*pResult = ERR_NOTIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
if (pResult != (RTS_RESULT *)1)
|
||||
(reinterpret_cast<IBase *>(pItf))->AddRef();
|
||||
if (pResult != NULL && pResult != (RTS_RESULT *)1)
|
||||
*pResult = ERR_OK;
|
||||
return pItf;
|
||||
}')
|
||||
divert(DIVERT_ENDCLASSDEF)
|
||||
public:
|
||||
RTS_HANDLE h`'_COMPONENT_NAME;
|
||||
int iRefCount;
|
||||
};
|
||||
divert(-1)
|
||||
define(`DIVERT_CLASSDEF',eval(DIVERT_CLASSDEF+3))
|
||||
define(`DIVERT_CLASSMEMBERS',eval(DIVERT_CLASSMEMBERS+3))
|
||||
define(`DIVERT_ENDCLASSDEF',eval(DIVERT_ENDCLASSDEF+3))
|
||||
undefine(`_IN_IMPLEMENT')
|
||||
divert
|
||||
')
|
||||
|
||||
%define(`IMPLEMENT_ITF', `
|
||||
%divert(-1)
|
||||
%include($1)
|
||||
%divert')
|
||||
|
||||
define(`GENERATE_ITF_MACRO', `divert(DIVERT_USE)\
|
||||
`ITF_'`$1' dnl
|
||||
divert(-1)')
|
||||
|
||||
define(`USE_ITF', `GEN_USED_INTERFACES($1)
|
||||
divert(-1)
|
||||
pushdef(`DEF_API',`')
|
||||
pushdef(`DEF_STATIC_API',`')
|
||||
pushdef(`DEF_CREATEITF_API',`')
|
||||
pushdef(`DEF_DELETEITF_API',`')
|
||||
pushdef(`DEF_HANDLEITF_API',`')
|
||||
pushdef(`DEF_HANDLEITF_API2',`')
|
||||
pushdef(`DEF_HANDLEITF_API_OWNCPP',`')
|
||||
pushdef(`DEF_CREATECLASSITF_API',`')
|
||||
pushdef(`DEF_CREATECLASSITF2_API',`')
|
||||
pushdef(`DEF_PRODUCECLASSITF_API',`')
|
||||
pushdef(`DEF_PRODUCECLASSITF_API_OWNCPP',`')
|
||||
pushdef(`DEF_DELETECLASSITF_API',`')
|
||||
pushdef(`DEF_DELETECLASSITF2_API',`')
|
||||
pushdef(`DEF_CLASSITF_API',`')
|
||||
pushdef(`DEF_RETURNHANDLECLASSITF_API',`')
|
||||
pushdef(`DEF_STATICITF_API',`')
|
||||
pushdef(`DEF_ITF_API',`')
|
||||
pushdef(`DEF_ITF_API_OWNCPP',`')
|
||||
pushdef(`DEF_ITF_API2',`')
|
||||
pushdef(`DEF_ITF_GLOBAL_API',`')
|
||||
include($1)
|
||||
popdef(`DEF_API')
|
||||
popdef(`DEF_STATIC_API')
|
||||
popdef(`DEF_CREATEITF_API')
|
||||
popdef(`DEF_DELETEITF_API')
|
||||
popdef(`DEF_HANDLEITF_API')
|
||||
popdef(`DEF_HANDLEITF_API_OWNCPP')
|
||||
popdef(`DEF_HANDLEITF_API2')
|
||||
popdef(`DEF_CREATECLASSITF_API')
|
||||
popdef(`DEF_CREATECLASSITF2_API')
|
||||
popdef(`DEF_PRODUCECLASSITF_API')
|
||||
popdef(`DEF_PRODUCECLASSITF_API_OWNCPP')
|
||||
popdef(`DEF_DELETECLASSITF_API')
|
||||
popdef(`DEF_DELETECLASSITF2_API')
|
||||
popdef(`DEF_RETURNHANDLECLASSITF_API')
|
||||
popdef(`DEF_CLASSITF_API')
|
||||
popdef(`DEF_STATICITF_API')
|
||||
popdef(`DEF_ITF_API2')
|
||||
popdef(`DEF_ITF_API')
|
||||
popdef(`DEF_ITF_API_OWNCPP')
|
||||
popdef(`DEF_ITF_GLOBAL_API')
|
||||
divert
|
||||
')
|
||||
|
||||
define(`DOUSE', `divert(DIVERT_USE) \
|
||||
ifelse($1,`CMUtlMemCpy',`/*obsolete USE_$1*/',
|
||||
$1,`LogAdd',`/*obsolete USE_$1*/',
|
||||
USE_$1) dnl
|
||||
divert(DIVERT_USEIMPORT) \
|
||||
ifelse($1,`CMUtlMemCpy',`/*obsolete USE_$1*/',
|
||||
$1,`LogAdd',`/*obsolete USE_$1*/',
|
||||
USE_$1) dnl
|
||||
divert(DIVERT_USEEXTERN) \
|
||||
ifelse($1,`CMUtlMemCpy',`/*obsolete USE_$1*/',
|
||||
$1,`LogAdd',`/*obsolete EXT_$1*/',
|
||||
EXT_$1) dnl
|
||||
divert')
|
||||
|
||||
|
||||
define(`DOIMPORT_REQ', `pushdef(`__IMPORTS',`ifelse($1,`LogAdd', `/*Obsolete required include LogAdd*/ \
|
||||
',dnl
|
||||
$1,`CMUtlMemCpy', `/*Obsolete required include CMUtlMemCpy*/ \
|
||||
',
|
||||
`if (ERR_OK == importResult ) importResult = GET_$1(0);\
|
||||
')')')
|
||||
|
||||
|
||||
define(`DOIMPORT_OPT', `pushdef(`__IMPORTS',`ifelse($1,`LogAdd', `/*Obsolete optional include LogAdd*/ \
|
||||
',dnl
|
||||
$1,`CMUtlMemCpy', `/*Obsolete optional include CMUtlMemCpy*/ \
|
||||
',
|
||||
`if (ERR_OK == importResult ) TempResult = GET_$1(CM_IMPORT_OPTIONAL_FUNCTION);\
|
||||
')')')
|
||||
|
||||
|
||||
|
||||
define(`REQUIRED_IMPORTS', dnl
|
||||
`ifelse($1,`', `', dnl
|
||||
`_FOREACH(`DOIMPORT_REQ', $@)dnl
|
||||
_FOREACH(`DOUSE', $@)dnl
|
||||
')
|
||||
')
|
||||
|
||||
define(`OPTIONAL_IMPORTS', dnl
|
||||
`ifelse($1,`', `', dnl
|
||||
`_FOREACH(`DOIMPORT_OPT', $@) dnl
|
||||
_FOREACH(`DOUSE', $@) dnl
|
||||
')
|
||||
')
|
||||
changecom(`/*', `*/')
|
||||
divert
|
||||
@@ -0,0 +1,113 @@
|
||||
divert(-1)
|
||||
changecom(`%')
|
||||
%
|
||||
% Copyright: Copyright CODESYS Development GmbH
|
||||
%
|
||||
|
||||
define(`_CONCAT',`ifelse($#,0,`',$#,1,`$1',$#,2,`$1$2',`_CONCAT(`$1$2',`_CONCAT(shift(shift($@)))')')')
|
||||
define(`_UPPERCASE', `translit($1, `a-z', `A-Z')')
|
||||
define(`_TRIM',`regexp(`$1',`^[ ]*\(.*[^ ]\)[ ]*$',`\1')')
|
||||
define(`_TRIMCMPPREFIX',`regexp(`$1',`...\(.*\)$',`\1')')
|
||||
define(`_TRIMPOINTERPARAM', `ifelse(regexp(`$1',`[^,]\*',`RTS_HANDLE'),-1,0,1)')
|
||||
define(`_TRIMVARPARAMLIST', `ifelse(regexp(`$1',`\.\.\.'),-1,0,1)')
|
||||
|
||||
define(`_FUN_PTR', _FUN_PTR1(`_UPPERCASE(`$1')'))
|
||||
define(`_FUN_PTR_IEC', _FUN_PTR1(`_UPPERCASE(`$1')'_IEC))
|
||||
define(`_FUN_PTR1', `PF'$1)
|
||||
|
||||
define( _CHKSUM, 0)
|
||||
|
||||
define(`_EXTRACTFIRSTPARAMTYPE',`_EXTRACTTYPE(_EXTRACTPARAMS(`$1'))')
|
||||
define(`_EXTRACTTYPE',`regexp(`$1',`\([\w_]*[^ ]*\)',`\1')')
|
||||
define(`_EXTRACTFIRSTPARAMTYPEPOINTER',`_EXTRACTTYPEPOINTER(_EXTRACTPARAMS(`$1'))')
|
||||
define(`_EXTRACTTYPEPOINTER',`regexp(`$1',`\([\*]\)',`\1')')
|
||||
define(`_EXTRACTFIRSTPARAMTYPERTS',`_EXTRACTTYPERTS(_EXTRACTPARAMS(`$1'))')
|
||||
define(`_EXTRACTTYPERTS',`regexp(`$1',`\(RTS_\)',`\1')')
|
||||
|
||||
define(`_EXTRACTPARAMS',`regexp(`$1',`^[ ]*(\(.*\))[ ]*$',`\1')')
|
||||
define(`_EXTRACTPARAMNAME',`regexp(`$1',`\([a-zA-Z0-9_]+\)$',`\1')')
|
||||
define(`_HAS_VARIABLEPARAMETER',`regexp(`$1',`\.\.\.')')
|
||||
define(`_EXTRACT_VARIABLEPARAMETER_FORMAT',`regexp(`$1',` \*?\([a-zA-Z0-9_]+\), \.\.\.',`\1')')
|
||||
|
||||
%
|
||||
% Extract the parameter out of a parameter list.
|
||||
%
|
||||
% _EXTRACT_PARAM_LIST(`(int nCount, char *pBuf)') => `nCount,pBuf'
|
||||
% _EXTRACT_PARAM_LIST(`(void)') => `'
|
||||
%
|
||||
define(_EXTRACT_PARAM_LIST_RECURSIVE,`ifelse($#,1,`_EXTRACTPARAMNAME(`$1')',`_EXTRACTPARAMNAME(`$1')`',_EXTRACT_PARAM_LIST_RECURSIVE(shift($@))')')
|
||||
define(_EXTRACT_PARAM_LIST_,`ifelse(_TRIM(`$1'),`',`',_TRIM(`$1'),`void',`',`_EXTRACT_PARAM_LIST_RECURSIVE($@)')')
|
||||
define(_EXTRACT_PARAM_LIST,`_EXTRACT_PARAM_LIST_(_EXTRACTPARAMS(`$1'))')
|
||||
|
||||
define(_EXTRACT_PARAM_LIST_HANDLE_RECURSIVE,`ifelse($#,1,`,_EXTRACTPARAMNAME(`$1')',`,_EXTRACTPARAMNAME(`$1')`'_EXTRACT_PARAM_LIST_HANDLE_RECURSIVE(shift($@))')')
|
||||
define(_EXTRACT_PARAM_LIST_HANDLE_,`ifelse(_TRIM(`$1'),`',`',_TRIM(`$1'),`void',`',`_EXTRACT_PARAM_LIST_HANDLE_RECURSIVE($@)')')
|
||||
define(_EXTRACT_PARAM_LIST_HANDLE,`_EXTRACT_PARAM_LIST_HANDLE_(shift(_EXTRACTPARAMS(`$1')))')
|
||||
|
||||
%
|
||||
% Creates a parameter list for a macro call "(p1, p2, p3)", with one parameter for each parameter
|
||||
% in the c parameterlist provided as parameter. If the provided parameterlist contains only `void'
|
||||
% then it is treated as if it was empty.
|
||||
%
|
||||
% _MAKE_DUMMYPARAMLIST(`(int nCount, char *pBuf)') => `p0,p1'
|
||||
% _MAKE_DUMMYPARAMLIST(`(void)') => `'
|
||||
%
|
||||
define(_MAKE_DUMMYPARAMLIST1,`ifelse($#,1,`',$#,2,`p$1',`p$1,_MAKE_DUMMYPARAMLIST1(incr($1),shift(shift($@)))')')
|
||||
define(_MAKE_DUMMYPARAMLIST_,`ifelse(_TRIM(`$1'),`',`',_TRIM(`$1'),`void',`',`_MAKE_DUMMYPARAMLIST1(0,$@)')')
|
||||
define(_MAKE_DUMMYPARAMLIST_WITHVOID_,`ifelse(_TRIM(`$1'),`',`',`_MAKE_DUMMYPARAMLIST1(0,$@)')')
|
||||
define(_MAKE_DUMMYPARAMLIST,`_MAKE_DUMMYPARAMLIST_(_EXTRACTPARAMS(`$1'))')
|
||||
|
||||
%
|
||||
% Creates a parameter list for a macro call "(p1, p2, p3)", with one parameter for each parameter
|
||||
% in the c parameterlist provided as parameter. If the provided parameterlist contains only `void'
|
||||
% then it is treated as if it had exactly one parameter.
|
||||
%
|
||||
% _MAKE_DUMMYPARAMLIST(`(int nCount, char *pBuf)') => `p0,p1'
|
||||
% _MAKE_DUMMYPARAMLIST(`(void)') => `p0'
|
||||
%
|
||||
define(_MAKE_DUMMYPARAMLIST_WITHVOID,`_MAKE_DUMMYPARAMLIST_WITHVOID_(_EXTRACTPARAMS(`$1'))')
|
||||
|
||||
%
|
||||
% Same as _MAKE_DUMMYPARAMLIST, but drops the first parameter
|
||||
%
|
||||
% _MAKE_HANDLE_DUMMYPARAMLIST(`(RTS_HANDLE, hHandle, int nCount, char *pBuf)') => `p1,p2'
|
||||
%
|
||||
define(_MAKE_HANDLE_DUMMYPARAMLIST,`shift(_MAKE_DUMMYPARAMLIST(`$1'))')
|
||||
|
||||
%
|
||||
% Same as _MAKE_DUMMYPARAMLIST, but drops the first n parameter
|
||||
%
|
||||
% _MAKE_HANDLE_DUMMYPARAMLIST2(`(RTS_HANDLE hHandle, int nCount, char *pBuf, int nValue)', 2) => `p2,p3'
|
||||
%
|
||||
define(nshift, `ifelse($2, 0, `$1', `nshift(`shift($1)', decr($2))')')
|
||||
define(_MAKE_HANDLE_DUMMYPARAMLIST2,`nshift(`_MAKE_DUMMYPARAMLIST(`$1')', $2)')
|
||||
|
||||
|
||||
define(_MAKE_PARAMLIST2,`ifelse(_TRIM($@),`',`',`, $1`'_MAKE_PARAMLIST2(shift($@))')')
|
||||
define(_MAKE_PARAMLIST1,`ifelse(_TRIM($@),`',`',`$1`'_MAKE_PARAMLIST2(shift($@))')')
|
||||
define(_MAKE_HANDLEITF_PARAMLIST,`ifelse(_TRIM(shift($@)),`',`void',_TRIM(shift($@)),`void',`void',`_MAKE_PARAMLIST1(shift($@))')')
|
||||
define(_MAKE_ITF_PARAMLIST, `ifelse(_TRIM($@),`',`void',_TRIM($@),`void',`void',`_MAKE_PARAMLIST1($@)')')
|
||||
define(_MAKE_CREATEITF_PARAMLIST,`ifelse(_TRIM($@),`',`void',_TRIM($@),`void',`void',`_MAKE_PARAMLIST1($@)')')
|
||||
|
||||
%
|
||||
% Ieration over some string elements
|
||||
%
|
||||
define(`_FOREACH', `ifelse(1,$#,` ',`$1($2)
|
||||
ifelse(2,$#, ,`_FOREACH(`$1',shift(shift($@)))')')')
|
||||
|
||||
%
|
||||
% Split component version number
|
||||
%
|
||||
% Example:
|
||||
% $1 = "0x03020104"
|
||||
% _VERSION_MAJOR => 3
|
||||
% _VERSION_SUB0 => 2
|
||||
% _VERSION_SUB1 => 1
|
||||
% _VERSION_SUB2 => 4
|
||||
%
|
||||
define(`_TRIMLEFT_ZERO', `regexp(`$1', `^0*\(.+\)', `\1')')
|
||||
define(`_VERSION_MAJOR',`_TRIMLEFT_ZERO(regexp(`$1',`^0x\([0-9a-fA-F][0-9a-fA-F]\)', `eval(0x\1)'))')
|
||||
define(`_VERSION_SUB0',`_TRIMLEFT_ZERO(regexp(`$1',`^0x[0-9a-fA-F][0-9a-fA-F]\([0-9a-fA-F][0-9a-fA-F]\)', `eval(0x\1)'))')
|
||||
define(`_VERSION_SUB1',`_TRIMLEFT_ZERO(regexp(`$1',`^0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\([0-9a-fA-F][0-9a-fA-F]\)', `eval(0x\1)'))')
|
||||
define(`_VERSION_SUB2',`_TRIMLEFT_ZERO(regexp(`$1',`^0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\([0-9a-fA-F][0-9a-fA-F]\)', `eval(0x\1)'))')
|
||||
|
||||
divert`'dnl
|
||||
@@ -0,0 +1,183 @@
|
||||
##############################################################################
|
||||
# Copyright: Copyright CODESYS Development GmbH
|
||||
# Program: Extension API for the Linux SL products
|
||||
##############################################################################
|
||||
|
||||
ifeq ($(dir $(lastword $(MAKEFILE_LIST))), ./)
|
||||
#
|
||||
# MAKEFILE is used wrong! Never call it from this folder directly
|
||||
#
|
||||
.PHONY:help
|
||||
help:
|
||||
@echo "**********************"
|
||||
@echo "Dont work inside this folder! Please go to your library folder and call this makefile e.g.:"
|
||||
@echo "make -f ../sdk/makefile newproject"
|
||||
@echo
|
||||
@echo "**********************"
|
||||
|
||||
.PHONY:all
|
||||
all: help
|
||||
|
||||
.PHONY:newproject
|
||||
newproject: help
|
||||
|
||||
.PHONY:makefile
|
||||
makefile: help
|
||||
|
||||
else
|
||||
#
|
||||
# NORMAL RULES
|
||||
#
|
||||
|
||||
# get some info from generated files
|
||||
ITFM4 = $(wildcard *Itf.m4)
|
||||
CSRC = $(wildcard *.c)
|
||||
CMPBASENAME=$(CSRC:.c=)
|
||||
|
||||
# set some variables
|
||||
OUTDIR=./out
|
||||
ITF = $(basename ${ITFM4})
|
||||
TEMPLATEDEP = $(SDKDIR)/m4/TemplateDep.m4
|
||||
DEP = ${CMPBASENAME}Dep
|
||||
|
||||
|
||||
# set name of shared object
|
||||
SONAME= lib${CMPBASENAME}.so
|
||||
|
||||
# set sources of component
|
||||
SRC += ${CSRC} CmpFrame.c
|
||||
|
||||
# objects: all sources
|
||||
OBJS = $(addprefix ${OUTDIR}/,$(SRC:.c=.o))
|
||||
|
||||
# set default includes
|
||||
INCLUDES += -I${SDKDIR}/include/ -I${OUTDIR}/ -I.
|
||||
CFLAGS += -fPIC -g -O0 -Wall -Wextra -Wno-unused
|
||||
CFLAGS += -DDEP_H=\"${DEP}.h\"
|
||||
|
||||
# set a vendorID
|
||||
CMPVENDORID=0xFFFF
|
||||
|
||||
vpath %.m4 ${SDKDIR}/cmpstub/
|
||||
vpath %.c ${SDKDIR}/src/
|
||||
|
||||
.PHONY:help
|
||||
help:
|
||||
@echo "**********************"
|
||||
@echo "help / usage / available make targets:"
|
||||
@echo "-all : just do everything needed"
|
||||
@echo "-clean : cleanup all generated files"
|
||||
@echo "-newproject : create a new project"
|
||||
@echo "-showenv : show intern variables (for debugging)"
|
||||
@echo "**********************"
|
||||
|
||||
|
||||
.PHONY:newproject
|
||||
newproject: makefile
|
||||
|
||||
.PHONY:all
|
||||
all: ${OUTDIR}/$(SONAME)
|
||||
|
||||
SDK_BASE=$(dir $(lastword $(MAKEFILE_LIST)))
|
||||
|
||||
.PHONY:showenv
|
||||
showenv:
|
||||
@echo "**********************"
|
||||
@echo "ITFM4: ${ITFM4}"
|
||||
@echo "CSRC: ${CSRC}"
|
||||
@echo "SONAME: ${SONAME}"
|
||||
@echo "ITF: ${ITF}"
|
||||
@echo "DEP: ${DEP}"
|
||||
@echo "OBJS: ${OBJS}"
|
||||
@echo "CC: $(CC)"
|
||||
@echo "CFLAGS: ${CFLAGS}"
|
||||
@echo "SDKDIR: ${SDKDIR}"
|
||||
@echo "CMPBASENAME: ${CMPBASENAME}"
|
||||
@echo "MAKEFILE_LIST: $(MAKEFILE_LIST)"
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
# check if there are whitespaces in the SDK BASE DIR
|
||||
# this causes horrible things in make, so we detect/avoid it directly at creating a new project
|
||||
ifeq (1,$(words $(MAKEFILE_LIST)))
|
||||
makefile:
|
||||
@echo "**********************"
|
||||
@echo "creating makefile for your project "
|
||||
cp ${SDK_BASE}/makefile_template $@
|
||||
@echo "# include of the SDK makefiles" >> $@
|
||||
@echo "SDKDIR="$(abspath ${SDK_BASE}) >> $@
|
||||
@echo 'include $${SDKDIR}/makefile' >> $@
|
||||
@echo "" >> $@
|
||||
@echo "now check your makefile here"
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
else
|
||||
makefile:
|
||||
@echo "**********************"
|
||||
@echo "creating makefile for your project FAILED:"
|
||||
@echo "there are whitespaces in the SDK path"
|
||||
@echo "this does not work with 'make'!"
|
||||
@echo "Please put your SDK to a path without whitespaces"
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
endif
|
||||
|
||||
${OUTDIR}/%.o: %.c
|
||||
@echo "**********************"
|
||||
@echo "compile: $@ from $<"
|
||||
@mkdir -p ${OUTDIR}
|
||||
$(CC) -c $(CFLAGS) $(INCLUDES) -o $@ $<
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
${OUTDIR}/${SONAME}: ${OUTDIR}/$(DEP).h ${OUTDIR}/$(ITF).h $(OBJS)
|
||||
@echo "**********************"
|
||||
@echo "link: $@"
|
||||
@mkdir -p ${OUTDIR}
|
||||
$(CC) $(LDFLAGS) -shared $(OBJS) -Wl,-soname,$(SONAME) -o $@ $(LDLIBS)
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
${OUTDIR}/$(DEP).m4:
|
||||
@echo "**********************"
|
||||
@echo "create $@ from template"
|
||||
@mkdir -p ${OUTDIR}
|
||||
echo 'SET_COMPONENT_NAME(`'${CMPBASENAME}"')" > $@
|
||||
echo 'COMPONENT_VERSION(`'${CMPVERSION}"')" >> $@
|
||||
echo 'COMPONENT_VENDORID(`'${CMPVENDORID}"')" >> $@
|
||||
echo "#define CMPID_${CMPBASENAME} ${CMPID}" >> $@
|
||||
echo "IMPLEMENT_ITF("'`'"${CMPBASENAME}Itf.m4')" >> $@
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
${OUTDIR}/$(DEP).h: ${OUTDIR}/$(DEP).m4 $(ITF).m4
|
||||
@echo "**********************"
|
||||
@echo "build dependency header: $@ from $<"
|
||||
@mkdir -p ${OUTDIR}
|
||||
$(DOS2UNIX) $<
|
||||
$(M4) -I$(SDKDIR)/m4 -I. Implementation.m4 - < $< > $@
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
${OUTDIR}/$(ITF).h: $(ITF).m4
|
||||
@echo "**********************"
|
||||
@echo "build interface header: $@ from $<"
|
||||
@sed -n '/DEF_API/ !d; /_cext/ ! { s/^/ERROR: This functionname does not contain _cext (this is mandatory, see help for details):\n/p;q 1}' $<
|
||||
@mkdir -p ${OUTDIR}
|
||||
$(DOS2UNIX) $<
|
||||
$(M4) -I$(SDKDIR)/m4 Exports.m4 - < $< > $@
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
.PHONY:clean
|
||||
clean:
|
||||
@echo ""
|
||||
@echo "**********************"
|
||||
@echo "clean up"
|
||||
rm -rf ${OUTDIR};
|
||||
@echo "**********************"
|
||||
@echo ""
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,48 @@
|
||||
##############################################################################
|
||||
# Copyright: Copyright CODESYS Development GmbH
|
||||
# Program: Extension API for the Linux SL products
|
||||
##############################################################################
|
||||
|
||||
#
|
||||
# with this makefile you can influence the build of your component
|
||||
#
|
||||
#
|
||||
# Hints:
|
||||
# - the name of the *Itf.m4 file in this folder will be used as name of the shared object (and component name)
|
||||
# - all C files in this folder will be compiled by default
|
||||
#
|
||||
|
||||
# set versions of your shared object
|
||||
# must be single digit, decimal
|
||||
MAJORVER=0
|
||||
MINORVER=1
|
||||
|
||||
# set a component version (must match your IEC library version)
|
||||
# must be 4 bytes, hexadecimal
|
||||
CMPVERSION=0x01000000
|
||||
|
||||
# set a component ID
|
||||
# must be 2 bytes >= 0x2000 and hexadecimal and can be used to differentiate different components
|
||||
CMPID=0x2000
|
||||
|
||||
# set your tools
|
||||
DOS2UNIX = dos2unix
|
||||
M4 = m4
|
||||
|
||||
# set a compiler
|
||||
CC ?= gcc
|
||||
|
||||
# add some compiler flags (with += )
|
||||
#CFLAGS += -g
|
||||
|
||||
# add some include paths (with +=)
|
||||
#INCLUDES += -I.
|
||||
|
||||
# add some linker flags (with += )
|
||||
#LDFLAGS +=
|
||||
|
||||
# add some libraries that you might need (with += )
|
||||
#LDLIBS += -lc
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* Copyright: Copyright CODESYS Development GmbH
|
||||
* Program: Extension API for the Linux SL products
|
||||
******************************************************************************/
|
||||
|
||||
#include "CmpStd.h"
|
||||
|
||||
#include DEP_H
|
||||
|
||||
USE_STMT
|
||||
|
||||
DLL_DECL int CDECL ComponentEntry(INIT_STRUCT *pInitStruct)
|
||||
/* Used to exchange function pointers between component manager and components.
|
||||
Called at startup for each component.
|
||||
pInitStruct: IN Pointer to structure with:
|
||||
pfExportFunctions OUT Pointer to function that exports component functions
|
||||
pfImportFunctions OUT Pointer to function that imports functions from other components
|
||||
pfGetVersion OUT Pointer to function to get component version
|
||||
pfRegisterAPI IN Pointer to component manager function to register a API function
|
||||
pfGetAPI IN Pointer to component manager function to get a API function
|
||||
pfCallHook IN Pointer to component manager function to call a hook function
|
||||
Return ERR_OK if library could be initialized, else error code
|
||||
*/
|
||||
{
|
||||
pInitStruct->CmpId = COMPONENT_ID;
|
||||
pInitStruct->pfExportFunctions = ExportFunctions;
|
||||
pInitStruct->pfImportFunctions = ImportFunctions;
|
||||
pInitStruct->pfGetVersion = CmpGetVersion;
|
||||
pInitStruct->pfHookFunction = HookFunction;
|
||||
pInitStruct->pfCreateInstance = NULL;
|
||||
pInitStruct->pfDeleteInstance = NULL;
|
||||
|
||||
s_pfCMRegisterAPI = pInitStruct->pfCMRegisterAPI;
|
||||
s_pfCMRegisterAPI2 = pInitStruct->pfCMRegisterAPI2;
|
||||
s_pfCMGetAPI = pInitStruct->pfCMGetAPI;
|
||||
s_pfCMGetAPI2 = pInitStruct->pfCMGetAPI2;
|
||||
s_pfCMCallHook = pInitStruct->pfCMCallHook;
|
||||
s_pfCMRegisterClass = pInitStruct->pfCMRegisterClass;
|
||||
s_pfCMCreateInstance = pInitStruct->pfCMCreateInstance;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* <description>Publish exported functions to the component manager, to make them available for other components.
|
||||
* Use generated macro EXPORT_STMT.</description>
|
||||
* <result>ERR_OK or error code in case of error</result>
|
||||
*/
|
||||
static int CDECL ExportFunctions(void)
|
||||
{
|
||||
/* Macro to export functions */
|
||||
EXPORT_STMT;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* <description>Import function pointers from other components. Use generated macro IMPORT_STMT.</description>
|
||||
* <result>ERR_OK or error code if function name could not be resolved</result>
|
||||
*/
|
||||
static int CDECL ImportFunctions(void)
|
||||
{
|
||||
/* Macro to import functions */
|
||||
IMPORT_STMT;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* <description>Return the version of our component.</description>
|
||||
* <result>Version as defined in dep file</result>
|
||||
*/
|
||||
static RTS_UI32 CDECL CmpGetVersion(void)
|
||||
{
|
||||
return CMP_VERSION;
|
||||
}
|
||||
|
||||
static RTS_RESULT CDECL HookFunction(RTS_UI32 ulHook, RTS_UINTPTR ulParam1, RTS_UINTPTR ulParam2)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user