搭建PVB架构,实现前端的基础布局、菜单、表格、图示等功能

This commit is contained in:
lixiaoyuan
2025-08-20 19:00:22 +08:00
parent 5de7687bcc
commit 7e965b6fb4
142 changed files with 28270 additions and 411 deletions

View File

@@ -0,0 +1,70 @@
/***************************************************************************
BMP.h - description
-------------------
begin : Sun Okt 12 2001
copyright : (C) 2000 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
typedef struct mytagBITMAPFILEHEADER
{ // bmfh
unsigned short int bfType;
unsigned short int bfSize[2];
unsigned short int bfReserved1;
unsigned short int bfReserved2;
unsigned short int bfOffBits[2];
} myBITMAPFILEHEADER;
typedef struct mytagBITMAPINFOHEADER{ // bmih
unsigned int biSize;
unsigned int biWidth;
unsigned int biHeight;
unsigned short int biPlanes;
unsigned short int biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
unsigned int biXPelsPerMeter;
unsigned int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} myBITMAPINFOHEADER;
typedef struct mytagBITMAPCOREHEADER { // bmch
unsigned int bcSize;
unsigned short int bcWidth;
unsigned short int bcHeight;
unsigned short int bcPlanes;
unsigned short int bcBitCount;
} myBITMAPCOREHEADER;
typedef struct mytagRGBTRIPLE { // rgbt
unsigned char rgbtBlue;
unsigned char rgbtGreen;
unsigned char rgbtRed;
} myRGBTRIPLE;
typedef struct mytagRGBQUAD { // rgbq
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} myRGBQUAD;
/* following BITMAPFILEHEADER */
typedef struct mytagBITMAPINFO {
myBITMAPINFOHEADER bmiHeader;
myRGBQUAD bmiColors[1];
} myBITMAPINFO;
/* following BITMAPFILEHEADER */
typedef struct my_BITMAPCOREINFO { // bmci
myBITMAPCOREHEADER bmciHeader;
myRGBTRIPLE bmciColors[1];
} myBITMAPCOREINFO;

View File

@@ -0,0 +1,415 @@
/*====================================================================
This software was written by Ian L. Kaplan, Chief Fat Bear, Bear Products
International. Use of this software, for any purpose, is granted on two
conditions:
1. This copyright notice must be included with the software
or any software derived from it.
2. The risk of using this software is accepted by the user. No
warranty as to its usefulness or functionality is provided
or implied. The author and Bear Products International provides
no support.
====================================================================*/
#ifndef DXF2GL_H
#define DXF2GL_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// These rather convoluted ifndef's are required because both FALSE, TRUE
// and BOOLEAN are defined by various windows and windows/nt headers. When
// these headers are included, a redefine error results without these ifndefs.
//
typedef enum {
#ifndef FALSE
FALSE = 0,
#endif
#ifndef TRUE
TRUE = 1,
#endif
BOGUS
} BoolVals;
#ifndef _WIN32
typedef int BOOLEAN;
#endif
/* FileAccess - a class for opening and reading ASCII files.
Public functions:
FileAccess constructor - The argument to this constructor is
the file name. The constructor will
open the file and set the variable
FileOpenOK (which can be accessed via
FileOK).
FileAccess destructor - Close the file
get_line - get a line for the file and return it as a null
terminated string.
*/
class FileAccess {
// Variables
private:
FILE *FilePtr;
BOOLEAN FileOpenOK;
protected:
public:
// Class Functions
private:
//OpenFile(char *FileName);
void file_error(const char *msg);
protected:
public:
FileAccess(const char *FileName = "" );
~FileAccess(void);
BOOLEAN FileOK(void) { return FileOpenOK; }
BOOLEAN get_line(char *LineBuf, const int BufSize);
}; // FileAccess
/*
The page_pool object is designed to support rapid memory allocation
and deallocation of all allocated memory, once the object is no
longer needed. By using a block allocation scheme, the overhead of
memory allocation is greatly reduced, compared to "malloc" (or new).
Deallocation of large blocks of memory is also much faster than
calling free for every allocated block of memory.
The page_pool allocator allocates blocks of memory in "page_size"
increments. The page_size variable is set at start-up and contains
the system virtual memory page size.
The page_pool object contains the virtual function "add_to_list"
which can be implemented by the inherited function
ordered_list. Ordered list is a class that supports ordered list
insertion and deletion. In this case, this is used to support an
ordered list of free memory blocks. The ordered list is only
needed if the page_pool is used as the base for a memory allocater
that can allocate from a free list.
*/
class page_pool {
private: // typedefs and variables
typedef struct page_chain_struct
{ void *block;
unsigned int bytes_used;
unsigned int block_size;
page_chain_struct *next_page;
} page_chain;
// The min_block_size is the smallest block that will be returned by the
// page_pool allocater. The max_block_size is the largest memory block
// that can be requested. Ideally, this should be a multiple of the page
// size.
typedef enum { min_block_size = 96, max_block_size = 1024 * 8 } bogus;
page_chain *page_list_head;
page_chain *current_page;
static unsigned int page_size; // system page size, shared by all instances
private: // class functions
static unsigned int GetSysPageSize(void);
page_chain *new_block( unsigned int block_size );
void *add_block( unsigned int block_size );
public: // class functions
page_pool(void);
~page_pool(void);
void *page_alloc( unsigned int block_size );
void print_page_pool_info(void);
virtual void add_to_list(void *addr, unsigned int size);
}; // class page_pool
/*
A 3D graphic object can be described as a list of polygons. Each
of these polygons consists of three or more points in 3D space
(e.g., x, y, z coordinates).
The FaceList object will construct a list of polygon faces read from
a DXF file. Two DXF file polygon formats are supported:
- 3DFACE
- POLYLINE
The "face" structure member "f" is a pointer to an array of points.
This point array is dynamically allocated. The minimum number of
points that can be allocated for a polygon is four (a 3DFACE polygon
may only consist of three points, in which case the last point is
unused).
Although during creating there is a distinction made between DXF
3DFACE objects and POLYLINE objects, the class represents both as
polygon faces and no such distinction exists when the polygon
list is read.
The object supplies the following public functions for creating a
polygon list:
add_3DFACE_point - Add a 3D point to a 3DFACE polygon
add_poly_point - Add a 3D point to a POLYLINE polygon
get_new_3DFACE - Create a new 3DFACE polygon
get_new_poly_face - Create a new POLYLINE polygon
Once the polygon list is created, it can be read using the following
functions:
GetListStart - Return a handle for the start of the polygon face
list
GetFace - Get a polygon face, given a list handle
GetNextFace - Get the next polygon face in the list
*/
class FaceList {
public:
typedef enum {MinSize = 4} bogus; // minimum number of points
typedef enum {Xcoord, Ycoord, Zcoord} bogus2;
typedef struct { float v[3]; } vect; // a point in the 3D plane
typedef struct { vect *f; // an array of 3D points
int point_cnt; // number of points currently alloc'ed
int point_max; // max points
} face;
typedef void *ListHandle;
private:
typedef struct FaceListStruct { face cur_face;
struct FaceListStruct *next_face;
} FaceElem;
page_pool mem;
FaceElem *ListHead;
FaceElem *ListTail;
private:
void add_point(face *cur_face, float x, float y, float z);
// void GrowFace( face *cur_face );
public:
FaceList(void) { ListHead = NULL;
ListTail = NULL;
}
void add_3DFACE_point(float x, float y, float z );
void add_poly_point(float x, float y, float z);
void get_new_3DFACE(void);
void get_new_poly_face(int polypont);
ListHandle GetListStart(void) { return (ListHandle)ListHead; }
face *GetFace( ListHandle handle)
{ return &((FaceElem *)handle)->cur_face; }
ListHandle GetNextFace( ListHandle handle )
{ return (ListHandle)((FaceElem *)handle)->next_face; }
void print(void);
};
//
// The gl_token enumeration defines the tokens that are returned by the
// scanner and are used by the parser in attempting to recognize the
// components of a DXF file.
//
typedef enum { bad_gl_token,
section,
header,
endsec,
seqend,
blocks,
block,
endblk,
vertex,
tables,
table,
layer,
contin,
endtab,
entities,
three_d_face,
end_of_file,
polyline,
integer,
real,
name,
last_gl_token } gl_token;
/*
This file contains the stack object definition. The scanner
requires two token look ahead to resolve things like the EOF token
sequence. If this sequence is checked for, but not found, it is
necessary to "back up" the input stream. This is done via the token
stack.
Note that a DXF file may contain both integer and float values.
Two versions of "push_token" are implemented, one with an integer
value and one with a float value. The integer version may be used
with just a token value, in which case the default value will be
used for the integer.
*/
class token_stack {
public:
typedef union { int intval;
float realval;
} token_union;
typedef struct { gl_token token;
token_union val;
} token_stack_type;
private:
typedef enum {MaxTokens = 10} bogus1;
token_stack_type token_stack_buf[ MaxTokens ];
int token_sp;
public:
token_stack(void) { token_sp = MaxTokens; }
BOOLEAN StackHasItems(void) { return token_sp < MaxTokens; }
void push_token( gl_token token, int intval = 0 );
void push_token( gl_token token, float realval );
token_stack_type pop_token(void);
};
/*
This file contains the scanner object that tokenizes the input
stream. The scanner either returns a reserved word (e.g., section
or three_d_face), "name" (an identifier, such as a layer name or
face name), integer or real. The various DXF markers (e.g., the 70
marker or 0 for start) are returned as integers. This scanner is
designed as a front end for a program that reads a DXF file and
displays it as a 3D wire frame, using openGL (hense then "GL"
naming).
Scanning and parsing a DXF file is difficult, because the DXF file
format seems to have grown over time in an ad hoc manner. Further,
the documentation is obscure and/or incomplete. While parsing the
file, it is sometimes necessary to "back up". To support this, a
stack is maintained. Input tokens and values can be "pushed" onto
this stack and re-read. The token_stack class supports this feature.
*/
class GL_scanner {
// variables
private:
token_stack stack;
float gl_float;
int gl_int;
FileAccess *MyFileObj;
typedef enum {WordBufSize = 40} bogus2;
char WordBuf[ WordBufSize ];
protected:
public:
// class functions
private:
gl_token scan_number(char *cptr);
gl_token scan_word(char *cptr);
gl_token gl_name_lookup(void);
protected:
public:
GL_scanner( FileAccess *FileObj ) { MyFileObj = FileObj; }
float get_gl_float() { return gl_float; }
int get_gl_int() { return gl_int; }
char *get_gl_name() { return WordBuf; }
gl_token get_next_token(void);
BOOLEAN token_in_stack(void) { return stack.StackHasItems(); }
gl_token get_token_from_stack();
void put_token_in_stack(const gl_token token);
void put_token_in_stack(const gl_token token, int DX_val)
{ stack.push_token(token, DX_val); }
void print_token(const gl_token token);
};
/* This file contains the parser object that processes the DXF file.
The class function GL_GetFaceList returns the Face list for the
3D DXF object.
*/
class MinMax {
private:
float min;
float max;
public:
typedef enum {MAXVAL = 1024*1000} bogus;
// The initial values of max and min should be way beyond any reasonable
// range.
MinMax(void) { min = (float)MAXVAL; max = (float)(-(MAXVAL)); }
void SetMinMax( float val ) { if (val < min)
min = val;
if (val > max)
max = val;
}
float GetMin(void) { return min; }
float GetMax(void) { return max; }
};
class GL_object {
// variables
private:
GL_scanner *GL_scan;
protected:
public:
MinMax PointRange;
// class functions
private:
void set_min_max();
void undo(gl_token token);
BOOLEAN IsEndSec(void);
BOOLEAN IsStart(void);
BOOLEAN IsName(void);
BOOLEAN IsTable(void);
BOOLEAN IsLayerName(void);
BOOLEAN Is3DFace(void);
BOOLEAN IsEndSet(void);
float GetCoord(void);
void get_3DFACE_point(FaceList *FaceObjPtr);
void get_poly_point(FaceList *FaceObjPtr);
void SkipSection(void);
void Get3DFACE(FaceList *&CurObj);
void GetPolyLine(FaceList *&CurObj);
protected:
public:
GL_object(FileAccess *FileObj ) { GL_scan = new GL_scanner( FileObj ); };
~GL_object(void) { delete GL_scan; }
FaceList *GL_GetFaceList(void);
}; // GL_object
typedef enum { DXF_start = 0,
DXF_textval = 1,
DXF_name = 2,
DXF_othername1 = 3,
DXF_othername2 = 4,
DXF_entity_handle = 5,
DXF_line_type = 6,
DXF_text_style = 7,
DXF_layer_name = 8,
DXF_var_name = 9,
DXF_primary_X = 10,
DXF_other_X_1 = 11,
DXF_primary_Y = 20,
DXF_other_Y_1 = 21,
DXF_other_Z = 31,
DXF_elevation = 38,
DXF_thickness = 39,
DXF_floatvals = 40,
DXF_repeat = 49,
DXF_angle1 = 50, DXF_angle2 = 51,
DXF_angle3 = 52, DXF_angle4 = 53,
DXF_angle5 = 54, DXF_angle6 = 55,
DXF_angle7 = 56, DXF_angle8 = 57,
DXF_angle9 = 58,
DXF_colornum = 62,
DXF_entities_flg = 66,
DXF_ent_ident = 67,
DXF_SeventyFlag = 70,
DXF_SeventyOneFlag= 71,
DXF_SeventyTwoFlag= 72,
DXF_view_state = 69,
DXF_comment = 999 } DXF_values;
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
// You may use this header if you use C++ string's
// avoid casts with .c_str()
// Warning: This file is NOT maintained on a regular basis, so some functions may be missing
// If you observe this please contact: R. Lehrig lehrig@t-online.de
#ifndef _PROCESS_VIEW_SERVER_STRING_H_
#define _PROCESS_VIEW_SERVER_STRING_H_
#include "processviewserver.h"
#include <string>
using namespace std;
inline int pvWait(PARAM *p, string pattern) { return pvWait(p, pattern.c_str()); }
inline int pvWarning(PARAM *p, string text) { return pvWarning(p, text.c_str()); }
inline int pvMainFatal(PARAM *p, string text) { return pvMainFatal(p, text.c_str()); }
inline int pvThreadFatal(PARAM *p, string text) { return pvThreadFatal(p, text.c_str()); }
inline int pvQButtonGroup(PARAM *p, int id, int parent, int columns, int orientation, string title) { return pvQButtonGroup(p, id, parent, columns, orientation, title.c_str()); }
inline int pvQImage(PARAM *p, int id, int parent, string imagename, int *w, int *h, int *depth) { return pvQImage(p, id, parent, imagename.c_str(), w, h, depth); }
inline int pvQGroupBox(PARAM *p, int id, int parent, int columns, int orientation, string title) { return pvQGroupBox(p, id, parent, columns, orientation, title.c_str()); }
inline int pvSetCaption(PARAM *p, string text) { return pvSetCaption(p, text.c_str()); }
inline int pvToolTip(PARAM *p, int id, string text) { return pvToolTip(p, id, text.c_str()); }
inline int pvSetText(PARAM *p, int id, string text) { return pvSetText(p, id, text.c_str()); }
inline int pvChangeItem(PARAM *p, int id, int index, string bmp_file, string text) { return pvChangeItem(p, id, index, bmp_file.c_str(), text.c_str()); }
inline int pvInsertItem(PARAM *p, int id, int index, string bmp_file, string text) { return pvInsertItem(p, id, index, bmp_file.c_str(), text.c_str()); }
inline int pvRemoveItemByName(PARAM *p, int id, string name) { return pvRemoveItemByName(p, id, name.c_str()); }
inline int pvAddColumn(PARAM *p, int id, string text, int size) { return pvAddColumn(p, id, text.c_str(), size); }
inline int pvSetTableText(PARAM *p, int id, int x, int y, string text) { return pvSetTableText(p, id, x, y, text.c_str()); }
inline int pvSetTableCheckBox(PARAM *p, int id, int x, int y, int state, string text) { return pvSetTableCheckBox(p, id, x, y, state, text.c_str()); }
inline int pvSetTableComboBox(PARAM *p, int id, int x, int y, int editable, string textlist) { return pvSetTableComboBox(p, id, x, y, editable, textlist.c_str()); }
inline int pvSetListViewText(PARAM *p, int id, string path, int column, string text) { return pvSetListViewText(p, id, path.c_str(), column, text.c_str()); }
inline int pvSetPixmap(PARAM *p, int id, string bmp_file) { return pvSetPixmap(p, id, bmp_file.c_str()); }
inline int pvSetTablePixmap(PARAM *p, int id, int x, int y, string bmp_file) { return pvSetTablePixmap(p, id, x, y, bmp_file.c_str()); }
inline int pvSetSource(PARAM *p, int id, string html_file) { return pvSetSource(p, id, html_file.c_str()); }
inline int pvSetImage(PARAM *p, int id, string filename) { return pvSetImage(p, id, filename.c_str()); }
inline int pvSetFont(PARAM *p, int id, string family, int pointsize, int bold, int italic , int underline, int strikeout) { return pvSetFont(p, id, family.c_str(), pointsize, bold, italic , underline, strikeout); }
inline int pvDisplayStr(PARAM *p, int id, string str) { return pvDisplayStr(p, id, str.c_str()); }
inline int pvAddTab(PARAM *p, int id, int id_child, string str) { return pvAddTab(p, id, id_child, str.c_str()); }
inline int pvSetListViewPixmap(PARAM *p, int id, string path, string bmp_file, int column) { return pvSetListViewPixmap(p, id, path.c_str(), bmp_file.c_str(), column); }
inline int pvRemoveListViewItem(PARAM *p, int id, string path) { return pvRemoveListViewItem(p, id, path.c_str()); }
inline int pvRemoveIconViewItem(PARAM *p, int id, string text) { return pvRemoveIconViewItem(p, id, text.c_str()); }
inline int pvSetIconViewItem(PARAM *p, int id, string bmp_file, string text) { return pvSetIconViewItem(p, id, bmp_file.c_str(), text.c_str()); }
inline int pvListViewEnsureVisible(PARAM *p, int id, string path) { return pvListViewEnsureVisible(p, id, path.c_str()); }
inline int pvListViewSetOpen(PARAM *p, int id, string path, int open) { return pvListViewSetOpen(p, id, path.c_str(), open); }
inline int pvVtkTcl(PARAM *p, int id, string tcl_command) { return pvVtkTcl(p, id, tcl_command.c_str()); }
inline int pvVtkTclScript(PARAM *p, int id, string filename) { return pvVtkTclScript(p, id, filename.c_str()); }
inline int pvHyperlink(PARAM *p, string link) { return pvHyperlink(p, link.c_str()); }
inline int pvWriteFile(PARAM *p, string filename, int width, int height) { return pvWriteFile(p, filename.c_str(), width, height); }
inline int pvSave(PARAM *p, int id, string filename) { return pvSave(p, id, filename.c_str()); }
inline int pvSaveAsBmp(PARAM *p, int id, string filename) { return pvSaveAsBmp(p, id, filename.c_str()); }
inline int pvSendFile(PARAM *p, string filename) { return pvSendFile(p, filename.c_str()); }
inline int pvDownloadFileAs(PARAM *p, string filename, string newname) { return pvDownloadFileAs(p, filename.c_str(), newname.c_str()); }
inline int pvDownloadFile(PARAM *p, string filename) { return pvDownloadFile(p, filename.c_str()); }
inline int pvPopupMenu(PARAM *p, int id_return, string text) { return pvPopupMenu(p, id_return, text.c_str()); }
inline int pvMessageBox(PARAM *p, int id_return, int type, string text, int button0, int button1, int button2) { return pvMessageBox(p, id_return, type, text.c_str(), button0, button1, button2); }
inline int pvInputDialog(PARAM *p, int id_return, string text, string default_text) { return pvInputDialog(p, id_return, text.c_str(), default_text.c_str()); }
inline int qpwSetTitle(PARAM *p, int id, string text) { return qpwSetTitle(p, id, text.c_str()); }
inline int qpwSetAxisTitle(PARAM *p, int id, int pos, string text) { return qpwSetAxisTitle(p, id, pos, text.c_str()); }
inline int qpwInsertCurve(PARAM *p, int id, int index, string text) { return qpwInsertCurve(p, id, index, text.c_str()); }
inline int qpwSetMarkerLabel(PARAM *p, int id, int number, string text) { return qpwSetMarkerLabel(p, id, number, text.c_str()); }
inline int qpwSetMarkerFont(PARAM *p, int id, int index, string family, int size, int style) { return qpwSetMarkerFont(p, id, index, family.c_str(), size, style); }
inline int qpwInsertLineMarker(PARAM *p, int id, int index, string text, int pos) { return qpwInsertLineMarker(p, id, index, text.c_str(), pos); }
inline int qpwSetAxisScaleDraw( PARAM *p, int id, int pos, string text ) { return qpwSetAxisScaleDraw( p, id, pos, text.c_str() ); }
inline int gWriteFile(string file) { return gWriteFile(file.c_str()); }
inline int gSetFont(PARAM *p, string family, int size, int weight, int italic) { return gSetFont(p, family.c_str(), size, weight, italic); }
inline int gText(PARAM *p, int x, int y, string text, int alignment) { return gText(p, x, y, text.c_str(), alignment); }
inline int gTextInAxis(PARAM *p, float x, float y, string text, int alignment) { return gTextInAxis(p, x, y, text.c_str(), alignment); }
inline int gSetFloatFormat(PARAM *p, string text) { return gSetFloatFormat(p, text.c_str()); }
inline int gBoxWithText(PARAM *p, int x, int y, int w, int h, int fontsize, string xlabel, string ylabel, string rylabel) { return gBoxWithText(p, x, y, w, h, fontsize, xlabel.c_str(), ylabel.c_str(), rylabel.c_str()); }
inline int gComment(PARAM *p, string comment) { return gComment(p, comment.c_str()); }
inline int gPlaySVG(PARAM *p, string filename) { return gPlaySVG(p, filename.c_str()); }
inline int qwtScaleSetTitle(PARAM *p, int id, string text) { return qwtScaleSetTitle(p, id, text.c_str()); }
inline int qwtScaleSetTitleFont(PARAM *p, int id, string family, int pointsize, int bold, int italic, int underline, int strikeout) { return qwtScaleSetTitleFont(p, id, family.c_str(), pointsize, bold, italic, underline, strikeout); }
#endif

View File

@@ -0,0 +1,31 @@
/***************************************************************************
pvapp.h - description
-------------------
begin : Sun Nov 12 2000
copyright : (C) 2000 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _PVAPP_H_
#define _PVAPP_H_
#include "processviewserver.h"
int show_mask1(PARAM *p);
int show_mask2(PARAM *p);
int show_mask3(PARAM *p);
int show_mask4(PARAM *p);
int show_periodic(PARAM *p);
int show_maskvtk(PARAM *p);
int show_qwt(PARAM *p);
int show_modal1(PARAM *p);
#endif

View File

@@ -0,0 +1,36 @@
/***************************************************************************
pvbImage.h - description
-------------------
begin : Sun Okt 12 2001
copyright : (C) 2000 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#include "BMP.h"
typedef struct
{
unsigned char b,g,r,reserved;
}LUT;
typedef struct
{
int w,h,bpp,nLut;
LUT *lut;
void *image;
}
PVB_IMAGE;
PVB_IMAGE *pvbImageRead(const char *filename);
void pvbImageFree(PVB_IMAGE *pvbImage);
int pvmyread(int fhdl, char *cptr, int len);
int pvopenBinary(const char *filename);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/***************************************************************************
wthread.h - description
-------------------
begin : Sun Nov 12 2000
copyright : (C) 2000 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/***********************************************************************************
Wrapper for posix threads (UNIX,VMS,windows)
(C) R. Lehrig 2000 lehrig@t-online.de
***********************************************************************************/
#ifndef _WTHREAD_H_
#define _WTHREAD_H_
#include "processviewserver.h"
#ifdef PVWIN32
#define WTREAD_GNUC1 ( __GNUC__ * 1000 ) + __GNUC_MINOR__
#if WTREAD_GNUC1 < 4008
#define PVWIN32THREAD
#endif
#include <windows.h>
#include <winbase.h>
#endif
#include <stddef.h>
#include <string.h>
#ifdef PVWIN32THREAD
#ifndef _WRAPTHREAD_
#ifndef _RL_WTHREAD_H_
typedef unsigned long int pthread_t;
/* Attributes for threads */
struct __sched_param
{
int sched_priority;
};
typedef struct
{
int __detachstate;
int __schedpolicy;
struct __sched_param __schedparam;
int __inheritsched;
int __scope;
size_t __guardsize;
int __stackaddr_set;
void *__stackaddr;
size_t __stacksize;
}pthread_attr_t;
typedef HANDLE pthread_mutex_t;
//old typedef CRITICAL_SECTION pthread_mutex_t;
typedef long pthread_mutexattr_t;
#endif
#endif
#else /* VMS or UNIX or new GCC on Windows*/
#ifndef WIN_PTHREADS_H
#include <pthread.h>
#endif
#endif /* end of MSWINDOWS */
#ifndef _WRAPTHREAD_
#ifndef _RL_WTHREAD_H_
typedef struct
{
#ifdef PVWIN32THREAD
int cmax;
HANDLE hSemaphore;
#else
int cmax;
int nready;
pthread_mutex_t mutex;
pthread_cond_t cond;
#endif
}WSEMAPHORE;
#endif
#endif
/* function prototypes */
#ifndef __VMS
#ifdef __cplusplus
extern "C" {
#endif
#endif
int pvthread_attr_init(pthread_attr_t *attr);
int pvthread_create(pthread_t *tid, const pthread_attr_t *attr,
void *(*func)(void*), void *arg);
void pvthread_close_handle(pthread_t *tid);
void pvthread_exit(void *status);
int pvthread_join(pthread_t tid, void **status);
int pvthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr);
int pvthread_mutex_destroy(pthread_mutex_t *mptr);
int pvthread_mutex_lock(pthread_mutex_t *mptr);
int pvthread_mutex_trylock(pthread_mutex_t *mptr);
int pvthread_mutex_unlock(pthread_mutex_t *mptr);
int pvthread_cancel(pthread_t tid);
int pvinit_semaphore(WSEMAPHORE *s, int cmax);
int pvincrement_semaphore(WSEMAPHORE *s);
int pvwait_semaphore(WSEMAPHORE *s);
int pvthread_sleep(long msec);
#ifndef __VMS
#ifdef __cplusplus
};
#endif
#endif
#endif

View File

@@ -0,0 +1,838 @@
/* <St> *******************************************************************
FILENAME : CIFUSER.H
-------------------------------------------------------------------------
CREATETED : R. Mayer, Hilscher GmbH
DATE : 28.11.95
PROJEKT : CIF device driver
=========================================================================
DISCRIPTION
User interface definition.
*
* Filename:
* $Workfile: CIFUSER.H $ $Revision: 21 $
* Last Modification:
* $Author: Sebastian $
* $Modtime: 6.04.04 11:52 $
*
* Targets:
* Win32/ANSI : yes
* Win32/Unicode: yes
* WinCE : yes
*
=========================================================================
CHANGES
version name date description
-------------------------------------------------------------------------
V1.300 MY 26.01.04 - Review
- changes from Harald
BOARD_INFO and BOARD_INFOEX included
- include "windows.h" removed
V1.202 MY 10.12.00 - CIF100 Rev.5 changes included
V1.201 MY 10.12.00 - Parameter definition of DevDMADown changed
V1.200 MY 15.03.00 - New CIF100 definitions included
V1.100 MY 19.09.99 - Function for performance test included
V1.023 MY 06.09.01 - Error number for configuration check
V1.022 MY 23.04.01 - Error number extended and
DMA driver errors included
- CIF 100 specific definitions included
- Definition for CIF_TKIT included
V1.021 MY 23.08.99 - Definition against multiple inclusion
added
V1.020 MY 22.03.99 - New Function DevDownload included
- Definitions for download modes included
V1.011 MY 20.02.98 - SPC_CONTROL_SET/CLEAR included
V1.010 MY 28.10.97 - Modes in DevExchangeIOErr changed from
0,1,2 to 2,3,4
V1.009 MY 16.09.97 - MS-C++ support include (#ifdef _cplusplus)
- DevPutMessage(), pvData renamed into
ptMessage
- Function: DevReadWriteRAW()
DevExchangeIOEx()
DevExchangeIOErr() included.
- MSG.data in MSG_STRUCT reduced to
255 Byte, which is the max. data length.
- New reset definition BOOTSTART included,
to save parameters on CIF40
- PcWatchDog into HostWatchDog renamed
- Error numbers -6, -26, -27 included
- Reset mode BOOTSTART included
- New handshake and definitions for
state field transfer included
V1.008 MY 05.06.97 - GETMESSAGECMD, size of message included,
to prevent overwriting of user buffer
V1.007 MY 05.06.97 - static definition of the
IOSEND and IORECEIVE data area removed
- BOARD_INFOEX structure and function
DevGetBoardInfoEx included
V1.006 MY 25.04.97 - function DevGetExtendedInfo included
V1.005 MY 30.11.96 - function DevExtendedData, DevGetMBXData
included
- error -25 included
V1.004 MY 18.06.96 - IO function IOCTLREADSEND
included
V1.003 MY 25.04.96 - IO function IOCTLEXIO
IOGETPARAM
IOSETHOST
included
V1.002 MY 28.02.96 - function DevGetMBXState included
- Variable name MSG_STRUC.daten
changed into data
V1.001 MY 31.01.96 - user interface changed
V1.000 MY
******************************************************************** <En> */
/* prevent multiple inclusion */
#ifndef __CIFUSER_H
#define __CIFUSER_H
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#ifdef __cplusplus
extern "C" {
#endif /* _cplusplus */
/* ------------------------------------------------------------------------------------ */
/* global definitions */
/* ------------------------------------------------------------------------------------ */
#define MAX_DEV_BOARDS 4 /* maximum numbers of boards */
/* ------------------------------------------------------------------------------------ */
/* driver errors */
/* ------------------------------------------------------------------------------------ */
#define DRV_NO_ERROR 0 /* no error */
#define DRV_BOARD_NOT_INITIALIZED -1 /* DRIVER Board not initialized */
#define DRV_INIT_STATE_ERROR -2 /* DRIVER Error in internal init state */
#define DRV_READ_STATE_ERROR -3 /* DRIVER Error in internal read state */
#define DRV_CMD_ACTIVE -4 /* DRIVER Command on this channel is active */
#define DRV_PARAMETER_UNKNOWN -5 /* DRIVER Unknown parameter in function occured */
#define DRV_WRONG_DRIVER_VERSION -6 /* DRIVER Version is incompatible with DLL */
#define DRV_PCI_SET_CONFIG_MODE -7 /* DRIVER Error during PCI set run mode */
#define DRV_PCI_READ_DPM_LENGTH -8 /* DRIVER Could not read PCI dual port memory length */
#define DRV_PCI_SET_RUN_MODE -9 /* DRIVER Error during PCI set run mode */
#define DRV_DEV_DPM_ACCESS_ERROR -10 /* DEVICE Dual port ram not accessable(board not found)*/
#define DRV_DEV_NOT_READY -11 /* DEVICE Not ready (ready flag failed) */
#define DRV_DEV_NOT_RUNNING -12 /* DEVICE Not running (running flag failed) */
#define DRV_DEV_WATCHDOG_FAILED -13 /* DEVICE Watchdog test failed */
#define DRV_DEV_OS_VERSION_ERROR -14 /* DEVICE Signals wrong OS version */
#define DRV_DEV_SYSERR -15 /* DEVICE Error in dual port flags */
#define DRV_DEV_MAILBOX_FULL -16 /* DEVICE Send mailbox is full */
#define DRV_DEV_PUT_TIMEOUT -17 /* DEVICE PutMessage timeout */
#define DRV_DEV_GET_TIMEOUT -18 /* DEVICE GetMessage timeout */
#define DRV_DEV_GET_NO_MESSAGE -19 /* DEVICE No message available */
#define DRV_DEV_RESET_TIMEOUT -20 /* DEVICE RESET command timeout */
#define DRV_DEV_NO_COM_FLAG -21 /* DEVICE COM-flag not set */
#define DRV_DEV_EXCHANGE_FAILED -22 /* DEVICE IO data exchange failed */
#define DRV_DEV_EXCHANGE_TIMEOUT -23 /* DEVICE IO data exchange timeout */
#define DRV_DEV_COM_MODE_UNKNOWN -24 /* DEVICE IO data mode unknown */
#define DRV_DEV_FUNCTION_FAILED -25 /* DEVICE Function call failed */
#define DRV_DEV_DPMSIZE_MISMATCH -26 /* DEVICE DPM size differs from configuration */
#define DRV_DEV_STATE_MODE_UNKNOWN -27 /* DEVICE State mode unknown */
#define DRV_DEV_HW_PORT_IS_USED -28 /* DEVICE Output port already in use */
/* Error from Interface functions */
#define DRV_USR_OPEN_ERROR -30 /* USER Driver not opened (device driver not loaded) */
#define DRV_USR_INIT_DRV_ERROR -31 /* USER Can't connect with device */
#define DRV_USR_NOT_INITIALIZED -32 /* USER Board not initialized (DevInitBoard not called)*/
#define DRV_USR_COMM_ERR -33 /* USER IOCTRL function failed */
#define DRV_USR_DEV_NUMBER_INVALID -34 /* USER Parameter DeviceNumber invalid */
#define DRV_USR_INFO_AREA_INVALID -35 /* USER Parameter InfoArea unknown */
#define DRV_USR_NUMBER_INVALID -36 /* USER Parameter Number invalid */
#define DRV_USR_MODE_INVALID -37 /* USER Parameter Mode invalid */
#define DRV_USR_MSG_BUF_NULL_PTR -38 /* USER NULL pointer assignment */
#define DRV_USR_MSG_BUF_TOO_SHORT -39 /* USER Message buffer too short */
#define DRV_USR_SIZE_INVALID -40 /* USER Parameter Size invalid */
#define DRV_USR_SIZE_ZERO -42 /* USER Parameter Size with zero length */
#define DRV_USR_SIZE_TOO_LONG -43 /* USER Parameter Size too long */
#define DRV_USR_DEV_PTR_NULL -44 /* USER Device address null pointer */
#define DRV_USR_BUF_PTR_NULL -45 /* USER Pointer to buffer is a null pointer */
#define DRV_USR_SENDSIZE_TOO_LONG -46 /* USER SendSize parameter too long */
#define DRV_USR_RECVSIZE_TOO_LONG -47 /* USER ReceiveSize parameter too long */
#define DRV_USR_SENDBUF_PTR_NULL -48 /* USER Pointer to buffer is a null pointer */
#define DRV_USR_RECVBUF_PTR_NULL -49 /* USER Pointer to buffer is a null pointer */
#define DRV_DMA_INSUFF_MEM -50 /* DMA Memory allocation error */
#define DRV_DMA_TIMEOUT_CH4 -51 /* DMA Read I/O timeout */
#define DRV_DMA_TIMEOUT_CH5 -52 /* DMA Write I/O timeout */
#define DRV_DMA_TIMEOUT_CH6 -53 /* DMA PCI transfer timeout */
#define DRV_DMA_TIMEOUT_CH7 -54 /* DMA Download timeout */
#define DRV_DMA_DB_DOWN_FAIL -55 /* DMA Database download failed */
#define DRV_DMA_FW_DOWN_FAIL -56 /* DMA Firmware download failed */
#define DRV_CLEAR_DB_FAIL -57 /* DMA Clear database on the device failed */
#define DRV_DEV_NO_VIRTUAL_MEM -60 /* USER Virtual memory not available */
#define DRV_DEV_UNMAP_VIRTUAL_MEM -61 /* USER Unmap virtual memory failed */
#define DRV_GENERAL_ERROR -70 /* DRIVER General error */
#define DRV_DMA_ERROR -71 /* DRIVER General DMA error */
#define DRV_WDG_IO_ERROR -74 /* DRIVER I/O WatchDog failed */
#define DRV_WDG_DEV_ERROR -75 /* DRIVER Device WatchDog failed */
#define DRV_USR_DRIVER_UNKNOWN -80 /* USER driver unknown */
#define DRV_USR_DEVICE_NAME_INVALID -81 /* USER device name invalid */
#define DRV_USR_DEVICE_NAME_UKNOWN -82 /* USER device name unknown */
#define DRV_USR_DEVICE_FUNC_NOTIMPL -83 /* USER device function not implemented */
#define DRV_USR_FILE_OPEN_FAILED -100 /* USER File not opened */
#define DRV_USR_FILE_SIZE_ZERO -101 /* USER File size zero */
#define DRV_USR_FILE_NO_MEMORY -102 /* USER Not enough memory to load file */
#define DRV_USR_FILE_READ_FAILED -103 /* USER File read failed */
#define DRV_USR_INVALID_FILETYPE -104 /* USER File type invalid */
#define DRV_USR_FILENAME_INVALID -105 /* USER File name not valid */
#define DRV_FW_FILE_OPEN_FAILED -110 /* USER Firmware file not opened */
#define DRV_FW_FILE_SIZE_ZERO -111 /* USER Firmware file size zero */
#define DRV_FW_FILE_NO_MEMORY -112 /* USER Not enough memory to load firmware file */
#define DRV_FW_FILE_READ_FAILED -113 /* USER Firmware file read failed */
#define DRV_FW_INVALID_FILETYPE -114 /* USER Firmware file type invalid */
#define DRV_FW_FILENAME_INVALID -115 /* USER Firmware file name not valid */
#define DRV_FW_DOWNLOAD_ERROR -116 /* USER Firmware file download error */
#define DRV_FW_FILENAME_NOT_FOUND -117 /* USER Firmware file not found in the internal table */
#define DRV_FW_BOOTLOADER_ACTIVE -118 /* USER Firmware file BOOTLOADER active */
#define DRV_FW_NO_FILE_PATH -119 /* USER Firmware file no file path */
#define DRV_CF_FILE_OPEN_FAILED -120 /* USER Configuration file not opend */
#define DRV_CF_FILE_SIZE_ZERO -121 /* USER Configuration file size zero */
#define DRV_CF_FILE_NO_MEMORY -122 /* USER Not enough memory to load configuration file */
#define DRV_CF_FILE_READ_FAILED -123 /* USER Configuration file read failed */
#define DRV_CF_INVALID_FILETYPE -124 /* USER Configuration file type invalid */
#define DRV_CF_FILENAME_INVALID -125 /* USER Configuration file name not valid */
#define DRV_CF_DOWNLOAD_ERROR -126 /* USER Configuration file download error */
#define DRV_CF_FILE_NO_SEGMENT -127 /* USER No flash segment in the configuration file */
#define DRV_CF_DIFFERS_FROM_DBM -128 /* USER Configuration file differs from database */
#define DRV_DBM_SIZE_ZERO -131 /* USER Database size zero */
#define DRV_DBM_NO_MEMORY -132 /* USER Not enough memory to upload database */
#define DRV_DBM_READ_FAILED -133 /* USER Database read failed */
#define DRV_DBM_NO_FLASH_SEGMENT -136 /* USER Database segment unknown */
#define DEV_CF_INVALID_DESCRIPT_VERSION -150/* CONFIG Version of the descript table invalid */
#define DEV_CF_INVALID_INPUT_OFFSET -151/* CONFIG Input offset is invalid */
#define DEV_CF_NO_INPUT_SIZE -152/* CONFIG Input size is 0 */
#define DEV_CF_MISMATCH_INPUT_SIZE -153/* CONFIG Input size does not match configuration */
#define DEV_CF_INVALID_OUTPUT_OFFSET -154/* CONFIG Invalid output offset */
#define DEV_CF_NO_OUTPUT_SIZE -155/* CONFIG Output size is 0 */
#define DEV_CF_MISMATCH_OUTPUT_SIZE -156/* CONFIG Output size does not match configuration */
#define DEV_CF_STN_NOT_CONFIGURED -157/* CONFIG Station not configured */
#define DEV_CF_CANNOT_GET_STN_CONFIG -158/* CONFIG Cannot get the Station configuration */
#define DEV_CF_MODULE_DEF_MISSING -159/* CONFIG Module definition is missing */
#define DEV_CF_MISMATCH_EMPTY_SLOT -160/* CONFIG Empty slot mismatch */
#define DEV_CF_MISMATCH_INPUT_OFFSET -161/* CONFIG Input offset mismatch */
#define DEV_CF_MISMATCH_OUTPUT_OFFSET -162/* CONFIG Output offset mismatch */
#define DEV_CF_MISMATCH_DATA_TYPE -163/* CONFIG Data type mismatch */
#define DEV_CF_MODULE_DEF_MISSING_NO_SI -164/* CONFIG Module definition is missing,(no Slot/Idx) */
#define DRV_RCS_ERROR_OFFSET 1000 /* RCS error number start */
/* ------------------------------------------------------------------------------------ */
/* message definition */
/* ------------------------------------------------------------------------------------ */
#pragma pack(1)
/* max. length is 288 Bytes, max message length is 255 + 8 Bytes */
typedef struct tagMSG_STRUC {
unsigned char rx;
unsigned char tx;
unsigned char ln;
unsigned char nr;
unsigned char a;
unsigned char f;
unsigned char b;
unsigned char e;
unsigned char data[255];
unsigned char dummy[25]; /* for compatibility with older definitions (288 Bytes) */
} MSG_STRUC;
#pragma pack()
/* ------------------------------------------------------------------------------------ */
/* INFO structure definitions */
/* ------------------------------------------------------------------------------------ */
#pragma pack(1)
/* DEVRESET */
#define COLDSTART 2
#define WARMSTART 3
#define BOOTSTART 4
/* DEVMBXINFO */
#define DEVICE_MBX_EMPTY 0
#define DEVICE_MBX_FULL 1
#define HOST_MBX_EMPTY 0
#define HOST_MBX_FULL 1
/* TRIGGERWATCHDOG */
#define WATCHDOG_STOP 0
#define WATCHDOG_START 1
/* GETINFO InfoArea definitions */
#define GET_DRIVER_INFO 1
#define GET_VERSION_INFO 2
#define GET_FIRMWARE_INFO 3
#define GET_TASK_INFO 4
#define GET_RCS_INFO 5
#define GET_DEV_INFO 6
#define GET_IO_INFO 7
#define GET_IO_SEND_DATA 8
#define GET_CIF_PLC_DRIVER_INFO 10
/* HOST mode definition */
#define HOST_NOT_READY 0
#define HOST_READY 1
/* DEVREADWRITERAW / DEVREADWRITEDPMDATA */
#define PARAMETER_READ 1
#define PARAMETER_WRITE 2
/* STATE definition */
#define STATE_ERR_NON 0
#define STATE_ERR 1
#define STATE_MODE_2 2
#define STATE_MODE_3 3
#define STATE_MODE_4 4
/* DEVSPECIALCONTROL */
#define SPECIAL_CONTROL_CLEAR 0
#define SPECIAL_CONTROL_SET 1
/* DEVDOWNLOAD */
#define FIRMWARE_DOWNLOAD 1
#define CONFIGURATION_DOWNLOAD 2
// DEVHWIOPORT
#define HW_PORT_SET_OUTPUT 1
#define HW_PORT_CLEAR_OUTPUT 2
#define HW_PORT_READ_INPUT 3
/* DEVMEMORYPTR */
#define MEMORY_PTR_CREATE 1
#define MEMORY_PTR_RELEASE 2
/* ------------------------------------------------------------------------------------ */
/* INFO structure definitions */
/* ------------------------------------------------------------------------------------ */
/* Device exchange IO information */
typedef struct tagIOINFO {
unsigned char bComBit; /* Actual state of the COM bit */
unsigned char bIOExchangeMode; /* Actual data exchange mode (0..5) */
unsigned long ulIOExchangeCnt; /* Exchange IO counter */
} IOINFO;
/* Device version information */
typedef struct tagVERSIONINFO { /* Device serial number and OS versions */
unsigned long ulDate;
unsigned long ulDeviceNo;
unsigned long ulSerialNo;
unsigned long ulReserved;
unsigned char abPcOsName0[4];
unsigned char abPcOsName1[4];
unsigned char abPcOsName2[4];
unsigned char abOemIdentifier[4];
} VERSIONINFO;
/* Device firmware information */
typedef struct tagFIRMWAREINFO {
unsigned char abFirmwareName[16]; /* Firmware name */
unsigned char abFirmwareVersion[16]; /* Firmware version */
} FIRMWAREINFO;
/* Device task state information */
typedef struct tagTASKSTATE {
unsigned char abTaskState[64]; /* Task state field */
} TASKSTATE;
/* Device task paramater data */
typedef struct tagTASKPARAM {
unsigned char abTaskParameter[64]; /* Task parameter field */
} TASKPARAM;
/* Device raw data structure */
typedef struct tagRAWDATA {
unsigned char abRawData[1022]; /* Definition of the last kByte */
} RAWDATA;
/* Device task information */
typedef struct tagTASKINFO {
struct {
unsigned char abTaskName[8]; /* Task name */
unsigned short usTaskVersion; /* Task version */
unsigned char bTaskCondition; /* Actual task condition */
unsigned char abreserved[5]; /* n.c. */
} tTaskInfo [7];
} TASKINFO;
/* Device operating system (RCS) information */
typedef struct tagRCSINFO {
unsigned short usRcsVersion; /* Device operating system (RCS) version */
unsigned char bRcsError; /* Operating system errors */
unsigned char bHostWatchDog; /* Host watchdog value */
unsigned char bDevWatchDog; /* Device watchdog value */
unsigned char bSegmentCount; /* RCS segment free counter */
unsigned char bDeviceAdress; /* RCS device base address */
unsigned char bDriverType; /* RCS driver type */
} RCSINFO;
/* Device description */
typedef struct tagDEVINFO {
unsigned char bDpmSize; /* Device dpm size (2,8...) */
unsigned char bDevType; /* Device type (manufactor code) */
unsigned char bDevModel; /* Device model (manufactor code) */
unsigned char abDevIdentifier[3]; /* Device identification characters */
} DEVINFO;
#pragma pack()
/* ------------------------------------------------------------------------------------ */
/* driver info structure definitions */
/* ------------------------------------------------------------------------------------ */
#pragma pack(1)
/* Board information structure */
typedef struct tagBOARD {
unsigned short usBoardNumber; /* DRV board number */
unsigned short usAvailable; /* DRV board is available */
unsigned long ulPhysicalAddress; /* DRV physical DPM address */
unsigned short usIrqNumber; /* DRV irq number */
} BOARD;
typedef struct tagBOARD_INFO{
unsigned char abDriverVersion[16]; /* DRV driver information string */
BOARD tBoard [MAX_DEV_BOARDS];
} BOARD_INFO;
/* Internal driver state information structure */
typedef struct tagDRIVERINFO{
unsigned long ulOpenCnt; /* DevOpen() counter */
unsigned long ulCloseCnt; /* DevClose() counter */
unsigned long ulReadCnt; /* Number of DevGetMessage commands */
unsigned long ulWriteCnt; /* Number of DevPutMessage commands */
unsigned long ulIRQCnt; /* Number of board interrupts */
unsigned char bInitMsgFlag; /* Actual init sate */
unsigned char bReadMsgFlag; /* Actual read mailbox state */
unsigned char bWriteMsgFlag; /* Actual write mailbox state */
unsigned char bLastFunction; /* Last driver function */
unsigned char bWriteState; /* Actual write command state */
unsigned char bReadState; /* Actual read command state */
unsigned char bHostFlags; /* Actual host flags */
unsigned char bMyDevFlags; /* Actual device falgs */
unsigned char bExIOFlag; /* Actual IO flags */
unsigned long ulExIOCnt; /* DevExchangeIO() counter */
} DRIVERINFO;
/* Extended board information structure */#
typedef struct tagBOARD_EX {
unsigned short usBoardNumber; /* DRV board number */
unsigned short usAvailable; /* DRV board is available */
unsigned long ulPhysicalAddress; /* DRV physical DPM address */
unsigned short usIrqNumber; /* DRV irq number */
DRIVERINFO tDriverInfo; /* Driver information */
FIRMWAREINFO tFirmware;
DEVINFO tDeviceInfo;
RCSINFO tRcsInfo;
VERSIONINFO tVersion;
} BOARD_EX;
typedef struct tagBOARD_INFOEX{
unsigned char abDriverVersion[16]; /* DRV driver information string */
BOARD_EX tBoard [MAX_DEV_BOARDS];
} BOARD_INFOEX;
/* Communication state field structure */
typedef struct tagCOMSTATE {
unsigned short usMode; /* Actual STATE mode */
unsigned short usStateFlag; /* State flag */
unsigned char abState[64]; /* State area */
} COMSTATE;
/* State information in bLastFunction */
#define FKT_OPEN 1
#define FKT_CLOSE 2
#define FKT_READ 3
#define FKT_WRITE 4
#define FKT_IO 5
/* State information in bWriteState and bReadState */
#define STATE_IN 0x01
#define STATE_WAIT 0x02
#define STATE_OUT 0x03
#define STATE_IN_IRQ 0x04
#pragma pack()
/* ------------------------------------------------------------------------------------ */
/* CIF100 special function definitions */
/* ------------------------------------------------------------------------------------ */
#pragma pack(1)
/*--------------------------*/
/* Device DMA download */
/*--------------------------*/
#define DEV_DMA_DOWN_FW 1
#define DEV_DMA_DOWN_DB 2
/*--------------------------*/
/* Device BACKUP RAM */
/*--------------------------*/
#define DEV_BACKUP_RAM_READ 1
#define DEV_BACKUP_RAM_WRITE 2
/*--------------------------*/
/* Device Timer */
/*--------------------------*/
#define DEV_TIMER_CTRL_START 1
#define DEV_TIMER_CTRL_STOP 2
#define DEV_TIMER_MODE_NORMAL 1
#define DEV_TIMER_MODE_NMI 2
#define DEV_TIMER_RESOLUTION_100US 0
#define DEV_TIMER_RESOLUTION_1MS 1
/*----------------------------*/
/* PLC information structure */
/*----------------------------*/
typedef struct tagCIF_PLC_DRIVER_INFO {
char *pbInput;
unsigned long ulInputSize;
char *pbOutput;
unsigned long ulOutputSize;
TASKSTATE *ptTaskState; /* Take this pointer and cast it to the protocol spez. structure */
unsigned long ulNVRAMSize;
char *pbNVRAM;
} CIF_PLC_DRIVER_INFO;
#ifndef CIF_TKIT
#ifndef NT_FUNCTIONS_INCLUDED
#define LARGE_INTEGER int
#endif
/*--------------------------*/
/* Performance test */
/*--------------------------*/
#define PERFORMANCE_START 1
#define PERFORMANCE_GETDATA 2
#define PERFORMANCE_STOP 3
#define PERFORMANCE_NETWORK 4
typedef struct tagPERFORMANCE_DATA {
unsigned short usDevNumber; /* IN Board number */
unsigned short usMeasurementMode; /* IN READ-WRITE-ONCE-CYCLIC */
unsigned char fActive; /* Performence measurement activ */
unsigned char fNetwork; /* IN inclusive/exclusive Network */
unsigned char bSendValue; /* IN value for performence test */
unsigned long dwRecvLen; /* IN receive size for interrupt */
LARGE_INTEGER ilLIfreq; /* OUT Timer frequency */
LARGE_INTEGER ilTickStartW; /* OUT WriteSTART */
LARGE_INTEGER ilTickEndW; /* OUT WriteEND */
LARGE_INTEGER ilTickStartR; /* OUT ReadSTART */
LARGE_INTEGER ilTickEndR; /* OUT ReadEND */
LARGE_INTEGER ilTickStartCycle;
LARGE_INTEGER ilTickEndCycle;
LARGE_INTEGER ilCycleTime;
LARGE_INTEGER ilTransferTime;
} PERFORMANCE_DATA_PVB; // appended _PVB because original name lead to name conflict on win32
/*--------------------------*/
/* Device RAM test test */
/*--------------------------*/
#define DEVRAMTEST_START 1
#define DEVRAMTEST_DOIT 2
#define DEVRAMTEST_RESULT 3
#define DEVRAMTEST_STOP 4
typedef struct tagDEV_RAM_TEST {
unsigned short usBoard; /* IN Board number */
unsigned short usMode; /* IN start, test, result, stop */
unsigned char fActive; /* DMA RAM test active */
unsigned char fWrite; /* Function writing */
unsigned char fRead; /* Function reading */
unsigned long dwDevStartAd;
unsigned long dwDataLen;
unsigned char ucPattern;
unsigned long dwCycleCnt;
unsigned long dwDMAerrCnt_W; /* DMA error count writing */
unsigned long dwDMAerrCnt_R; /* DMA error count reading */
unsigned long dwDATAerrCnt;
} DEV_RAM_TEST;
/*--------------------------*/
/* Logfile */
/*--------------------------*/
#define LOGFILE_HEAD 1
#define LOGFILE_REPORT 2
#define LOGFILE_ERROR 4
#define LOGFILE_DATA_MSG 8
#define LOGFILE_DATA_LENGTH 300
typedef struct tagDEV_LOGFILE_DATA {
unsigned char bSeparator; /* Seperator */
unsigned char bIdent; /* Identification */
unsigned long ulLength; /* Data length */
LARGE_INTEGER ilSystemTime; /* Time stamp */
unsigned short usBoardNumber; /* Board number */
long lErrorNumber; /* Error number */
unsigned char abData[LOGFILE_DATA_LENGTH]; /* Data */
} DEV_LOGFILE_DATA;
#endif /* !Toolkit definition */
#pragma pack()
/* ------------------------------------------------------------------------------------ */
/* Configuration file definition */
/* ------------------------------------------------------------------------------------ */
/* Descript tabel version definition */
#define RECORD_TYPE_LESS_THEN_2300 0x01
#define RECORD_TYPE_EQUAL_HIGHER_2300 0x02
/* ------------------------------------------------------------------------------------ */
/* Function prototypes */
/* ------------------------------------------------------------------------------------ */
#ifndef CIF_TKIT
short APIENTRY DevOpenDriver ( unsigned short usDevNumber);
short APIENTRY DevCloseDriver ( unsigned short usDevNumber);
short APIENTRY DevGetBoardInfo ( unsigned short usDevNumber,
unsigned short usSize,
void *pvData);
short APIENTRY DevInitBoard ( unsigned short usDevNumber,
void *pDevAddress);
short APIENTRY DevExitBoard ( unsigned short usDevNumber);
short APIENTRY DevPutTaskParameter ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
short APIENTRY DevReset ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulTimeout);
short APIENTRY DevPutMessage ( unsigned short usDevNumber,
MSG_STRUC *ptMessage,
unsigned long ulTimeout);
short APIENTRY DevGetMessage ( unsigned short usDevNumber,
unsigned short usSize,
MSG_STRUC *ptMessage,
unsigned long ulTimeout);
short APIENTRY DevGetTaskState ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
short APIENTRY DevGetMBXState ( unsigned short usDevNumber,
unsigned short *pusDevMBXState,
unsigned short *pusHostMBXState);
short APIENTRY DevTriggerWatchDog ( unsigned short usDevNumber,
unsigned short usFunction,
unsigned short *usDevWatchDog);
short APIENTRY DevGetInfo ( unsigned short usDevNumber,
unsigned short usFunction,
unsigned short usSize,
void *pvData);
short APIENTRY DevGetTaskParameter ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
short APIENTRY DevExchangeIO ( unsigned short usDevNumber,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
unsigned long ulTimeout);
short APIENTRY DevReadSendData ( unsigned short usDevNumber,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
short APIENTRY DevSetHostState ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulTimeout);
short APIENTRY DevExtendedData ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usSize,
void *pvData);
short APIENTRY DevGetMBXData ( unsigned short usDevNumber,
unsigned short usHostSize,
void *pvHostData,
unsigned short usDevSize,
void *pvDevData);
short APIENTRY DevGetBoardInfoEx ( unsigned short usDevNumber,
unsigned short usSize,
void *pvData);
short APIENTRY DevExchangeIOEx ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
unsigned long ulTimeout);
short APIENTRY DevExchangeIOErr ( unsigned short usDevNumber,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
COMSTATE *ptState,
unsigned long ulTimeout);
short APIENTRY DevReadWriteDPMRaw ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
short APIENTRY DevSpecialControl ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short *pusCtrlAck);
short APIENTRY DevDownload ( unsigned short usDevNumber,
unsigned short usMode,
unsigned char *pszFileName,
DWORD *pdwBytes);
short APIENTRY DevReadWriteDPMData ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
/*-------------------*/
/* Special functions */
/*-------------------*/
short APIENTRY DevGetDPMPtr ( unsigned short usMode,
unsigned short usDevNumber,
void *pvUserData,
unsigned long *pulDPMSize,
unsigned char **pDPMBase,
long *plError);
/*---------------------------*/
/* CIF100 spezific functions */
/*---------------------------*/
short APIENTRY DevPerformance ( void *ptData);
short APIENTRY DevRAMTest ( void *ptData);
short APIENTRY DevTimer ( unsigned short usDevNumber,
unsigned short usControl,
unsigned short usMode,
unsigned short usResolution,
char bTickCount);
short APIENTRY DevBackupRAM ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulOffset,
unsigned long ulSize,
void *pvData);
short APIENTRY DevRAMrw ( unsigned short usDevNumber,
unsigned long ulDevStartAdd,
unsigned short usDataLen,
void *pvSendData,
void *pvReceiveData,
unsigned long ulTimeout);
short APIENTRY DevDMAdown ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulTimeout);
short APIENTRY DevClearConfig ( unsigned short usDevNumber);
short APIENTRY DevIsPLCDataReady ( unsigned short usDevNumber,
unsigned short *pusState);
short APIENTRY DevExchangePLCData ( unsigned short usDevNumber,
unsigned short usSendSize,
unsigned short usReceiveSize,
unsigned long ulTimeout);
short APIENTRY DevHWPortControl ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short *pusState);
short APIENTRY DevMemoryPtr ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long usSize,
CIF_PLC_DRIVER_INFO *ptPLCData);
#endif /* !Toolkit definition */
#ifdef __cplusplus
}
#endif
#endif /* __CIFUSER_H */

View File

@@ -0,0 +1,133 @@
/* <St> *******************************************************************
FILENAME : ASC_USER.H
-------------------------------------------------------------------------
CREATED BY : R. Mayer, Hilscher GmbH
CREATED AT : 29.05.96
PROJECT : ASC
=========================================================================
FUNCTION :
User interface ASCII protocol
=========================================================================
CHANGES OF REVISIONS :
Version Name Date Change
-------------------------------------------------------------------------
V1.000 Mayer 29.05.96 Created
******************************************************************** <En> */
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack(1) /* Byte Alignment */
#endif
/* ======================================================================== */
/* Protocol definition */
/* ======================================================================== */
/* Mode */
#define ASC_MODE_SLAVE 0
#define ASC_MODE_MASTER 1
/* Stop mode */
#define ASC_ENDMODE_TIMEOUT 0 /* Timeout */
#define ASC_ENDMODE_ID 1 /* Identifier */
#define ASC_ENDMODE_QUITT 2 /* Acknowledg telegram */
#define ASC_ENDMODE_ID_QUITT 3 /* Identifier / Acknowledg telegram */
#define ASC_ENDMODE_NUMBER 4 /* Character number */
#define ASC_ENDMODE_DEFNUMBER 5 /* Predefined character number */
/* Checksum */
#define ASC_CHKSUM_NONE 0
#define ASC_CHKSUM_BIN7 1
#define ASC_CHKSUM_BIN8 2
#define ASC_CHKSUM_BCC 3
#define ASC_CHKSUM_BCC_ASCII 4
/* Checksum area */
#define ASC_CHK_AREA_DATA_ONLY 0 /* Data only */
#define ASC_CHK_AREA_DATA_STARTID 1 /* Data with start identifier */
#define ASC_CHK_AREA_DATA_ENDID 2 /* Data with stop identifier */
#define ASC_CHK_AREA_FULL 3 /* Full telegram */
/* Filter */
#define ASC_FILTER_NONE 0
#define ASC_FILTER_DOUBLE_CHAR 1
/* Timeouts */
#define ASC_TIMEOUT_NONE 0
/* Telegram definition */
#define ASC_TELEGRAM_LENGTH_ZERO 0
/* Telegram sequenz */
#define ASC_TELEGRAM_SEQUENZ_NONE 0
/* ======================================================================== */
/* Protocol parameter structure */
/* ======================================================================== */
typedef struct ASC_PARAMETRtag {
unsigned char bScl; /* Communication line number */
unsigned char bRtsControl; /* RTS control */
unsigned char bBaudrate; /* Baudrate */
unsigned char bDataBits; /* Number of data bits */
unsigned char bStopBits; /* Number of stop bits */
unsigned char bParityBit; /* Parity */
unsigned char bMode; /* Mode */
unsigned char bEndMode; /* End mode */
unsigned char bCheckMode; /* Check mode */
unsigned char bCheckArea; /* Check area */
unsigned char bFilterMode; /* Filter mode */
unsigned short usFilterCharacter; /* Filter characters */
unsigned short usTelTimeout; /* Telegram timeout */
unsigned short usStartTimeout; /* Telegram start timeout */
unsigned short usCharTimeout; /* Charater timeout */
unsigned char bRetries; /* Telegram retries */
unsigned char bErrorLed; /* Mode of the error LED */
unsigned char bTelStartLen; /* Telegram start length */
unsigned char bTelStart[8]; /* Start telegram */
unsigned char bTelEndLen; /* End telegram length */
unsigned char bTelEnd[8]; /* End telegram */
unsigned char bTelAckLen; /* ACK telegram length */
unsigned char bTelAck[8]; /* ACK telegram */
unsigned char bTelNackLen; /* NACK telegram length */
unsigned char bTelNack[8]; /* NACK telegram */
unsigned char bTelDeviceLen; /* Device telegram length */
unsigned short usTelFollowTime;/* Telegram following time */
} ASC_PARAMETER;
/* ======================================================================== */
/* Protocol task state structure */
/* ======================================================================== */
typedef struct ASC_STATEtag {
unsigned char bTaskState; /* Task state */
unsigned long ulTxCount; /* Transmitt telegram count */
unsigned long ulRxCount; /* Receive telegram count */
unsigned short usTxErrorCount; /* Transmitt error count */
unsigned short usRxErrorCount; /* Receive error count */
unsigned short usErrorBits; /* Error bits */
unsigned char bError; /* Last error */
} ASC_STATE;
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack() /* Byte Alignment */
#endif
/* === eof 'USER.H' === */

View File

@@ -0,0 +1,234 @@
/* <St> *******************************************************************
cif_dev.h
-------------------------------------------------------------------------
CREATETED : D. Tsaava, Hilscher GmbH
DATE : 18.07.2000
PROJEKT : CIF device driver
=========================================================================
DISCRIPTION
Include file for CIF device driver, DPM layout .
=========================================================================
CHANGES
version name date Discription
March 2001
Juli 2004 Redesigned for the 2.6 Kernel
Copyright changed to GNU Lesser GPL
-------------------------------------------------------------------------
V2.601
NOTE: as groundwork for this header served Windows version of
the CIF device driver
======================== Copyright =====================================
Copyright (C) 2004 Hilscher GmbH
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
========================================================================
******************************************************************** <En> */
#ifndef CIF_DEV_H
# define CIF_DEV_H
#ifndef STRICT /* Check Typdefinition */
#define STRICT
#endif
#ifndef _GNUC_
# define _GNUC_
#endif /* _GNUC_ */
/* ---------------------------------------------------------------------------------- */
/* DEV definitions */
/* ---------------------------------------------------------------------------------- */
#define DRV_ACTIV_STATE1 2 /* DEV board is in the registery */
#define DRV_ACTIV_STATE2 TRUE /* DEV board is tested and ready */
#define NUM_OF_DRV_NAMES 3 /* Number of possible driver names */
#define DEVNAMELEN 3 /* Size of DEV name in DPM */
#define HW_INTERRUPT_DISABLE 0x00
#define HW_INTERRUPT_ENABLE 0x01
#define BUS_TYPE_PCI 0x01
#define BUS_TYPE_ISA 0x02
/* ------------------------------------------------------------------------------------ */
/* PCI/CPCI card definitions */
/* ------------------------------------------------------------------------------------ */
#define VENDOR_ID 0x10B5 /* PLX technology */
#define SUBVENDOR_ID 0x10B5 /* PLX-PCI chip */
#define SUBSYSTEM_ID_1 0x1080 /* Hilscher CIF50 boards */
#define DEVICE_ID_1 0x9050 /* PLX-PCI chip */
#define SUBSYSTEM_ID_2 0x2695 /* Hilscher newer CIF50 & CIF80 boards */
#define DEVICE_ID_2 0x9030 /* PLX-PCI chip */
/* ------------------------------------------------------------------------------------ */
/* Local Control Register Offsets */
#define PCI_INTCTRLSTS_REG 0x4C
#ifndef CIF_MAJOR
#define CIF_MAJOR 0 /* dynamic major by default */
#endif
#ifndef CIF_MAX_BOARDS
#define CIF_MAX_BOARDS 4 /* Board-0 through Board-3 */
#endif
/* ------------------------------------------------------------------------------------ */
/* DPM structure */
/* ------------------------------------------------------------------------------------ */
#ifdef _GNUC_
# ifndef PACKED
# define PACKED __attribute__((packed, aligned(1)))
# endif /* PACKED */
#else
# define PACKED
#endif
typedef struct tagDPM_MEMORY{
/* DPM size is flexible, now using pointers */
/* for addressing the send and receive area */
MSG_STRUC tDevMbx PACKED; /* Mailbox PC --> DEV (288 Bytes)*/
VERSIONINFO tDevVersion PACKED; /* DEV version information ( 32 Bytes)*/
MSG_STRUC tPcMbx PACKED; /* Mailbox DEV --> PC (288 Bytes)*/
FIRMWAREINFO tFiwInfo PACKED; /* Firmware info ( 32 Bytes)*/
TASKPARAM tKpt1Param PACKED; /* Task 1 interface parameter ( 64 Bytes)*/
TASKPARAM tKpt2Param PACKED; /* Task 2 interface parameter ( 64 Bytes)*/
TASKSTATE tKpt1State PACKED; /* Task 1 state ( 64 Bytes)*/
TASKSTATE tKpt2State PACKED; /* Task 2 state ( 64 Bytes)*/
TASKINFO tTaskInfo PACKED; /* Task 1 to 7 info field (112 Bytes)*/
RCSINFO tRcsInfo PACKED; /* RCS information ( 8 Bytes)*/
DEVINFO tDevInfo PACKED; /* DEV information ( 6 Bytes)*/
unsigned char HostFlags PACKED; /* DPM communication DEV->PC(PcFlags) ( 1 Byte )*/
unsigned char DevFlags PACKED; /* DPM communication PC->DEV(CifFlags)( 1 Byte )*/
} DPM_MEMORY;
/* ------------------------------------------------------------------------------------ */
/* DPM flag definition */
/* ------------------------------------------------------------------------------------ */
// Host flags (HOST_FLAGS) written by the device
#define HOSTCOM_FLAG 0x01
#define DEVACK_FLAG 0x02
#define PDACK_FLAG 0x04
#define STATECOM_FLAG 0x08
#define SPCACK_FLAG 0x10
#define COM_FLAG 0x20
#define RUN_FLAG 0x40
#define READY_FLAG 0x80
// Device flags (DEV_FLAGS) written by the host
#define HOSTACK_FLAG 0x01
#define DEVCOM_FLAG 0x02
#define PDCOM_FLAG 0x04
#define STATEACK_FLAG 0x08
#define SPCCOM_FLAG 0x10
#define NOTREADY_FLAG 0x20
#define INIT_FLAG 0x40
#define RESET_FLAG 0x80
/* ------------------------------------------------------------------------------------ */
/* driver state definitions */
/* ------------------------------------------------------------------------------------ */
#define INI_MSG_WAIT 0x00
#define INI_MSG_RUN 0x40
#define INI_MSG_RDY 0x80
#define INI_MSG_RDYRUN 0xC0
#define COM_FLAG_RDY 0x20
#define RESET_MSG_NON 0x00
#define RESET_MSG_RUN 0x01
#define EXCHGIO_NON 0x00
#define EXCHGIO_EQUAL 0x01
#define EXCHGIO_NOT_EQUAL 0x02
#ifndef CIF_NR_DEVS
#define CIF_NR_DEVS 4
#endif
/*
* Split minors in two parts
*/
#define TYPE(dev) (MINOR(dev) >> 4) /* high nibble */
#define NUM(dev) (MINOR(dev) & 0xf) /* low nibble */
/* ------------------------------------------------------------------------------------ */
/* DEV instance structure */
/* ------------------------------------------------------------------------------------ */
typedef struct tagDEV_INSTANCE {
struct tagDEV_INSTANCE *next; /* linked list of Devices, see CIF_MAX_BOARDS = 4 */
unsigned short usBoard; // Internal board number
void * pvIntSynch; // Interrupt synchronization
unsigned char ucPCIBusNumber; // PCI bus number
unsigned char ucBusType; // PCI, ISA
unsigned long ulBoardAddress; // physical memory address
unsigned long ulDPMSize; // DPM size of the DEV
unsigned long ulDPMByteSize; // DPM size in bytes
unsigned short usBoardIrq; // Interrupt number of the DEV
unsigned short usBoardIrq_scanned; // Interrupt number of the DEV
unsigned char * IrqCtrlRegAddr; //
void * pvVirtualIrq; // Virtual Interrupt
unsigned short usRcsError; // DEV-Error during startup
short sDrvInitError; // DRV-Error during startup
unsigned char bActive; // Board is active
unsigned char * pDpmBase; // Virtual DPM start address
DPM_MEMORY * ptDpmAddress; // Virtual DPM address last kbyte
unsigned char * pbDpmSendArea; // Virtual DPM IO address send area
unsigned char * pbDpmReceiveArea; // Virtual DPM IO address receive area
unsigned char * pbHostFlags; // Pointer to HostFlags (PcFlags)
unsigned char * pbDevFlags; // Pointer to DevFlags (CifFlags)
unsigned short usOpenCounter; // Number of Applikations
spinlock_t mutex; // SMP synchronization
wait_queue_head_t pInitSemaphore;
wait_queue_head_t pReadSemaphore;
wait_queue_head_t pWriteSemaphore;
wait_queue_head_t pExIOSemaphore;
unsigned char bInitState; // Driver init state
unsigned char bReadState; // Driver read state
unsigned char bWriteState; // Driver write state
unsigned char bExIOEqState; // Driver exchange IO EQUAL state
unsigned char bExIONeqState; // Driver exchange IO NOT EQUAL state
unsigned char bCOMEqState; // Driver COM state wait on EQUAL
unsigned char bCOMNeqState; // Driver COM state wait on NOT EQUAL
unsigned char bInitMsgFlag; // Init message activ flag
unsigned char bReadMsgFlag; // Read message available flag
unsigned char bWriteMsgFlag; // Write message done flag
unsigned char bStateFlag; // State flag
unsigned char bExIOFlag; // Exchange IO flag
unsigned char bHostFlags;
unsigned char bMyDevFlags;
unsigned short usSpecialRcsError; // DEV-Error during startup
DRIVERINFO tStateInfo;
/* Structure extention for PCMCIA kernel 2.6.18 */
struct pcmcia_device *p_dev;
dev_node_t node;
} DEV_INSTANCE;
#endif /* CIF_DEV_H */

View File

@@ -0,0 +1,638 @@
/* <St> *******************************************************************
cifdev_i.h
-------------------------------------------------------------------------
CREATETED : D. Tsaava, Hilscher GmbH
DATE : 18.07.2000
PROJEKT : CIF device driver
=========================================================================
DISCRIPTION
Internal driver interface definition
=========================================================================
CHANGES
version name date Discription
March 2001
Juli 2004 Redesigned for the 2.6 Kernel
Copyright changed to GNU Lesser GPL
-------------------------------------------------------------------------
V2.601
NOTE: as groundwork for this header served Windows version of
the CIF device driver
======================== Copyright =====================================
Copyright (C) 2004 Hilscher GmbH
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
========================================================================
******************************************************************** <En> */
#ifndef CIFDEV_I_H
# define CIFDEV_I_H
#ifdef _cplusplus
extern "C" {
#endif /* _cplusplus */
#ifndef _GNUC_
# define _GNUC_
#endif /* _GNUC_ */
/* ------------------------------------------------------------------------------------ */
/* global definitions */
/* ------------------------------------------------------------------------------------ */
#define MAX_DEV_BOARDS 4 // maximum numbers of boards
/* ------------------------------------------------------------------------------------ */
/* driver errors */
/* ------------------------------------------------------------------------------------ */
#define DRV_NO_ERROR 0 // no error
#define DRV_BOARD_NOT_INITIALIZED -1 // DRIVER board not initialized
#define DRV_INIT_STATE_ERROR -2 // DRIVER error in internal init state
#define DRV_READ_STATE_ERROR -3 // DRIVER error in internal read state
#define DRV_CMD_ACTIVE -4 // DRIVER command on this chanal is activ
#define DRV_PARAMETER_UNKNOWN -5 // DRIVER unknown parameter in function occured
#define DRV_WRONG_DRIVER_VERSION -6 // DRIVER driver version is incompatible with DLL
#define DRV_PCI_SET_CONFIG_MODE -7 // DRIVER error during PCI set config mode
#define DRV_PCI_READ_DPM_LENGTH -8 // DRIVER could not read PCI DPM length
#define DRV_PCI_SET_RUN_MODE -9 // DRIVER error during PCI set run mode
#define DRV_DEV_DPM_ACCESS_ERROR -10 // DEVICE dual port ram not accessable
#define DRV_DEV_NOT_READY -11 // DEVICE not ready (ready flag failed)
#define DRV_DEV_NOT_RUNNING -12 // DEVICE not running (running flag failed)
#define DRV_DEV_WATCHDOG_FAILED -13 // DEVICE watch dog test failed
#define DRV_DEV_OS_VERSION_ERROR -14 // DEVICE signals wrong OS version
#define DRV_DEV_SYSERR -15 // DEVICE error in dual port flags
#define DRV_DEV_MAILBOX_FULL -16 // DEVICE send mailbox is full
#define DRV_DEV_PUT_TIMEOUT -17 // DEVICE PutMessage timeout
#define DRV_DEV_GET_TIMEOUT -18 // DEVICE GetMessage timeout
#define DRV_DEV_GET_NO_MESSAGE -19 // DEVICE no message available
#define DRV_DEV_RESET_TIMEOUT -20 // DEVICE RESET command timeout
#define DRV_DEV_NO_COM_FLAG -21 // DEVICE COM-flag not set
#define DRV_DEV_EXCHANGE_FAILED -22 // DEVICE IO data exchange failed
#define DRV_DEV_EXCHANGE_TIMEOUT -23 // DEVICE IO data exchange timeout
#define DRV_DEV_COM_MODE_UNKNOWN -24 // DEVICE IO data mode unknown
#define DRV_DEV_FUNCTION_FAILED -25 // DEVICE Function call failed
#define DRV_DEV_DPMSIZE_MISMATCH -26 // DEVICE DPM size differs from configuration
#define DRV_DEV_STATE_MODE_UNKNOWN -27 // DEVICE State mode unknown
// Error from Interface functions
#define DRV_USR_OPEN_ERROR -30 // USER driver not opened
#define DRV_USR_INIT_DRV_ERROR -31 // USER can't connect with DEV board
#define DRV_USR_NOT_INITIALIZED -32 // USER board not initialized
#define DRV_USR_COMM_ERR -33 // USER IOCTRL function faild
#define DRV_USR_DEV_NUMBER_INVALID -34 // USER parameter for DEV number invalid
#define DRV_USR_INFO_AREA_INVALID -35 // USER parameter InfoArea unknown
#define DRV_USR_NUMBER_INVALID -36 // USER parameter Number invalid
#define DRV_USR_MODE_INVALID -37 // USER parameter Mode invalid
#define DRV_USR_MSG_BUF_NULL_PTR -38 // USER NULL pointer assignment
#define DRV_USR_MSG_BUF_TOO_SHORT -39 // USER Messagebuffer too short
#define DRV_USR_SIZE_INVALID -40 // USER size parameter invalid
#define DRV_USR_SIZE_ZERO -42 // USER size parameter with zero length
#define DRV_USR_SIZE_TOO_LONG -43 // USER size parameter too long
#define DRV_USR_DEV_PTR_NULL -44 // USER device address null pointer
#define DRV_USR_BUF_PTR_NULL -45 // USER pointer to buffer is a null pointer
#define DRV_USR_SENDSIZE_TOO_LONG -46 // USER SendSize parameter too long
#define DRV_USR_RECVSIZE_TOO_LONG -47 // USER ReceiveSize parameter too long
#define DRV_USR_SENDBUF_PTR_NULL -48 // USER pointer to buffer is a null pointer
#define DRV_USR_RECVBUF_PTR_NULL -49 // USER pointer to buffer is a null pointer
#define DRV_DEV_NO_VIRTUAL_MEM -60 // DEVICE Virtual memory not available
#define DRV_DEV_UNMAP_VIRTUAL_MEM -61 // DEVICE Unmap virtual memory failed
#define DRV_DEV_REQUEST_IRQ_FAILED -62 // DEVICE Request irq failed
#define DRV_USR_FILE_OPEN_FAILED -100 // USER file not opend
#define DRV_USR_FILE_SIZE_ZERO -101 // USER file size zero
#define DRV_USR_FILE_NO_MEMORY -102 // USER not enough memory to load file
#define DRV_USR_FILE_READ_FAILED -103 // USER file read failed
#define DRV_USR_INVALID_FILETYPE -104 // USER file type invalid
#define DRV_USR_FILENAME_INVALID -105 // USER file name not valid
#define DRV_RCS_ERROR_OFFSET 1000 // RCS error number start
/* ------------------------------------------------------------------------------------ */
/* message definition */
/* ------------------------------------------------------------------------------------ */
#ifdef _GNUC_
# ifndef PACKED
# define PACKED __attribute__((packed, aligned(1)))
# endif /* PACKED */
#else
# define PACKED
#endif
#ifndef CIFUSER_H_INCLUDED
// max. length is 255 + 8 Bytes
typedef struct tagMSG_STRUC {
unsigned char rx PACKED;
unsigned char tx PACKED;
unsigned char ln PACKED;
unsigned char nr PACKED;
unsigned char a PACKED;
unsigned char f PACKED;
unsigned char b PACKED;
unsigned char e PACKED;
unsigned char data[255] PACKED;
unsigned char dummy[25] PACKED;
} MSG_STRUC;
#endif
/* ------------------------------------------------------------------------------------ */
/* DEV DPM DATA structures */
/* ------------------------------------------------------------------------------------ */
#ifndef CIFUSER_H_INCLUDED
typedef struct tagIOINFO {
unsigned char bComBit PACKED;
unsigned char bIOExchangeMode PACKED;
unsigned long ulIOExchangeCnt PACKED;
} IOINFO;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagVERSIONINFO { /* DEV serial number and OS versions */
unsigned long ulDate PACKED PACKED;
unsigned long ulDeviceNo PACKED;
unsigned long ulSerialNo PACKED;
unsigned long ulReserved PACKED;
unsigned char PcOsName0[4] PACKED;
unsigned char PcOsName1[4] PACKED;
unsigned char PcOsName2[4] PACKED;
unsigned char OemIdentifier[4] PACKED;
} VERSIONINFO;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagFIRMWAREINFO {
unsigned char FirmwareName[16] PACKED;
unsigned char FirmwareVersion[16] PACKED;
} FIRMWAREINFO;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagTASKSTATE {
unsigned char TaskState[64] PACKED;
} TASKSTATE;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagTASKPARAM {
unsigned char TaskParameter[64] PACKED;
} TASKPARAM;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagRAWDATA {
unsigned char abRawData[1022] PACKED;
} RAWDATA;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagTASKINFO {
struct {
char TaskName[8] PACKED; /* Task name */
unsigned short Version PACKED; /* Task version */
unsigned char TaskCondition PACKED;
unsigned char reserved[5] PACKED; /* n.c. */
} tInfo [7];
} TASKINFO;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagRCSINFO {
unsigned short RcsVersion PACKED; /* Operationsystem Version */
unsigned char RcsError PACKED;
unsigned char HostWatchDog PACKED;
unsigned char DevWatchDog PACKED;
unsigned char SegmentCount PACKED;
unsigned char DeviceAdress PACKED;
unsigned char DriverType PACKED;
} RCSINFO;
#endif
#ifndef CIFUSER_H_INCLUDED
typedef struct tagDEVINFO {
unsigned char DpmSize PACKED;
unsigned char DevType PACKED;
unsigned char DevModel PACKED;
unsigned char DevIdentifier[3] PACKED;
} DEVINFO;
#endif
/* ------------------------------------------------------------------------------------ */
/* driver info structure definitions */
/* ------------------------------------------------------------------------------------ */
// Board information structure
#ifndef CIFUSER_H_INCLUDED
typedef struct tagBOARD_INFO{
unsigned char abDriverVersion[16] PACKED; // DRV driver information string
struct {
unsigned short usBoard PACKED; // DRV board number
unsigned short usAvailable PACKED; // DRV board is available
unsigned long ulPhysicalAddress PACKED; // DRV physical DPM address
unsigned short usIrq PACKED; // DRV irq number
} tBoard [MAX_DEV_BOARDS];
unsigned short usBoards_detected PACKED;
} BOARD_INFO;
#endif
// Driver information structure
#ifndef CIFUSER_H_INCLUDED
typedef struct tagDRIVERINFO{
unsigned long OpenCnt PACKED; // number of driver open
unsigned long CloseCnt PACKED; // number of driver close
unsigned long ReadCnt PACKED; // number of DevGetMessage commands
unsigned long WriteCnt PACKED; // number of DevPutMessage commands
unsigned long IRQCnt PACKED; // number of IRQs
unsigned char InitMsgFlag PACKED; // DPM state init
unsigned char ReadMsgFlag PACKED; // DPM state read message
unsigned char WriteMsgFlag PACKED; // DPM state write message
unsigned char LastFunction PACKED; // DRV last function in driver
unsigned char WriteState PACKED; // DRV actual write state
unsigned char ReadState PACKED; // DRV actual read state
unsigned char HostFlags PACKED; // DPM HostFlags (PcFlags)
unsigned char MyDevFlags PACKED; // DPM (internal) DevFlags
unsigned char ExComBit PACKED; // COM bit
unsigned long ExIOCnt PACKED; // IO data exchange count
} DRIVERINFO;
#endif
// Extended board information structure
#ifndef CIFUSER_H_INCLUDED
typedef struct tagBOARD_INFOEX{
unsigned char abDriverVersion[16] PACKED; // DRV driver information string
struct {
unsigned short usBoard PACKED; // DRV board number
unsigned short usAvailable PACKED; // DRV board is available
unsigned long ulPhysicalAddress PACKED; // DRV physical DPM address
unsigned short usIrq PACKED; // DRV irq number
DRIVERINFO tDriverInfo PACKED; // Driver information
FIRMWAREINFO tFirmware PACKED;
DEVINFO tDeviceInfo PACKED;
RCSINFO tRcsInfo PACKED;
VERSIONINFO tVersion PACKED;
} tBoard [MAX_DEV_BOARDS];
} BOARD_INFOEX;
#endif
// State field structure
#ifndef CIFUSER_H_INCLUDED
typedef struct tagCOMSTATE {
unsigned short usMode PACKED; // Actual STATE mode
unsigned short usStateFlag PACKED; // State flag
unsigned char abState[64] PACKED; // State area
} COMSTATE;
#endif
// state information in bLastFunction
#define FKT_OPEN 1;
#define FKT_CLOSE 2;
#define FKT_READ 3;
#define FKT_WRITE 4;
#define FKT_IO 5;
// state information in bWriteState and bReadState
#define STATE_IN 0x01;
#define STATE_WAIT 0x02;
#define STATE_OUT 0x03;
#define STATE_IN_IRQ 0x04;
/* ------------------------------------------------------------------------------------ */
/* IOCTRL data structures */
/* ------------------------------------------------------------------------------------ */
// IOCTRL funktion defines, always step 8
/*
* Ioctl definitions
*/
/* Use 'c' as magic number */
#define CIF_IOC_MAGIC 'c'
#define CIF_IOCRESET _IO(CIF_IOC_MAGIC, 0)
#define CIF_IOCTLNOFUNCTION _IO (CIF_IOC_MAGIC, 0)
#define CIF_IOCTLBOARDINFO _IOWR(CIF_IOC_MAGIC, 1, char[256])
#define CIF_IOCTLINITDRV _IOWR(CIF_IOC_MAGIC, 2, char[13])
#define CIF_IOCTLPARAMETER _IOW (CIF_IOC_MAGIC, 3, char[71])
#define CIF_IOCTLRESETDEV _IOW (CIF_IOC_MAGIC, 4, char[13])
#define CIF_IOCTLPUTMSG _IO (CIF_IOC_MAGIC, 5)
#define CIF_IOCTLGETMSG _IO (CIF_IOC_MAGIC, 6)
#define CIF_IOCTLTASKSTATE _IO (CIF_IOC_MAGIC, 7)
#define CIF_IOCTLMBXINFO _IO (CIF_IOC_MAGIC, 8)
#define CIF_IOCTLTRIGGERWD _IO (CIF_IOC_MAGIC, 9)
#define CIF_IOCTLGETINFO _IO (CIF_IOC_MAGIC, 10)
#define CIF_IOCTLEXITDRV _IO (CIF_IOC_MAGIC, 11)
#define CIF_IOCTLGETPARAMETER _IO (CIF_IOC_MAGIC, 12)
#define CIF_IOCTLEXIO _IO (CIF_IOC_MAGIC, 13)
#define CIF_IOCTLSETHOST _IO (CIF_IOC_MAGIC, 14)
#define CIF_IOCTLREADSEND _IO (CIF_IOC_MAGIC, 15)
#define CIF_IOCTLEXTDATA _IO (CIF_IOC_MAGIC, 16)
#define CIF_IOCTLGETMBX _IO (CIF_IOC_MAGIC, 17)
#define CIF_IOCTLBOARDINFOEX _IO (CIF_IOC_MAGIC, 18)
#define CIF_IOCTLEXIOEX _IO (CIF_IOC_MAGIC, 19)
#define CIF_IOCTLEXIOERR _IO (CIF_IOC_MAGIC, 20)
#define CIF_IOCTLRWRAW _IO (CIF_IOC_MAGIC, 21)
#define CIF_IOCTLSPCONTROL _IO (CIF_IOC_MAGIC, 22)
#define CIF_IOCTLGETDPMPTR _IO (CIF_IOC_MAGIC, 23)
#define CIF_IOCTLRWDPMDATA _IO (CIF_IOC_MAGIC, 24)
#define CIF_IOCTL_IRQ_POLL _IOWR(CIF_IOC_MAGIC, 25, char[13])
#define CIF_IOC_MAXNR 25
// interface structure for ioctl's
typedef struct cif_ioctl_data {
unsigned long lInpBuffLen PACKED;
unsigned long lOutBuffLen PACKED;
unsigned char *pInpBuff PACKED;
unsigned char *pOutBuff PACKED;
} cif_ioctl_data;
// SET BOARD OPERATION MODE
typedef struct tagDEVIO_SETOPMODE {
unsigned short usBoard PACKED;
unsigned short usMode PACKED; // Interrupt/polling mode
unsigned short usIrq PACKED;
short sError PACKED;
} DEVIO_SETOPMODE;
// GETBOARDINFORMATION
typedef struct tagDEVIO_GETBOARDINFOCMD {
unsigned short usDevNumber PACKED; // n.a.
unsigned short usInfoLen PACKED; // Information length
BOARD_INFO *ptBoardInfo PACKED;
short sError PACKED;
} DEVIO_GETBOARDINFOCMD;
// Extnded GETBOARDINFORMATION
typedef struct tagDEVIO_GETBOARDINFOEXCMD {
unsigned short usDevNumber PACKED; // n.a.
unsigned short usInfoLen PACKED; // Information length
BOARD_INFOEX * ptBoard PACKED;
short sError PACKED;
} DEVIO_GETBOARDINFOEXCMD;
// RESETDEV
#define COLDSTART 2
#define WARMSTART 3
#define BOOTSTART 4
typedef struct tagDEVIO_RESETCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usMode PACKED; // DEV function
unsigned long ulTimeout PACKED; // Service timeout
unsigned long ulDpmSize PACKED;
short sError PACKED;
} DEVIO_RESETCMD;
// PUTTASKPARAMETER
typedef struct tagDEVIO_PUTPARAMETERCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usTaskParamNum PACKED; // Number of the parameter area
unsigned short usTaskParamLen PACKED; // Lenght of parameter data
unsigned char TaskParameter[64] PACKED;
short sError PACKED;
} DEVIO_PUTPARAMETERCMD;
// PUTMESSAGE
typedef struct tagDEVIO_PUTMESSAGECMD {
unsigned short usBoard PACKED; // DEV board number
MSG_STRUC tMsg PACKED; // Message data
unsigned long ulTimeout PACKED; // Service timeout
short sError PACKED;
} DEVIO_PUTMESSAGECMD;
// GETMESSAGE
typedef struct tagDEVIO_GETMESSAGECMD {
unsigned short usBoard PACKED; // DEV board number
unsigned long ulTimeout PACKED; // Service timeout
unsigned long ulMsgSize PACKED; // User message buffer size
MSG_STRUC tMsg PACKED; // Message data
short sError PACKED;
} DEVIO_GETMESSAGECMD;
// GETTASKSTATE
typedef struct tagDEVIO_GETTASKSTATECMD {
unsigned char ucBoard PACKED; // DEV board number
unsigned short usStateNum PACKED; // Task state field number
unsigned short usStateLen PACKED; // Lenght of state data
unsigned char TaskState[64] PACKED;
short sError PACKED;
} DEVIO_GETTASKSTATECMD;
// DEVMBXINFO
#define DEVICE_MBX_EMPTY 0
#define DEVICE_MBX_FULL 1
#define HOST_MBX_EMPTY 0
#define HOST_MBX_FULL 1
#define HOST_MBX_SYSERR 2
typedef struct tagDEVIO_MBXINFOCMD {
unsigned char ucBoard PACKED; // DEV board number
unsigned short usDevMbxState PACKED; // State of the device mailbox
unsigned short usHostMbxState PACKED; // State of the host mailbox
short sError PACKED;
} DEVIO_MBXINFOCMD;
// Board operation mode
#define POLLING_MODE 0
#define INTERRUPT_MODE 1
// TRIGGERWATCHDOG and SETHOSTSTATE
#define WATCHDOG_STOP 0
#define WATCHDOG_START 1
#define HOST_NOT_READY 0
#define HOST_READY 1
#define SPECIAL_CONTROL_CLEAR 0
#define SPECIAL_CONTROL_SET 1
typedef struct tagDEVIO_TRIGGERCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usMode PACKED; // DEV function
unsigned long ulTimeout PACKED; // DEV timeout
unsigned short usTriggerValue PACKED; // DEV trigger value
short sError PACKED;
} DEVIO_TRIGGERCMD;
// GETINFO
// InfoArea definitions
#define GET_DRIVER_INFO 1
#define GET_VERSION_INFO 2
#define GET_FIRMWARE_INFO 3
#define GET_TASK_INFO 4
#define GET_RCS_INFO 5
#define GET_DEV_INFO 6
#define GET_IO_INFO 7
#define GET_IO_SEND_DATA 8
typedef struct tagDEVIO_GETDEVINFOCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usInfoArea PACKED; // Number of info area
unsigned short usInfoLen PACKED; // Lenght of info data
unsigned char * pabInfoData PACKED; // Pointer to info data area
short sError PACKED;
} DEVIO_GETDEVINFOCMD;
// EXITDRV
typedef struct tagDEVIO_EXITCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usDrvOpenCount PACKED; // dr<64>er opencount
short sError PACKED;
} DEVIO_EXITCMD;
// GETTASKPARAMETER
typedef struct tagDEVIO_GETPARAMETERCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usTaskParamNum PACKED; // Number of the parameter area
unsigned short usTaskParamLen PACKED; // Lenght of parameter data
unsigned char TaskParameter[64] PACKED;
short sError PACKED;
} DEVIO_GETPARAMETERCMD;
// EXIO
typedef struct tagDEVIO_EXIOCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usSendOffset PACKED; // Byte offset send data
unsigned short usSendLen PACKED; // Length of send data
unsigned char *pabSendData PACKED; // Send data buffer
unsigned short usReceiveOffset PACKED; // Byte offset receive data
unsigned short usReceiveLen PACKED; // Length of receive data
unsigned char *pabReceiveData PACKED; // Receive data buffer
unsigned long ulTimeout PACKED; // Service timeout
short sError PACKED;
} DEVIO_EXIOCMD;
// EXIOEX
typedef struct tagDEVIO_EXIOCMDEX {
unsigned short usBoard PACKED; // DEV board number
unsigned short usSendOffset PACKED; // Byte offset send data
unsigned short usSendLen PACKED; // Length of send data
unsigned char * pabSendData PACKED; // Send data buffer
unsigned short usReceiveOffset PACKED; // Byte offset receive data
unsigned short usReceiveLen PACKED; // Length of receive data
unsigned char * pabReceiveData PACKED; // Receive data buffer
unsigned long ulTimeout PACKED; // Service timeout
short sError PACKED; // --- Equal to "ExcahangeIOCmd"
unsigned short usMode PACKED; // External exchange mode
} DEVIO_EXIOCMDEX;
// EXIOERR
#define STATE_ERR_NON 0
#define STATE_ERR 1
#define STATE_MODE_2 2
#define STATE_MODE_3 3
#define STATE_MODE_4 4
typedef struct tagDEVIO_EXIOCMDERR {
unsigned short usBoard PACKED; // DEV board number
unsigned short usSendOffset PACKED; // Byte offset send data
unsigned short usSendLen PACKED; // Length of send data
unsigned char *pabSendData PACKED; // Send data buffer
unsigned short usReceiveOffset PACKED; // Byte offset receive data
unsigned short usReceiveLen PACKED; // Length of receive data
unsigned char *pabReceiveData PACKED; // Receive data buffer
unsigned long ulTimeout PACKED; // Service timeout
short sError PACKED; // --- Equal to "ExcahangeIOCmd"
COMSTATE *ptStateData PACKED; // State data buffer
} DEVIO_EXIOCMDERR;
// READIO
typedef struct tagDEVIO_READSENDCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usReadOffset PACKED; // Byte offset send/receive data
unsigned short usReadLen PACKED; // Length of send/receive data
unsigned char * pabReadData PACKED; // Read send data buffer
short sError PACKED;
} DEVIO_READSENDCMD;
// ExtData
#define EXTDATASIZE 20
typedef struct tagDEVIO_EXTDATACMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usMode PACKED; // DEV mode
unsigned char *pabExtData PACKED; // DEV Extended data
short sError PACKED;
} DEVIO_EXTDATACMD;
// GetMbxData
typedef struct tagDEVIO_GETMBXCMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usDevLen PACKED; // DEV length of dev data
unsigned short usHostLen PACKED; // DEV length of host data
unsigned char abHostMbx[288] PACKED; // DEV pointer to host data buffer
unsigned char abDevMbx[288] PACKED; // DEV pointer to device data buffer
short sError PACKED;
} DEVIO_GETMBXCMD;
// ReadWriteRawData
#define PARAMETER_READ 1
#define PARAMETER_WRITE 2
typedef struct tagDEVIO_RWRAWDATACMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usMode PACKED; // DEV read or write
unsigned short usOffset PACKED; // DEV offset in the DPM last kByte
unsigned short usLen PACKED; // DEV length of data
unsigned char *pabData PACKED; // DEV pointer to data buffer
short sError PACKED;
} DEVIO_RWRAWDATACMD;
// ReadWriteDPMData
typedef struct tagDEVIO_RWDPMDATACMD {
unsigned short usBoard PACKED; // DEV board number
unsigned short usMode PACKED; // DEV read or write
unsigned short usOffset PACKED; // DEV offset in the DPM last kByte
unsigned short usLen PACKED; // DEV length of data
unsigned char *pabData PACKED; // DEV pointer to data buffer
short sError PACKED;
} DEVIO_RWDPMDATACMD;
// GetDPMPtr
#define DPM_PTR_OPEN_DRV 1
#define DPM_PTR_OPEN_USR 2
#define DPM_PTR_CLOSE 3
typedef struct tagDEVIO_GETDPMPTR {
unsigned short usMode PACKED; // DEV mode
unsigned short usBoard PACKED; // DEV board number
void *pvUserData PACKED; // DEV user data for pmi
unsigned long *pulDPMSize PACKED; // DEV DPM size in bytes
unsigned char **pDPMBase PACKED; // DEV pointer to data buffer
unsigned long lError PACKED; // DEV system error
short sError PACKED; // DEV driver error
} DEVIO_GETDPMPTR;
#ifdef _cplusplus
}
#endif
#endif /* CIFDEV_I_H */

View File

@@ -0,0 +1,71 @@
/* <St> *******************************************************************
cif_types.h
-------------------------------------------------------------------------
CREATETED : D. Tsaava, Hilscher GmbH
DATE : 18.07.2000
PROJEKT : CIF device driver
=========================================================================
DISCRIPTION
Includefile for CIF device driver, DPM layout .
=========================================================================
CHANGES
version name date Discription
March 2001
Juli 2004 Redesigned for the 2.6 Kernel
Copyright changed to GNU Lesser GPL
-------------------------------------------------------------------------
V2.601
======================== Copyright =====================================
Copyright (C) 2004 Hilscher GmbH
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
=========================================================================
******************************************************************** <En> */
#ifndef CIF_TYPES_H
# define CIF_TYPES_H
/* Macros for debugging */
#undef DBG_PRN /* undef it, just in case */
#ifdef CIF_DEBUG
# define CIF_PRN(function, lineno,fmt,args...) printk(fmt,function,lineno,##args)
# define DBG_PRN(fmt,args...) CIF_PRN((__FUNCTION__),(__LINE__),KERN_INFO __FILE__"::%s(L%.4d): "fmt,##args)
#else
# define DBG_PRN(fmt, args...) /* not debugging: nothing */
#endif
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#ifndef BOOL
# define BOOL int
#endif
#endif /* CIF_TYPES_H */

View File

@@ -0,0 +1,495 @@
/* <St> *******************************************************************
cif_user.h
-------------------------------------------------------------------------
CREATETED : D. Tsaava, Hilscher GmbH
DATE : 18.07.2000
PROJEKT : CIF device driver
=========================================================================
DISCRIPTION
User interface definition.
=========================================================================
CHANGES
version name date Discription
Juli 2004 Copyright changed to GNU Lesser GPL
-------------------------------------------------------------------------
V2.000
NOTE: The Code from the Windows version of the driver related to
driver API was taken over for the most part unchanged
======================== Copyright =====================================
Copyright (C) 2004 Hilscher GmbH
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
========================================================================
******************************************************************** <En> */
/* prevent multiple inclusion */
#ifndef CIFUSER_H_INCLUDED
#define CIFUSER_H_INCLUDED
//#ifdef __cplusplus
// extern "C" {
//#endif /* _cplusplus */
#ifndef _GNUC_
# define _GNUC_
#endif /* _GNUC_ */
/* ------------------------------------------------------------------------------------ */
/* global definitions */
/* ------------------------------------------------------------------------------------ */
#define MAX_DEV_BOARDS 4 // maximum numbers of boards
/* ------------------------------------------------------------------------------------ */
/* driver errors */
/* ------------------------------------------------------------------------------------ */
#define DRV_NO_ERROR 0 // no error
#define DRV_BOARD_NOT_INITIALIZED -1 // DRIVER Board not initialized
#define DRV_INIT_STATE_ERROR -2 // DRIVER Error in internal init state
#define DRV_READ_STATE_ERROR -3 // DRIVER Error in internal read state
#define DRV_CMD_ACTIVE -4 // DRIVER Command on this channel is activ
#define DRV_PARAMETER_UNKNOWN -5 // DRIVER Unknown parameter in function occured
#define DRV_WRONG_DRIVER_VERSION -6 // DRIVER Version is incompatible with DLL
#define DRV_PCI_SET_CONFIG_MODE -7 // DRIVER Error during PCI set run mode
#define DRV_PCI_READ_DPM_LENGTH -8 // DRIVER Could not read PCI dual port memory length
#define DRV_PCI_SET_RUN_MODE -9 // DRIVER Error during PCI set run mode
#define DRV_DEV_DPM_ACCESS_ERROR -10 // DEVICE Dual port ram not accessable(board not found)
#define DRV_DEV_NOT_READY -11 // DEVICE Not ready (ready flag failed)
#define DRV_DEV_NOT_RUNNING -12 // DEVICE Not running (running flag failed)
#define DRV_DEV_WATCHDOG_FAILED -13 // DEVICE Watchdog test failed
#define DRV_DEV_OS_VERSION_ERROR -14 // DEVICE Signals wrong OS version
#define DRV_DEV_SYSERR -15 // DEVICE Error in dual port flags
#define DRV_DEV_MAILBOX_FULL -16 // DEVICE Send mailbox is full
#define DRV_DEV_PUT_TIMEOUT -17 // DEVICE PutMessage timeout
#define DRV_DEV_GET_TIMEOUT -18 // DEVICE GetMessage timeout
#define DRV_DEV_GET_NO_MESSAGE -19 // DEVICE No message available
#define DRV_DEV_RESET_TIMEOUT -20 // DEVICE RESET command timeout
#define DRV_DEV_NO_COM_FLAG -21 // DEVICE COM-flag not set
#define DRV_DEV_EXCHANGE_FAILED -22 // DEVICE IO data exchange failed
#define DRV_DEV_EXCHANGE_TIMEOUT -23 // DEVICE IO data exchange timeout
#define DRV_DEV_COM_MODE_UNKNOWN -24 // DEVICE IO data mode unknown
#define DRV_DEV_FUNCTION_FAILED -25 // DEVICE Function call failed
#define DRV_DEV_DPMSIZE_MISMATCH -26 // DEVICE DPM size differs from configuration
#define DRV_DEV_STATE_MODE_UNKNOWN -27 // DEVICE State mode unknown
// Error from Interface functions
#define DRV_USR_OPEN_ERROR -30 // USER Driver not opened (device driver not loaded)
#define DRV_USR_INIT_DRV_ERROR -31 // USER Can't connect with device
#define DRV_USR_NOT_INITIALIZED -32 // USER Board not initialized (DevInitBoard not called)
#define DRV_USR_COMM_ERR -33 // USER IOCTRL function failed
#define DRV_USR_DEV_NUMBER_INVALID -34 // USER Parameter DeviceNumber invalid
#define DRV_USR_INFO_AREA_INVALID -35 // USER Parameter InfoArea unknown
#define DRV_USR_NUMBER_INVALID -36 // USER Parameter Number invalid
#define DRV_USR_MODE_INVALID -37 // USER Parameter Mode invalid
#define DRV_USR_MSG_BUF_NULL_PTR -38 // USER NULL pointer assignment
#define DRV_USR_MSG_BUF_TOO_SHORT -39 // USER Message buffer too short
#define DRV_USR_SIZE_INVALID -40 // USER Parameter Size invalid
#define DRV_USR_SIZE_ZERO -42 // USER Parameter Size with zero length
#define DRV_USR_SIZE_TOO_LONG -43 // USER Parameter Size too long
#define DRV_USR_DEV_PTR_NULL -44 // USER Device address null pointer
#define DRV_USR_BUF_PTR_NULL -45 // USER Pointer to buffer is a null pointer
#define DRV_USR_SENDSIZE_TOO_LONG -46 // USER Parameter SendSize too long
#define DRV_USR_RECVSIZE_TOO_LONG -47 // USER Parameter ReceiveSize too long
#define DRV_USR_SENDBUF_PTR_NULL -48 // USER Pointer to send buffer is a null pointer
#define DRV_USR_RECVBUF_PTR_NULL -49 // USER Pointer to receive buffer is a null pointer
#define DRV_DEV_NO_VIRTUAL_MEM -60 // DEVICE Virtual memory not available
#define DRV_DEV_UNMAP_VIRTUAL_MEM -61 // DEVICE Unmap virtual memory failed
#define DRV_DEV_REQUEST_IRQ_FAILED -62 // DEVICE Request irq failed
#define DRV_USR_FILE_OPEN_FAILED -100 // USER file not opend
#define DRV_USR_FILE_SIZE_ZERO -101 // USER file size zero
#define DRV_USR_FILE_NO_MEMORY -102 // USER not enough memory to load file
#define DRV_USR_FILE_READ_FAILED -103 // USER file read failed
#define DRV_USR_INVALID_FILETYPE -104 // USER file type invalid
#define DRV_USR_FILENAME_INVALID -105 // USER file name not valid
#define DRV_RCS_ERROR_OFFSET 1000 // RCS error number start
#ifdef _GNUC_
# ifndef PACKED
# define PACKED __attribute__((packed, aligned(1)))
# endif /* PACKED */
#else
# define PACKED
#endif
/* ------------------------------------------------------------------------------------ */
/* message definition */
/* ------------------------------------------------------------------------------------ */
// max. length is 288 Bytes, max message length is 255 + 8 Bytes
typedef struct tagMSG_STRUC {
unsigned char rx PACKED;
unsigned char tx PACKED;
unsigned char ln PACKED;
unsigned char nr PACKED;
unsigned char a PACKED;
unsigned char f PACKED;
unsigned char b PACKED;
unsigned char e PACKED;
unsigned char data[255] PACKED;
unsigned char dummy[25] PACKED; // for compatibility with older definitions (288 Bytes)
} MSG_STRUC;
/* ------------------------------------------------------------------------------------ */
/* INFO structure definitions */
/* ------------------------------------------------------------------------------------ */
// Board operation mode
#define POLLING_MODE 0
#define INTERRUPT_MODE 1
// DEVRESET
#define COLDSTART 2
#define WARMSTART 3
#define BOOTSTART 4
// DEVMBXINFO
#define DEVICE_MBX_EMPTY 0
#define DEVICE_MBX_FULL 1
#define HOST_MBX_EMPTY 0
#define HOST_MBX_FULL 1
// TRIGGERWATCHDOG
#define WATCHDOG_STOP 0
#define WATCHDOG_START 1
// GETINFO InfoArea definitions
#define GET_DRIVER_INFO 1
#define GET_VERSION_INFO 2
#define GET_FIRMWARE_INFO 3
#define GET_TASK_INFO 4
#define GET_RCS_INFO 5
#define GET_DEV_INFO 6
#define GET_IO_INFO 7
#define GET_IO_SEND_DATA 8
// HOST mode definition
#define HOST_NOT_READY 0
#define HOST_READY 1
// DEVREADWRITERAW
#define PARAMETER_READ 1
#define PARAMETER_WRITE 2
// STATE definition
#define STATE_ERR_NON 0
#define STATE_ERR 1
#define STATE_MODE_2 2
#define STATE_MODE_3 3
#define STATE_MODE_4 4
// DEVSPECIALCONTROL
#define SPECIAL_CONTROL_CLEAR 0
#define SPECIAL_CONTROL_SET 1
// DEVDOWNLOAD
#define FIRMWARE_DOWNLOAD 1
#define CONFIGURATION_DOWNLOAD 2
// Device exchange IO information
typedef struct tagIOINFO {
unsigned char bComBit PACKED; /* Actual state of the COM bit */
unsigned char bIOExchangeMode PACKED; /* Actual data exchange mode (0..5) */
unsigned long ulIOExchangeCnt PACKED; /* Exchange IO counter */
} IOINFO;
// Device version information
typedef struct tagVERSIONINFO { /* DEV serial number and OS versions */
unsigned long ulDate PACKED;
unsigned long ulDeviceNo PACKED;
unsigned long ulSerialNo PACKED;
unsigned long ulReserved PACKED;
unsigned char abPcOsName0[4] PACKED;
unsigned char abPcOsName1[4] PACKED;
unsigned char abPcOsName2[4] PACKED;
unsigned char abOemIdentifier[4] PACKED;
} VERSIONINFO;
// Device firmware information
typedef struct tagFIRMWAREINFO {
unsigned char abFirmwareName[16] PACKED; /* Firmware name */
unsigned char abFirmwareVersion[16] PACKED; /* Firmware version */
} FIRMWAREINFO;
// Device task state information
typedef struct tagTASKSTATE {
unsigned char abTaskState[64] PACKED; /* Task state field */
} TASKSTATE;
// Device task paramater data
typedef struct tagTASKPARAM {
unsigned char abTaskParameter[64] PACKED; /* Task parameter field */
} TASKPARAM;
// Device raw data structure
typedef struct tagRAWDATA {
unsigned char abRawData[1022] PACKED; /* Definition of the last kByte */
} RAWDATA;
// Device task information
typedef struct tagTASKINFO {
struct {
unsigned char abTaskName[8] PACKED; /* Task name */
unsigned short usTaskVersion PACKED; /* Task version */
unsigned char bTaskCondition PACKED; /* Actual task condition */
unsigned char abreserved[5] PACKED; /* n.c. */
} tTaskInfo [7];
} TASKINFO;
// Device operating system (RCS) information
typedef struct tagRCSINFO {
unsigned short usRcsVersion PACKED; /* Device operating system (RCS) version */
unsigned char bRcsError PACKED; /* Operating system errors */
unsigned char bHostWatchDog PACKED; /* Host watchdog value */
unsigned char bDevWatchDog PACKED; /* Device watchdog value */
unsigned char bSegmentCount PACKED; /* RCS segment free counter */
unsigned char bDeviceAdress PACKED; /* RCS device base address */
unsigned char bDriverType PACKED; /* RCS driver type */
} RCSINFO;
// Device description
typedef struct tagDEVINFO {
unsigned char bDpmSize PACKED; /* Device dpm size (2,8...) */
unsigned char bDevType PACKED; /* Device type (manufactor code) */
unsigned char bDevModel PACKED; /* Device model (manufactor code) */
unsigned char abDevIdentifier[3] PACKED; /* Device identification characters */
} DEVINFO;
/* ------------------------------------------------------------------------------------ */
/* driver info structure definitions */
/* ------------------------------------------------------------------------------------ */
// Board information structure
typedef struct tagBOARD_INFO{
unsigned char abDriverVersion[16] PACKED; // DRV driver information string
struct {
unsigned short usBoard PACKED; // DRV board number
unsigned short usAvailable PACKED; // DRV board is available
unsigned long ulPhysicalAddress PACKED; // DRV physical DPM address
unsigned short usIrq PACKED; // DRV irq number
} tBoard [MAX_DEV_BOARDS];
unsigned short usBoards_detected PACKED;
} BOARD_INFO;
// Internal driver state information structure
typedef struct tagDRIVERINFO{
unsigned long ulOpenCnt PACKED; // DevOpen() counter
unsigned long CloseCnt PACKED; // number of driver close
unsigned long ulReadCnt PACKED; // Number of DevGetMessage commands
unsigned long ulWriteCnt PACKED; // Number of DevPutMessage commands
unsigned long ulIRQCnt PACKED; // Number of board interrupts
unsigned char bInitMsgFlag PACKED; // Actual init sate
unsigned char bReadMsgFlag PACKED; // Actual read mailbox state
unsigned char bWriteMsgFlag PACKED; // Actual write mailbox state
unsigned char bLastFunction PACKED; // Last driver function
unsigned char bWriteState PACKED; // Actual write command state
unsigned char bReadState PACKED; // Actual read command state
unsigned char bHostFlags PACKED; // Actual host flags
unsigned char bMyDevFlags PACKED; // Actual device falgs
unsigned char bExIOFlag PACKED; // Actual IO flags
unsigned long ulExIOCnt PACKED; // DevExchangeIO() counter
} DRIVERINFO;
// Extended board information structure
typedef struct tagBOARD_INFOEX{
unsigned char abDriverVersion[16] PACKED; // DRV driver information string
struct {
unsigned short usBoard PACKED; // DRV board number
unsigned short usAvailable PACKED; // DRV board is available
unsigned long ulPhysicalAddress PACKED; // DRV physical DPM address
unsigned short usIrq PACKED; // DRV irq number
DRIVERINFO tDriverInfo PACKED; // Driver information
FIRMWAREINFO tFirmware PACKED;
DEVINFO tDeviceInfo PACKED;
RCSINFO tRcsInfo PACKED;
VERSIONINFO tVersion PACKED;
} tBoard [MAX_DEV_BOARDS];
} BOARD_INFOEX;
// Communication state field structure
typedef struct tagCOMSTATE {
unsigned short usMode PACKED; // Actual STATE mode
unsigned short usStateFlag PACKED; // State flag
unsigned char abState[64] PACKED; // State area
} COMSTATE;
// state information in bLastFunction
#define FKT_OPEN 1;
#define FKT_CLOSE 2;
#define FKT_READ 3;
#define FKT_WRITE 4;
#define FKT_IO 5;
// state information in bWriteState and bReadState
#define STATE_IN 0x01;
#define STATE_WAIT 0x02;
#define STATE_OUT 0x03;
#define STATE_IN_IRQ 0x04;
/* ------------------------------------------------------------------------------------ */
/* funcion prototypes */
/* ------------------------------------------------------------------------------------ */
extern short DevOpenDriver ( void);
extern short DevCloseDriver ( void);
extern short DevGetBoardInfo ( BOARD_INFO *pvData);
extern short DevInitBoard ( unsigned short usDevNumber);
extern short DevExitBoard ( unsigned short usDevNumber);
extern short DevPutTaskParameter ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
extern short DevReset ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulTimeout);
extern short DevPutMessage ( unsigned short usDevNumber,
MSG_STRUC *ptMessage,
unsigned long ulTimeout);
extern short DevGetMessage ( unsigned short usDevNumber,
unsigned short usSize,
MSG_STRUC *ptMessage,
unsigned long ulTimeout);
extern short DevGetTaskState ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
extern short DevGetMBXState ( unsigned short usDevNumber,
unsigned short *pusDevMBXState,
unsigned short *pusHostMBXState);
extern short DevTriggerWatchDog ( unsigned short usDevNumber,
unsigned short usFunction,
unsigned short *usDevWatchDog);
extern short DevGetInfo ( unsigned short usDevNumber,
unsigned short usFunction,
unsigned short usSize,
void *pvData);
extern short DevGetTaskParameter ( unsigned short usDevNumber,
unsigned short usNumber,
unsigned short usSize,
void *pvData);
extern short DevExchangeIO ( unsigned short usDevNumber,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
unsigned long ulTimeout);
extern short DevReadSendData ( unsigned short usDevNumber,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
extern short DevSetHostState ( unsigned short usDevNumber,
unsigned short usMode,
unsigned long ulTimeout);
extern short DevExtendedData ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usSize,
void *pvData);
extern short DevGetMBXData ( unsigned short usDevNumber,
unsigned short usHostSize,
void *pvHostData,
unsigned short usDevSize,
void *pvDevData);
extern short DevGetBoardInfoEx ( void *pvData);
extern short DevExchangeIOEx ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
unsigned long ulTimeout);
extern short DevExchangeIOErr ( unsigned short usDevNumber,
unsigned short usSendOffset,
unsigned short usSendSize,
void *pvSendData,
unsigned short usReceiveOffset,
unsigned short usReceiveSize,
void *pvReceiveData,
COMSTATE *ptState,
unsigned long ulTimeout);
extern short DevReadWriteDPMRaw ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
extern short DevSpecialControl ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short *pusCtrlAck);
extern short DevDownload ( unsigned short usDevNumber,
unsigned short usMode,
unsigned char *pszFileName,
unsigned long *pdwBytes);
extern short DevReadWriteDPMData ( unsigned short usDevNumber,
unsigned short usMode,
unsigned short usOffset,
unsigned short usSize,
void *pvData);
extern short DevSetOpMode ( unsigned short usBoard,
unsigned short usMode ,
unsigned short *usIrq );
//#ifdef __cplusplus
//}
//#endif
#endif // ifndef CIFUSER_H_INCLUDED

View File

@@ -0,0 +1,16 @@
/* prevent multiple inclusion */
#ifndef DRVSUDEF_H_INCLUDED
#define DRVSUDEF_H_INCLUDED
/* Device state flags */
#define DRV_OPEN 0x8000
#define DEV_INIT 0x0100
#define DEV_INFO 0x0200
#define DEV_INFO_FI 0x0400
#define HOST_RDY 0x0800
#define BOARD_0 0x0001
#define BOARD_1 0x0002
#define BOARD_2 0x0004
#define BOARD_3 0x0008
#endif // DRVSUDEF_H_INCLUDED

View File

@@ -0,0 +1,13 @@
#ifndef log__
#define log__
#define LOG1(x) fprintf(stderr,x)
#define LOG2(x,y) fprintf(stderr,x,y)
#define LOG3(a,b,c) fprintf(stderr,a,b,c)
#define LOG4(a,b,c,d) fprintf(stderr,a,b,c,d)
#define LOG5(a,b,c,d,e) fprintf(stderr,a,b,c,d,e)
#define FLUSH fflush(stderr)
#define LOG_1(a) fprintf(stderr,a)
#define LOG_2(a,b) fprintf(stderr,a,b)
#endif

View File

@@ -0,0 +1,837 @@
/*
Part of Libnodave, a free communication libray for Siemens S7 200/300/400 via
the MPI adapter 6ES7 972-0CA22-0XAC
or MPI adapter 6ES7 972-0CA23-0XAC
or TS adapter 6ES7 972-0CA33-0XAC
or MPI adapter 6ES7 972-0CA11-0XAC,
IBH-NetLink or CPs 243, 343 and 443
(C) Thomas Hergenhahn (thomas.hergenhahn@web.de) 2002..2004
Libnodave is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
Libnodave is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Libnodave; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef CPLUSPLUS
extern "C" {
#endif
#ifndef __nodave
#define __nodave
#ifdef LINUX
#define DECL2
#define EXPORTSPEC
typedef struct {
int rfd;
int wfd;
} _daveOSserialType;
#include <stdlib.h>
#else
#ifdef CYGWIN
typedef struct {
int rfd;
int wfd;
} _daveOSserialType;
#include <stdlib.h>
#else
#ifdef BCCWIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#define DECL2 WINAPI
#define DECL2
#define EXPORTSPEC
/*
#ifdef DOEXPORT
#define EXPORTSPEC __declspec (dllexport)
#else
#define EXPORTSPEC __declspec (dllimport)
#endif
*/
typedef struct {
HANDLE rfd;
HANDLE wfd;
} _daveOSserialType;
#else
#error Fill in what you need for your OS or API.
#endif
#endif
#endif
/*
Define this if your system doesn't have byteswap.h or if you experience difficulties with
the inline functions
*/
/* this is now done in the Makefile: */
/* #define LINUX */
/* #include "log.h" */
/*
some frequently used ASCII control codes:
*/
#define DLE 0x10
#define ETX 0x03
#define STX 0x02
#define SYN 0x16
#define NAK 0x15
/*
Protocol types to be used with newInterface:
*/
#define daveProtoMPI 0 /* MPI for S7 300/400 */
#define daveProtoMPI2 1 /* MPI for S7 300/400, "Andrew's version" */
#define daveProtoMPI3 2 /* MPI for S7 300/400, Step 7 Version, not yet implemented */
#define daveProtoPPI 10 /* PPI for S7 200 */
#define daveProtoISOTCP 122 /* ISO over TCP */
#define daveProtoISOTCP243 123 /* ISO over TCP with CP243 */
#define daveProtoMPI_IBH 223 /* MPI with IBH NetLink MPI to ethernet gateway */
#define daveProtoPPI_IBH 224 /* PPI with IBH NetLink PPI to ethernet gateway */
/*
* ProfiBus speed constants:
*/
#define daveSpeed9k 0
#define daveSpeed19k 1
#define daveSpeed187k 2
#define daveSpeed500k 3
#define daveSpeed1500k 4
#define daveSpeed45k 5
#define daveSpeed93k 6
/*
Some MPI function codes (yet unused ones may be incorrect).
*/
#define daveFuncOpenS7Connection 0xF0
#define daveFuncRead 0x04
#define daveFuncWrite 0x05
#define daveFuncStartUpload 0x1D
#define daveFuncUpload 0x1E
#define daveFuncEndUpload 0x1F
/*
S7 specific constants:
*/
#define daveBlockType_OB '8'
#define daveBlockType_DB 'A'
#define daveBlockType_SDB 'B'
#define daveBlockType_FC 'C'
#define daveBlockType_SFC 'D'
#define daveBlockType_FB 'E'
#define daveBlockType_SFB 'F'
/*
Use these constants for parameter "area" in daveReadBytes and daveWriteBytes
*/
#define daveSysInfo 0x3 /* System info of 200 family */
#define daveSysFlags 0x5 /* System flags of 200 family */
#define daveAnaIn 0x6 /* analog inputs of 200 family */
#define daveAnaOut 0x7 /* analog outputs of 200 family */
#define daveInputs 0x81
#define daveOutputs 0x82
#define daveFlags 0x83
#define daveDB 0x84 /* data blocks */
#define daveDI 0x85 /* not tested */
#define daveLocal 0x86 /* not tested */
#define daveV 0x87 /* don't know what it is */
#define daveCounter 28
#define daveTimer 29
#define daveCounter200 30
#define daveTimer200 31
/**
Library specific:
**/
/*
Result codes. Genarally, 0 means ok,
>0 are results (also errors) reported by the PLC
<0 means error reported by library code.
*/
#define daveResOK 0 /* means all ok */
#define daveResMultipleBitsNotSupported 6 /* CPU tells it does not support to read a bit block with a */
/* length other than 1 bit. */
#define daveResItemNotAvailable200 3 /* means a a piece of data is not available in the CPU, e.g. */
/* when trying to read a non existing DB or bit bloc of length<>1 */
/* This code seems to be specific to 200 family. */
#define daveResItemNotAvailable 10 /* means a a piece of data is not available in the CPU, e.g. */
/* when trying to read a non existing DB */
#define daveAddressOutOfRange 5 /* means the data address is beyond the CPUs address range */
#define daveWriteDataSizeMismatch 7 /* means the write data size doesn't fit item size */
#define daveResCannotEvaluatePDU -123
#define daveResCPUNoData -124
#define daveUnknownError -125
#define daveEmptyResultError -126
#define daveEmptyResultSetError -127
/*
error code to message string conversion:
Call this function to get an explanation for error codes returned by other functions.
*/
EXPORTSPEC char * DECL2 daveStrerror(int code);
/*
Max number of bytes in a single message.
An upper limit for MPI over serial is:
8 transport header
+2*240 max PDU len *2 if every character were a DLE
+3 DLE,ETX and BCC
= 491
Later I saw some programs offering up to 960 bytes in PDU size negotiation
Max number of bytes in a single message.
An upper limit for MPI over serial is:
8 transport header
+2*960 max PDU len *2 if every character were a DLE
+3 DLE,ETX and BCC
= 1931
For now, we take the rounded max of all this to determine our buffer size. This is ok
for PC systems, where one k less or more doesn't matter.
*/
#define daveMaxRawLen 2048
/*
Some definitions for debugging:
*/
#define daveDebugRawRead 0x01 /* Show the single bytes received */
#define daveDebugSpecialChars 0x02 /* Show when special chars are read */
#define daveDebugRawWrite 0x04 /* Show the single bytes written */
#define daveDebugListReachables 0x08 /* Show the steps when determine devices in MPI net */
#define daveDebugInitAdapter 0x10 /* Show the steps when Initilizing the MPI adapter */
#define daveDebugConnect 0x20 /* Show the steps when connecting a PLC */
#define daveDebugPacket 0x40
#define daveDebugByte 0x80
#define daveDebugCompare 0x100
#define daveDebugExchange 0x200
#define daveDebugPDU 0x400 /* debug PDU handling */
#define daveDebugUpload 0x800 /* debug PDU loading program blocks from PLC */
#define daveDebugMPI 0x1000
#define daveDebugPrintErrors 0x2000 /* Print error messages */
#define daveDebugPassive 0x4000
#define daveDebugAll 0xffff
/*
IBH-NetLink packet types:
*/
#define _davePtEmpty -2
#define _davePtMPIAck -3
#define _davePtUnknownMPIFunc -4
#define _davePtUnknownPDUFunc -5
#define _davePtReadResponse 1
#define _davePtWriteResponse 2
extern EXPORTSPEC int daveDebug;
EXPORTSPEC void DECL2 setDebug(int nDebug);
/*
Some data types:
*/
#define uc unsigned char
#define us unsigned short
#define u32 unsigned int
/*
This is a wrapper for the serial or ethernet interface. This is here to make porting easier.
*/
typedef struct _daveConnection daveConnection;
typedef struct _daveInterface daveInterface;
/*
Helper struct to manage PDUs. This is NOT the part of the packet I would call PDU, but
a set of pointers that ease access to the "private parts" of a PDU.
*/
typedef struct {
uc * header; /* pointer to start of PDU (PDU header) */
uc * param; /* pointer to start of parameters inside PDU */
uc * data; /* pointer to start of data inside PDU */
uc * udata; /* pointer to start of data inside PDU */
int hlen; /* header length */
int plen; /* parameter length */
int dlen; /* data length */
int udlen; /* user or result data length */
} PDU;
/*
Definitions of prototypes for the protocol specific functions. The library "switches"
protocol by setting pointers to the protol specific implementations.
*/
typedef int (*_initAdapterFunc) ();
typedef int (*_connectPLCFunc) ();
typedef int (*_disconnectPLCFunc) ();
typedef int (*_disconnectAdapterFunc) ();
typedef int (*_exchangeFunc) (daveConnection *, PDU *);
typedef int (*_sendMessageFunc) (daveConnection *, PDU *);
typedef int (*_getResponseFunc) (daveConnection *);
typedef int (*_listReachablePartnersFunc) (daveInterface * di, char * buf);
/*
This groups an interface together with some information about it's properties
in the library's context.
*/
struct _daveInterface {
_daveOSserialType fd; /* some handle for the serial interface */
int users; /* a counter used when multiple PLCs are accessed via */
/* the same serial interface and adapter. */
int localMPI; /* the adapter's MPI address */
char * name; /* just a name that can be used in programs dealing with multiple */
/* daveInterfaces */
int timeout; /* Timeout in microseconds used in transort. */
int protocol; /* The kind of transport protocol used on this interface. */
int speed; /* The MPI or Profibus speed */
int ackPos; /* position of some packet number that has to be repeated in ackknowledges */
int nextConnection;
_initAdapterFunc initAdapter; /* pointers to the protocol */
_connectPLCFunc connectPLC; /* specific implementations */
_disconnectPLCFunc disconnectPLC; /* of these functions */
_disconnectAdapterFunc disconnectAdapter;
_exchangeFunc exchange;
_sendMessageFunc sendMessage;
_getResponseFunc getResponse;
_listReachablePartnersFunc listReachablePartners;
};
EXPORTSPEC
daveInterface * DECL2 daveNewInterface(_daveOSserialType nfd, char * nname, int localMPI, int protocol, int speed);
/*
This is the packet header used by IBH ethernet NetLink.
*/
typedef struct {
uc ch1; // logical connection or channel ?
uc ch2; // logical connection or channel ?
uc len; // number of bytes counted from the ninth one.
uc packetNumber; // a counter, response packets refer to request packets
us sFlags; // my guess
us rFlags; // my interpretation
} IBHpacket;
/*
Header for MPI packets on IBH-NetLink:
*/
typedef struct {
uc src_conn;
uc dst_conn;
uc MPI;
uc localMPI;
uc len;
uc func;
uc packetNumber;
} MPIheader;
typedef struct {
uc src_conn;
uc dst_conn;
uc MPI;
uc xxx1;
uc xxx2;
uc xx22;
uc len;
uc func;
uc packetNumber;
} MPIheader2;
/*
This holds data for a PLC connection;
*/
struct _daveConnection {
daveInterface * iface; /* pointer to used interface */
int MPIAdr; /* The PLC's address */
int messageNumber; /* current message number */
int needAckNumber; /* message number we need ackknowledge for */
int AnswLen; /* length of last message */
PDU rcvdPDU;
MPIheader templ; /* template of MPI Header, setup once, copied in and then modified */
uc msgIn[daveMaxRawLen];
uc msgOut[daveMaxRawLen];
uc * resultPointer; /* used to retrieve single values from the result byte array */
uc * _resultPointer;
int PDUstartO; /* position of PDU in outgoing messages. This is different for different transport methodes. */
int PDUstartI; /* position of PDU in incoming messages. This is different for different transport methodes. */
int rack; /* rack number for ISO over TCP */
int slot; /* slot number for ISO over TCP */
int maxPDUlength;
int connectionNumber;
int connectionNumber2;
uc packetNumber; /* packetNumber in transport layer */
};
/*
Setup a new connection structure using an initialized
daveInterface and PLC's MPI address.
*/
EXPORTSPEC
daveConnection * DECL2 daveNewConnection(daveInterface * di, int MPI,int rack, int slot);
typedef struct {
uc type[2];
unsigned short count;
} daveBlockTypeEntry;
typedef struct {
unsigned short number;
uc type[2];
} daveBlockEntry;
typedef struct {
uc type[2];
uc x1[2]; /* 00 4A */
uc w1[2]; /* some word var? */
char pp[2]; /* allways 'pp' */
uc x2[4]; /* 00 4A */
unsigned short number; /* the block's number */
uc x3[26]; /* ? */
unsigned short length; /* the block's length */
uc x4[16];
uc name[8];
uc x5[12];
} daveBlockInfo;
/**
PDU handling:
PDU is the central structure present in S7 communication.
It is composed of a 10 or 12 byte header,a parameter block and a data block.
When reading or writing values, the data field is itself composed of a data
header followed by payload data
**/
typedef struct {
uc P; /* allways 0x32 */
uc type; /* Header type, one of 1,2,3 or 7. type 2 and 3 headers are two bytes longer. */
uc a,b; /* currently unknown. Maybe it can be used for long numbers? */
us number; /* A number. This can be used to make sure a received answer */
/* corresponds to the request with the same number. */
us plen; /* length of parameters which follow this header */
us dlen; /* length of data which follow the parameters */
uc result[2]; /* only present in type 2 and 3 headers. This contains error information. */
} PDUHeader;
/*
set up the header. Needs valid header pointer in the struct p points to.
*/
EXPORTSPEC void DECL2 _daveInitPDUheader(PDU * p, int type);
/*
add parameters after header, adjust pointer to data.
needs valid header
*/
EXPORTSPEC void DECL2 _daveAddParam(PDU * p,uc * param,us len);
/*
add data after parameters, set dlen
needs valid header,and valid parameters.
*/
EXPORTSPEC void DECL2 _daveAddData(PDU * p,void * data,int len);
/*
add values after value header in data, adjust dlen and data count.
needs valid header,parameters,data,dlen
*/
EXPORTSPEC void DECL2 _daveAddValue(PDU * p,void * data,int len);
/*
add data in user data. Add a user data header, if not yet present.
*/
EXPORTSPEC void DECL2 _daveAddUserData(PDU * p, uc * da, int len);
/*
set up pointers to the fields of a received message
*/
EXPORTSPEC int DECL2 _daveSetupReceivedPDU(daveConnection * dc,PDU * p);
/*
Get the eror code from a PDU, if one.
*/
EXPORTSPEC int DECL2 daveGetPDUerror(PDU * p);
/*
send PDU to PLC and retrieve the answer
*/
EXPORTSPEC int DECL2 _daveExchange(daveConnection * dc,PDU *p);
/*
retrieve the answer
*/
EXPORTSPEC int DECL2 daveGetResponse(daveConnection * dc);
/*
send PDU to PLC
*/
EXPORTSPEC int DECL2 daveSendMessage(daveConnection * dc, PDU * p);
/******
Utilities:
****/
/*
Hex dump PDU:
*/
EXPORTSPEC void DECL2 _daveDumpPDU(PDU * p);
/*
This is an extended memory compare routine. It can handle don't care and stop flags
in the sample data. A stop flag lets it return success, if there were no mismatches
up to this point.
*/
EXPORTSPEC int DECL2 _daveMemcmp(us * a, uc *b, size_t len);
/*
Hex dump. Write the name followed by len bytes written in hex and a newline:
*/
EXPORTSPEC void DECL2 _daveDump(char * name,uc*b,int len);
/*
name Objects:
*/
EXPORTSPEC char * DECL2 daveBlockName(uc bn);
EXPORTSPEC char * DECL2 daveAreaName(uc n);
/*
Data conversion convenience functions:
*/
EXPORTSPEC int DECL2 daveGetByte(daveConnection * dc);
EXPORTSPEC float DECL2 daveGetFloat(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetInteger(daveConnection * dc);
EXPORTSPEC unsigned int DECL2 daveGetDWORD(daveConnection * dc);
EXPORTSPEC unsigned int DECL2 daveGetUnsignedInteger(daveConnection * dc);
EXPORTSPEC unsigned int DECL2 daveGetWORD(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetByteat(daveConnection * dc, int pos);
EXPORTSPEC unsigned int DECL2 daveGetWORDat(daveConnection * dc, int pos);
EXPORTSPEC unsigned int DECL2 daveGetDWORDat(daveConnection * dc, int pos);
EXPORTSPEC float DECL2 daveGetFloatat(daveConnection * dc, int pos);
/*
int daveGetBytesLeft(daveConnection * dc) {
return ( dc->AnswLen-(int)(dc->resultPointer)+(int)(dc->rcvdPDU.data));
}
*/
EXPORTSPEC float DECL2 toPLCfloat(float ff);
EXPORTSPEC short DECL2 bswap_16(short ff);
EXPORTSPEC int DECL2 bswap_32(int ff);
/**
Newer conversion routines. As the terms WORD, INT, INTEGER etc have different meanings
for users of different programming languages and compilers, I choose to provide a new
set of conversion routines named according to the bit length of the value used. The 'U'
or 'S' stands for unsigned or signed.
**/
/*
Get a value from the position b points to. B is typically a pointer to a buffer that has
been filled with daveReadBytes:
*/
EXPORTSPEC int DECL2 daveGetS8from(uc *b);
EXPORTSPEC int DECL2 daveGetU8from(uc *b);
EXPORTSPEC int DECL2 daveGetS16from(uc *b);
EXPORTSPEC int DECL2 daveGetU16from(uc *b);
EXPORTSPEC int DECL2 daveGetS32from(uc *b);
EXPORTSPEC unsigned int DECL2 daveGetU32from(uc *b);
EXPORTSPEC float DECL2 daveGetFloatfrom(uc *b);
/*
Get a value from the current position in the last result read on the connection dc.
This will increment an internal pointer, so the next value is read from the position
following this value.
*/
EXPORTSPEC int DECL2 daveGetS8(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetU8(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetS16(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetU16(daveConnection * dc);
EXPORTSPEC int DECL2 daveGetS32(daveConnection * dc);
EXPORTSPEC unsigned int DECL2 daveGetU32(daveConnection * dc);
/*
Get a value from a given position in the last result read on the connection dc.
*/
EXPORTSPEC int DECL2 daveGetS8at(daveConnection * dc, int pos);
EXPORTSPEC int DECL2 daveGetU8at(daveConnection * dc, int pos);
EXPORTSPEC int DECL2 daveGetS16at(daveConnection * dc, int pos);
EXPORTSPEC int DECL2 daveGetU16at(daveConnection * dc, int pos);
EXPORTSPEC int DECL2 daveGetS32at(daveConnection * dc, int pos);
EXPORTSPEC unsigned int DECL2 daveGetU32at(daveConnection * dc, int pos);
/*
put one byte into buffer b:
*/
EXPORTSPEC uc * DECL2 davePut8(uc *b,int v);
EXPORTSPEC uc * DECL2 davePut16(uc *b,int v);
EXPORTSPEC uc * DECL2 davePut32(uc *b,int v);
EXPORTSPEC uc * DECL2 davePutFloat(uc *b,float v);
EXPORTSPEC void DECL2 davePut8at(uc *b, int pos, int v);
EXPORTSPEC void DECL2 davePut16at(uc *b, int pos, int v);
EXPORTSPEC void DECL2 davePut32at(uc *b, int pos, int v);
EXPORTSPEC void DECL2 davePutFloatat(uc *b,int pos, float v);
/**
Timer and Counter conversion functions:
**/
/*
get time in seconds from current read position:
*/
EXPORTSPEC float DECL2 daveGetSeconds(daveConnection * dc);
/*
get time in seconds from random position:
*/
EXPORTSPEC float DECL2 daveGetSecondsAt(daveConnection * dc, int pos);
/*
get counter value from current read position:
*/
EXPORTSPEC int DECL2 daveGetCounterValue(daveConnection * dc);
/*
get counter value from random read position:
*/
EXPORTSPEC int DECL2 daveGetCounterValueAt(daveConnection * dc,int pos);
/*
Functions to load blocks from PLC:
*/
EXPORTSPEC void DECL2 _daveConstructUpload(PDU *p,char blockType, int blockNr);
EXPORTSPEC void DECL2 _daveConstructDoUpload(PDU * p, int uploadID);
EXPORTSPEC void DECL2 _daveConstructEndUpload(PDU * p, int uploadID);
/*
Get the PLC's order code as ASCIIZ. Buf must provide space for
21 characters at least.
*/
#define daveOrderCodeSize 21
EXPORTSPEC int DECL2 daveGetOrderCode(daveConnection * dc,char * buf);
/*
connect to a PLC. returns 0 on success.
*/
EXPORTSPEC int DECL2 daveConnectPLC(daveConnection * dc);
/*
Read len bytes from the PLC. Start determines the first byte.
Area denotes whether the data comes from FLAGS, DATA BLOCKS,
INPUTS or OUTPUTS. The reading and writing of other data
like timers and counters is not supported.
DB is the number of the data block to be used. Set it to zero
for other area types.
Buffer is a pointer to a memory block provided by the calling
program. If the pointer is not NULL, the result data will be copied thereto.
Hence it must be big enough to take up the result.
In any case, you can also retrieve the result data using the get<type> macros
on the connection pointer.
FIXME: Existence of DB is not checked.
There is no error message for nonexistent data blocks.
There is no check for max. message len or
automatic splitting into multiple messages.
*/
EXPORTSPEC int DECL2 daveReadBytes(daveConnection * dc, int area, int DB, int start, int len, void * buffer);
/*
Write len bytes from buffer to the PLC.
Start determines the first byte.
Area denotes whether the data goes to FLAGS, DATA BLOCKS,
INPUTS or OUTPUTS. The writing of other data
like timers and counters is not supported.
DB is the number of the data block to be used. Set it to zero
for other area types.
FIXME: Existence of DB is not checked.
There is no error message for nonexistent data blocks.
There is no check for max. message len or
automatic splitting into multiple messages.
*/
EXPORTSPEC int DECL2 daveWriteBytes(daveConnection * dc,int area, int DB, int start, int len, void * buffer);
/*
Bit manipulation:
*/
EXPORTSPEC int DECL2 daveReadBits(daveConnection * dc, int area, int DB, int start, int len, void * buffer);
EXPORTSPEC int DECL2 daveWriteBits(daveConnection * dc,int area, int DB, int start, int len, void * buffer);
/*
PLC diagnostic and inventory functions:
*/
EXPORTSPEC int DECL2 daveReadSZL(daveConnection * dc, int ID, int index, void * buf);
EXPORTSPEC int DECL2 daveListBlocksOfType(daveConnection * dc,uc type,daveBlockEntry * buf);
EXPORTSPEC int DECL2 daveListBlocks(daveConnection * dc,daveBlockTypeEntry * buf);
/*
PLC program read functions:
*/
EXPORTSPEC int DECL2 initUpload(daveConnection * dc,char blockType, int blockNr, int * uploadID);
EXPORTSPEC int DECL2 doUpload(daveConnection*dc, int * more, uc**buffer, int*len, int uploadID);
EXPORTSPEC int DECL2 endUpload(daveConnection*dc, int uploadID);
EXPORTSPEC int DECL2 daveStop(daveConnection*dc);
EXPORTSPEC int DECL2 daveStart(daveConnection*dc);
/*
Multiple variable support:
*/
typedef struct {
int error;
int length;
uc * bytes;
} daveResult;
typedef struct {
int numResults;
daveResult * results;
} daveResultSet;
/* use this to initialize a multivariable read: */
EXPORTSPEC void DECL2 davePrepareReadRequest(daveConnection * dc, PDU *p);
/* Adds a new variable to a prepared request: */
EXPORTSPEC void DECL2 daveAddVarToReadRequest(PDU *p, int area, int DBnum, int start, int bytes);
/* Executes the complete request. */
EXPORTSPEC int DECL2 daveExecReadRequest(daveConnection * dc, PDU *p, daveResultSet * rl);
/* Lets the functions daveGet<data type> work on the n-th result: */
EXPORTSPEC int DECL2 daveUseResult(daveConnection * dc, daveResultSet rl, int n);
/* Frees the memory occupied by the result structure */
EXPORTSPEC void DECL2 daveFreeResults(daveResultSet * rl);
/* Adds a new bit variable to a prepared request: */
EXPORTSPEC void DECL2 daveAddBitVarToReadRequest(PDU *p, int area, int DBnum, int start, int byteCount);
/* use this to initialize a multivariable write: */
EXPORTSPEC void DECL2 davePrepareWriteRequest(daveConnection * dc, PDU *p);
/* Adds a new variable to a prepared request: */
EXPORTSPEC void DECL2 daveAddVarToWriteRequest(PDU *p, int area, int DBnum, int start, int bytes, void * buffer);
/* Adds a new bit variable to a prepared write request: */
EXPORTSPEC void DECL2 daveAddBitVarToWriteRequest(PDU *p, int area, int DBnum, int start, int byteCount, void * buffer);
/* Executes the complete request. */
EXPORTSPEC int DECL2 daveExecWriteRequest(daveConnection * dc, PDU *p, daveResultSet * rl);
EXPORTSPEC int DECL2 daveInitAdapter(daveInterface * di);
EXPORTSPEC int DECL2 daveConnectPLC(daveConnection * dc);
EXPORTSPEC int DECL2 daveDisconnectPLC(daveConnection * dc);
EXPORTSPEC int DECL2 daveDisconnectAdapter(daveInterface * di);
EXPORTSPEC int DECL2 daveListReachablePartners(daveInterface * di,char * buf);
EXPORTSPEC int DECL2 _daveReturnOkDummy(void * dummy);
EXPORTSPEC int DECL2 _daveListReachablePartnersDummy(daveInterface * di,char * buf);
EXPORTSPEC int DECL2 _daveNegPDUlengthRequest(daveConnection * dc, PDU *p);
/* MPI specific functions */
#define daveMPIReachable 0x30
#define daveMPIunused 0x10
#define davePartnerListSize 126
EXPORTSPEC int DECL2 _daveListReachablePartnersMPI(daveInterface * di,char * buf);
EXPORTSPEC int DECL2 _daveInitAdapterMPI1(daveInterface * di);
EXPORTSPEC int DECL2 _daveInitAdapterMPI2(daveInterface * di);
EXPORTSPEC int DECL2 _daveConnectPLCMPI1(daveConnection * dc);
EXPORTSPEC int DECL2 _daveConnectPLCMPI2(daveConnection * dc);
EXPORTSPEC int DECL2 _daveDisconnectPLCMPI(daveConnection * dc);
EXPORTSPEC int DECL2 _daveDisconnectAdapterMPI(daveInterface * di);
EXPORTSPEC int DECL2 _daveExchangeMPI(daveConnection * dc,PDU * p1);
EXPORTSPEC int DECL2 _daveListReachablePartnersMPI3(daveInterface * di,char * buf);
EXPORTSPEC int DECL2 _daveInitAdapterMPI3(daveInterface * di);
EXPORTSPEC int DECL2 _daveConnectPLCMPI3(daveConnection * dc);
EXPORTSPEC int DECL2 _daveDisconnectPLCMPI3(daveConnection * dc);
EXPORTSPEC int DECL2 _daveDisconnectAdapterMPI3(daveInterface * di);
EXPORTSPEC int DECL2 _daveExchangeMPI3(daveConnection * dc,PDU * p1);
/* ISO over TCP specific functions */
EXPORTSPEC int DECL2 _daveExchangeTCP(daveConnection * dc,PDU * p1);
EXPORTSPEC int DECL2 _daveConnectPLCTCP(daveConnection * dc);
/*
make internal PPI functions available for experimental use:
*/
EXPORTSPEC int DECL2 _daveExchangePPI(daveConnection * dc,PDU * p1);
EXPORTSPEC void DECL2 _daveSendLength(daveInterface * di, int len);
EXPORTSPEC void DECL2 _daveSendRequestData(daveConnection * dc, int alt);
EXPORTSPEC void DECL2 _daveSendIt(daveInterface * di, uc * b, int size);
EXPORTSPEC int DECL2 _daveGetResponsePPI(daveConnection *dc);
EXPORTSPEC int DECL2 _daveReadChars(daveInterface * di, uc *b, int tmo, int max);
EXPORTSPEC int DECL2 _daveConnectPLCPPI(daveConnection * dc);
/*
make internal MPI functions available for experimental use:
*/
EXPORTSPEC int DECL2 _daveReadMPI(daveInterface * di, uc *b);
EXPORTSPEC void DECL2 _daveSendSingle(daveInterface * di, uc c);
EXPORTSPEC int DECL2 _daveSendAck(daveConnection * dc, int nr);
EXPORTSPEC int DECL2 _daveGetAck(daveInterface*di, int nr);
EXPORTSPEC int DECL2 _daveSendDialog2(daveConnection * dc, int size);
EXPORTSPEC int DECL2 _daveSendWithPrefix(daveConnection * dc, uc * b, int size);
EXPORTSPEC int DECL2 _daveSendWithPrefix2(daveConnection * dc, int size);
EXPORTSPEC int DECL2 _daveSendWithCRC(daveInterface * di, uc *b, int size);
EXPORTSPEC int DECL2 _daveReadSingle(daveInterface * di);
EXPORTSPEC int DECL2 _daveReadOne(daveInterface * di, uc *b);
EXPORTSPEC int DECL2 _daveReadMPI2(daveInterface * di, uc *b);
EXPORTSPEC int DECL2 _daveGetResponseMPI(daveConnection *dc);
EXPORTSPEC int DECL2 _daveSendMessageMPI(daveConnection * dc, PDU * p);
/*
make internal ISO_TCP functions available for experimental use:
*/
/*
Read one complete packet. The bytes 3 and 4 contain length information.
*/
EXPORTSPEC int DECL2 _daveReadISOPacket(daveInterface * di,uc *b);
EXPORTSPEC int DECL2 _daveGetResponseISO_TCP(daveConnection *dc);
typedef uc * (*userReadFunc) (int , int, int, int, int *);
typedef void (*userWriteFunc) (int , int, int, int, int *,uc *);
extern userReadFunc readCallBack;
extern userWriteFunc writeCallBack;
void _daveConstructReadResponse(PDU * p);
void _daveConstructWriteResponse(PDU * p);
void _daveConstructBadReadResponse(PDU * p);
void _daveHandleRead(PDU * p1,PDU * p2);
EXPORTSPEC void _daveHandleWrite(PDU * p1,PDU * p2);
/*
make internal IBH functions available for experimental use:
*/
EXPORTSPEC int DECL2 _daveReadIBHPacket(daveInterface * di,uc *b);
EXPORTSPEC int DECL2 _daveWriteIBH(daveInterface * di, void * buffer, int len);
EXPORTSPEC int DECL2 _davePackPDU(daveConnection * dc,PDU *p);
EXPORTSPEC void DECL2 _daveSendIBHNetAck(daveConnection * dc);
EXPORTSPEC int DECL2 _daveExchangeIBH(daveConnection * dc, PDU * p);
EXPORTSPEC int DECL2 _daveConnectPLC_IBH(daveConnection*dc);
EXPORTSPEC int DECL2 _daveDisconnectPLC_IBH(daveConnection*dc);
EXPORTSPEC void DECL2 _daveSendMPIAck2(daveConnection *dc);
EXPORTSPEC int DECL2 _daveGetResponseMPI_IBH(daveConnection *dc);
EXPORTSPEC int DECL2 _daveSendMessageMPI_IBH(daveConnection * dc, PDU * p);
EXPORTSPEC int DECL2 _daveListReachablePartnersMPI_IBH(daveInterface *di, char * buf);
#endif /* _nodave */
#ifdef CPLUSPLUS
}
#endif
/*
Changes:
07/19/04 added the definition of daveExchange().
09/09/04 applied patch for variable Profibus speed from Andrew Rostovtsew.
09/09/04 applied patch from Bryan D. Payne to make this compile under Cygwin and/or newer gcc.
12/09/04 added daveReadBits(), daveWriteBits()
12/09/04 added some more comments.
12/09/04 changed declaration of _daveMemcmp to use typed pointers.
01/15/04 generic getResponse, more internal functions, use a single dummy to replace
initAdapterDummy,
01/26/05 replaced _daveConstructReadRequest by the sequence prepareReadRequest, addVarToReadRequest
01/26/05 added multiple write
02/02/05 added readIBHpacket
02/06/05 replaced _daveConstructBitWriteRequest by the sequence prepareWriteRequest, addBitVarToWriteRequest
02/08/05 removed inline functions.
*/

View File

@@ -0,0 +1,76 @@
/* <St> *******************************************************************
FILENAME : NVR_USER.H
-------------------------------------------------------------------------
CREATED BY : R. Mayer, Hilscher GmbH
CREATED AT : 29.05.96
PROJECT : NVR
=========================================================================
FUNCTION :
User interface NVR protocol
=========================================================================
CHANGES OF REVISIONS :
Version Name Date Change
-------------------------------------------------------------------------
V1.000 Mayer 29.05.96 Created
******************************************************************** <En> */
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack(1) /* Byte Alignment */
#endif
/* ======================================================================== */
/* Protocol definition */
/* ======================================================================== */
#define NVR_MODE_MSB_LSB 0
#define NVR_MODE_LSB_MSB 1
#define NVR_MODE_BYTE 2
#define NVR_MODE_TRANSPARENT 3
/* ======================================================================== */
/* Protocol parameter structure */
/* ======================================================================== */
typedef struct NVR_PARAMETRtag {
unsigned char bScl; /* Communication line number */
unsigned char bRtsControl; /* RTS control */
unsigned char bBaudrate; /* Baudrate */
unsigned char bDataBits; /* Number of data bits */
unsigned char bStopBits; /* Number of stop bits */
unsigned char bParityBit; /* Parity */
unsigned char bPriority; /* Priority */
unsigned short usTimeout; /* Timeout */
unsigned char bReceiveMode; /* Receive mode */
unsigned char bSendMode; /* Send mode */
unsigned char bErrorLed; /* Mode of the error LED */
} NVR_PARAMETER;
/* ======================================================================== */
/* Protocol task state structure */
/* ======================================================================== */
typedef struct NVR_STATEtag {
unsigned char bTaskState; /* Task state */
unsigned long ulTxCount; /* Transmitt telegram count */
unsigned long ulRxCount; /* Receive telegram count */
unsigned char bTxRetryCount; /* Number of transmitt retries */
unsigned char bRxRetryCount; /* Number of receive retries */
unsigned short usTxErrorCount; /* Transmitt error count */
unsigned short usRxErrorCount; /* Receive error count */
unsigned short usErrorBits; /* Error bits */
unsigned char bError; /* Last error */
} NVR_STATE;
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack() /* Byte Alignment */
#endif

View File

@@ -0,0 +1,124 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Bräutigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef OBJDIR
#define OBJDIR
#include <iostream>
using std::cin;
using std::cout;
#include "rlinifile.h"
#include <stdlib.h>
#include <qstring.h>
#include <qptrvector.h>
#define ACSII_CODE_CARRIAGE_RETURN 13
//! class which handles the object directory of a node
class ObjDir
{
public:
//! enum contains all values saved in one objdir entry
enum Obj_Parameters{
OBJNUMBER,
SUBNUMBER,
PARAMETERNAME,
OBJECTTYPE,
DATATYPE,
ACCESSTYPE,
DEFAULTVALUE,
PDOMAPPING
};
//! empty constructor not yet implemented
ObjDir();
//! nothing to do. QPtrVector Destructor performs memory cleanup.
~ObjDir();
/*! main constructor builds object directory. It recieves a pointer to a
rlIniFile object which is allready initialized with an EDS file. Calls
countobj to resize QPtrVector. Calls extraktobj to extrakt all objects
from an eds-object category (MandatoryObjects or OptionalObjects). */
ObjDir(rlIniFile* _ini);
/*! returns a specific parameter identified by _paramtype from an object
directory entry, identified by objectindex and subindex. */
QString get_objparameter( Obj_Parameters _paramtype, int _obj, int _sub );
//! iterates through whole objectdir and returns 1 when given object exists
int OVAdressExists( int _obj, int _sub );
private:
/*! this class contains all data of an object diretory entry*/
class ObjItem
{
public:
/*! constructor initializes item-data */
ObjItem( QString _objnumber,
QString _subnumber,
QString _parametername,
QString _objecttype,
QString _datatype,
QString _accesstype,
QString _defaultvalue,
QString _pdomapping ):
objnumber (_objnumber),
subnumber (_subnumber),
parametername (_parametername),
objecttype (_objecttype),
datatype (_datatype),
accesstype (_accesstype),
defaultvalue (_defaultvalue),
pdomapping (_pdomapping) {};
QString objnumber;
QString subnumber;
QString parametername;
QString objecttype;
QString datatype;
QString accesstype;
QString defaultvalue;
QString pdomapping;
};
//! object which manages a dynamic list of all objects in memory
QPtrVector<ObjItem> objstorage;
//! pointer to inifile, previously initialized by cannode object
rlIniFile* ini;
//! output function for debbuging purposes only
void dout(const char* _str);
/*! creates a new ObjItem and adds it to the objstorage. iniheadline must
be generated previously from objectindex and subindex number */
int additem(QString _objname, QString _iniheadline, int _subint);
/*! iterates through all items of given category. extracts objnames.
iterates through all subindexes of objname and calls additem. */
int extraktobj(QString _categoryname, int _objcount);
/*! similar to extraktobj but only counts number of available objects */
int countobj(QString _categoryname, int _objcount);
int itemcount;
};
#endif

View File

@@ -0,0 +1,251 @@
/* <St> *******************************************************************
FILENAME : RCS_USER.H
-------------------------------------------------------------------------
CREATED BY : R.Mayer, Hilscher GmbH
CREATED AT : 10.05.96
PROJECT : global
=========================================================================
FUNCTION :
General RCS definitions
=========================================================================
CHANGES OF REVISIONS :
Version Name Date Change
-------------------------------------------------------------------------
V1.002 Mayer 14.05.98 RCS_TELEGRAMHEADERDATA_10 structure included
V1.001 Mayer 29.05.96 Task errors included
V1.000 Mayer 10.05.96 created from the file rc090203.h
******************************************************************** <En> */
//#ifdef __cplusplus
//}
//#endif
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack(1) /* Byte Alignment */
#endif
/* ======================================================================== */
/* General task errors */
/* ======================================================================== */
#define TASK_F_OK 0
#define TASK_F_NO_COMMUNICATION 1
#define TASK_F_IDLE 2
#define TASK_F_INIT_BASE 50
#define TASK_F_PARITY 100
#define TASK_F_FRAMING 101
#define TASK_F_OVERRUN 102
#define TASK_F_DATACOUNT 103
#define TASK_F_CHECKSUM 104
#define TASK_F_TIMEOUT 105
#define TASK_F_PROTOCOL 106
#define TASK_F_DATA 107
#define TASK_F_NACK 108
#define TASK_F_PROTOCOL_BASE 110
#define TASK_F_MESSAGEHEADER 150
#define TASK_F_MESSAGESIZE 151
#define TASK_F_MESSAGECOMMAND 152
#define TASK_F_MESSAGESTRUCTURE 153
#define TASK_F_MESSAGEERROR 154
#define TASK_F_MESSAGETIMEOUT 155
#define TASK_F_TELEGRAMHEADER 160
#define TASK_F_DEVICE_ADR 161
#define TASK_F_DATA_AREA 162
#define TASK_F_DATA_ADR 163
#define TASK_F_DATA_IDX 164
#define TASK_F_DATA_CNT 165
#define TASK_F_DATA_TYPE 166
#define TASK_F_FUNCTION 167
#define TASK_F_MESSAGE_BASE 170
#define TASK_F_NOT_INITIALIZED 200
#define TASK_F_BUSY 201
#define TASK_F_SEGMENT 202
#define TASK_F_USER 203
#define TASK_F_DATABASE 210
#define TASK_F_DATABASE_WRITE 211
#define TASK_F_DATABASE_READ 212
#define TASK_F_STRUCTURE 213
#define TASK_F_PARAMETER 214
#define TASK_F_CONFIGURATION 215
#define TASK_F_FUNCTIONLIST 216
#define TASK_F_SYSTEM 217
#define TASK_F_SYSTEM_BASE 220
/* ======================================================================== */
/* Task commands */
/* ======================================================================== */
#define TASK_B_10 16 /* RCS_TELEGRAMHEADER_10 */
#define TASK_B_11 17 /* Task specific */
/* ======================================================================== */
/* Message definitions */
/* ======================================================================== */
/* ----------------- Definition of the standard telegram header ----------- */
/* Keyword: MESSAGE ---------------------------------------------------- */
/* TelegramFunCtion */
#define TASK_TFC_UNUSED 0
#define TASK_TFC_READ 1
#define TASK_TFC_WRITE 2
#define TASK_TFC_QUERRY 3
/* TelegramDataArea */
/* 'data_area' */
#define TASK_TDA_UNUSED 0
#define TASK_TDA_BIT 1
#define TASK_TDA_BYTE 2
#define TASK_TDA_WORD 3
#define TASK_TDA_DWORD 4
#define TASK_TDA_FLOAT 5
/* TelegramDataType */
/* 'data_type' for MOTOROLA data types ! */
/* For INTEL data types, the 'RCS_TDT_IDF_MASK' flag must be set */
#define TASK_TDT_UNUSED 0
#define TASK_TDT_BOOLEAN 1
#define TASK_TDT_INT8 2
#define TASK_TDT_INT16 3
#define TASK_TDT_INT32 4
#define TASK_TDT_UINT8 5
#define TASK_TDT_UINT16 6
#define TASK_TDT_UINT32 7
#define TASK_TDT_FLOAT 8
#define TASK_TDT_ASCII 9
#define TASK_TDT_STRING 10
#define TASK_TDT_BIT 14
#define TASK_TDT_IDF_MSK 0X80
/* ======================================================================== */
/* Message structure definitions */
/* ======================================================================== */
/* -------------------- General RCS definitions -------------------------- */
/* Keyword: MESSAGE ------------------------------------------------------ */
#define RCS_SEGMENT_LEN 288
#define RCS_MESSAGEHEADER_LEN 8
#define RCS_TELEGRAMHEADER_LEN 8
/* ------------------------ RCS message definition ------------------------ */
typedef struct RCS_MESSAGEHEADERtag {
unsigned char rx; /* receiver */
unsigned char tx; /* transmitter */
unsigned char ln; /* lenght */
unsigned char nr; /* number */
unsigned char a; /* answer */
unsigned char f; /* fault */
unsigned char b; /* command */
unsigned char e; /* extension */
} RCS_MESSAGEHEADER;
typedef struct RCS_MESSAGEtag {
unsigned char rx; /* receiver */
unsigned char tx; /* transmitter */
unsigned char ln; /* lenght */
unsigned char nr; /* number */
unsigned char a; /* answer */
unsigned char f; /* fault */
unsigned char b; /* command */
unsigned char e; /* extension */
unsigned char d[ RCS_SEGMENT_LEN-RCS_MESSAGEHEADER_LEN ]; /* data */
} RCS_MESSAGE;
/* ----------------- Standard telegram header ----------------------------- */
/* Keyword: MESSAGE, TASK_B_10 --------------------------------------------*/
typedef struct RCS_TELEGRAMHEADER_10tag {
unsigned char device_adr; /* device address */
unsigned char data_area; /* data area */
unsigned short data_adr; /* data address */
unsigned char data_idx; /* data index */
unsigned char data_cnt; /* data count */
unsigned char data_type; /* data type */
unsigned char function; /* function */
} RCS_TELEGRAMHEADER_10;
typedef struct RCS_MESSAGETELEGRAMHEADER_10_tag {
unsigned char rx; /* receiver */
unsigned char tx; /* transmitter */
unsigned char ln; /* lenght */
unsigned char nr; /* number */
unsigned char a; /* answer */
unsigned char f; /* fault */
unsigned char b; /* command */
unsigned char e; /* extension */
unsigned char device_adr; /* device address */
unsigned char data_area; /* data area */
unsigned short data_adr; /* data address */
unsigned char data_idx; /* data index */
unsigned char data_cnt; /* data count */
unsigned char data_type; /* data type */
unsigned char function; /* function */
} RCS_MESSAGETELEGRAMHEADER_10;
typedef struct RCS_TELEGRAMHEADERDATA_10tag {
unsigned char device_adr;
unsigned char data_area;
unsigned short data_adr;
unsigned char data_idx;
unsigned char data_cnt;
unsigned char data_type;
unsigned char function;
unsigned char d[ RCS_SEGMENT_LEN-RCS_MESSAGEHEADER_LEN-RCS_TELEGRAMHEADER_LEN];
} RCS_TELEGRAMHEADERDATA_10;
typedef struct RCS_MESSAGETELEGRAM_10tag {
unsigned char rx; /* receiver */
unsigned char tx; /* transmitter */
unsigned char ln; /* lenght */
unsigned char nr; /* number */
unsigned char a; /* answer */
unsigned char f; /* fault */
unsigned char b; /* command */
unsigned char e; /* extension */
unsigned char device_adr; /* device address */
unsigned char data_area; /* data area */
unsigned short data_adr; /* data address */
unsigned char data_idx; /* data index */
unsigned char data_cnt; /* data count */
unsigned char data_type; /* data type */
unsigned char function; /* function */
unsigned char d[ RCS_SEGMENT_LEN-RCS_MESSAGEHEADER_LEN-RCS_TELEGRAMHEADER_LEN];
} RCS_MESSAGETELEGRAM_10;
#if defined( _MSC_VER) /* Microsoft C */
#pragma pack() /* Byte Alignment */
#endif
//#ifdef __cplusplus
//}
//#endif
/* === eof 'RCS_USER.H' === */

View File

@@ -0,0 +1,139 @@
/* <St> *******************************************************************
FILENAME : RcsDef.h
-------------------------------------------------------------------------
CREATED BY : R.Mayer, Hilscher GmbH
CREATED AT : 10.03.97
PROJECT :
=========================================================================
FUNCTION / CLASSDESCRIPTION:
=========================================================================
CHANGES OF REVISIONS :
Version Name Date Change
-------------------------------------------------------------------------
1.000 RM 10.03.97 Created
******************************************************************** <En> */
// Prevent multiple inclusion
#ifndef __RCSDEF_H__
#define __RCSDEF_H__
#ifdef _cplusplus
extern "C" {
#endif /* _cplusplus */
#define FIRMWARE_DOWNLOAD 1
#define CONFIGURATION_DOWNLOAD 2
/* ======================================================================== */
/* Message definitions */
/* ======================================================================== */
#define RCS_TASK 0x00 /* Number of RCS */
#define PLC_TASK 0x02 /* Number for PLC_TASK */
#define MSG_SYSTEM_TX 0xFF /* Transmitter for system functions number */
#define RCS_B_TASK_STATE 4 // Task state
/************************************************************************** */
/* Genaral RCS commands */
/************************************************************************** */
#define RCS_B_SYSFKT 1
#define RCS_B_TASKFKT 2
#define RCS_B_DIAGNOSE 3
#define RCS_B_STRUCTFNC 4
#define RCS_B_TRACE 5
#define RCS_B_LOADFKT 6
#define RCS_B_DBMFKT 10
/* ----------------------- */
/* Message extension masks */
/* ----------------------- */
#define RCS_FIFO_MSK 0
#define RCS_LIFO_MSK 1
#define RCS_NAK_MSK 2
#define RCS_NORM_MSK 0
#define RCS_FIRST_MSK 4
#define RCS_CONT_MSK 8
#define RCS_LAST_MSK 0x0C
#define RCS_SEQ_MSK 0x0C
/* ------------------ */
/* Mode definitions */
/* ------------------ */
#define MODE_NEUSTART 0 /* Command: B_SYSFKT */
#define MODE_KALTSTART 1 /* Command: B_SYSFKT */
#define MODE_WARMSTART 2 /* Command: B_SYSFKT */
#define MODE_ZYKL_STATUS_STOP 3 /* Command: B_SYSFKT */
#define MODE_FWVERSION 4 /* Command: B_SYSFKT */
#define MODE_GET_PROJ_WERTE_HW 5 /* Command: B_SYSFKT */
#define MODE_GET_PROJ_WERTE_SW 6 /* Command: B_SYSFKT */
#define MODE_SHOW_DYN_SYSSTAT 7 /* Command: B_SYSFKT */
#define MODE_SETTIME 9 /* not implemented yet */
#define MODE_SET_DEVICE_DATA 9 /* not implemented yet */
#define MODE_MODUL_RCS 11 /* Command: B_SYSFKT */
#define MODE_MODUL_LIB 12 /* Command: B_SYSFKT */
#define MODE_MODUL_MCL 13 /* Command: B_SYSFKT */
#define MODE_MODUL_LIB 12 /* Command: B_SYSFKT */
#define MODE_MODUL_MCL 13 /* Command: B_SYSFKT */
#define MODE_DISTRIBUTOR_DRIVER 14 /* Command: B_SYSFKT ->function 1 = insert */
#define MODE_PRINT_DRIVER 15 /* Command: B_SYSFKT */
#define MODE_GET_RCS_ERROR 16 /* Command: B_SYSFKT */
#define MODE_PRINT_DEVICE 1 /* NO mode, only for MENU.H */
#define MODE_PRINT_DEVICE_DRIVER 2 /* NO mode, only for MENU.H */
#define MODE_START_STOP_STAT 0 /* Command: B_TASKFKT */
#define MODE_START_STOP 1 /* Command: B_TASKFKT */
#define MODE_TASK_VERSION 2 /* Command: B_TASKFKT */
#define MODE_ZYKL_STATUS 3 /* Command: B_TASKFKT */
#define MODE_SHOW_FUELLST 4 /* Command: B_TASKFKT */
#define MODE_SHOW_TIMER 5 /* Command: B_TASKFKT */
#define MODE_DIAG_MEM_READ_SINGLE 0x0 /* Command: B_DIAGNOSE */
#define MODE_DIAG_MEM_WRITE_SINGLE 0x1 /* Command: B_DIAGNOSE */
#define MODE_DIAG_IO_READ_SINGLE 0x2 /* Command: B_STRUKTFKT */
#define MODE_DIAG_IO_WRITE_SINGLE 0x3 /* Command: B_STRUKTFKT */
#define MODE_DIAG_ZYKL 0x10 /* Command: B_STRUKTFKT */
#define MODE_DIAG_MEM_READ_ZYKL 0x10 /* Command: B_STRUKTFKT */
#define MODE_DIAG_MEM_WRITE_ZYKL 0x11 /* Command: B_STRUKTFKT */
#define MODE_DIAG_IO_READ_ZYKL 0x12 /* Command: B_STRUKTFKT */
#define MODE_DIAG_IO_WRITE_ZYKL 0x13 /* Command: B_STRUKTFKT */
#define MODE_ZYKL_TASK_STRUK 0 /* Command: B_STRUKTFKT */
#define MODE_INIT_INFO_STRUK 1 /* Command: B_STRUKTFKT */
#define MODE_WRITE_STRUK 2 /* Command: B_STRUKTFKT */
#define MODE_START_TRACE 0 /* Command: B_TRACE */
#define MODE_DEL_TRACE_PUF 1 /* Command: B_TRACE */
#define MODE_UPLOAD_BINAER 0 /* Command: B_LOADFKT */
#define MODE_DOWNLOAD_BINAER 1 /* Command: B_LOADFKT */
#define MODE_UPLOAD_DBM 2 /* Command: B_LOADFKT */
#define MODE_DOWNLOAD_DBM 3 /* Command: B_LOADFKT */
#define MODE_DEL_FLASH 4 /* Command: B_LOADFKT */
#define MODE_GET_FLASH_DIR 5 /* Command: B_LOADFKT */
#define MODE_URLADEN 6 /* Command: B_LOADFKT */
#define MODE_LONG_BINLOAD 7 /* Command: B_LOADFKT */
#define MODE_FREE_DRIVER 8 /* Command: B_LOADFKT */
#define MODE_RESET_DEVICE 10 /* Command: B_LOADFKT */
/* ------------------------------------------------------------------------------------ */
#ifdef _cplusplus
}
#endif
#endif
// ======== eof 'RcsDef.h' ========

View File

@@ -0,0 +1,63 @@
/***************************************************************************
rl3964r.h - description
-------------------
begin : Wed Jan 14 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_3964R_H_
#define _RL_3964R_H_
#include "rldefine.h"
#include "rlserial.h"
#include "rlthread.h"
/*! <pre>
This class implements the siemens 3964R dust protocol.
The read messages must be handled within the callback routine.
</pre> */
class rl3964R
{
public:
enum priorityEnum
{
highPriority = 0,
lowPriority
};
rl3964R(int _priority = highPriority);
virtual ~rl3964R();
int open(const char *devicename, int _baudrate = B9600);
int close();
int setReadCallback( void (*_readCallback)(const unsigned char *buf, int len));
int write(const unsigned char *buf, int len);
int send();
int receive();
rlThread receiver;
rlSerial tty;
int state;
int priority;
int run;
int debug;
int dprintf(const char *format, ...);
private:
void (*readCallback)(const unsigned char *buf, int len);
unsigned char tel_send[512];
unsigned char tel_receive[512];
int tel_send_length;
int tel_receive_length;
int isOpen;
int send_result;
};
#endif

View File

@@ -0,0 +1,46 @@
/***************************************************************************
rlbuffer.h - description
-------------------
begin : Sun Aug 24 2014
copyright : (C) 2014 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_BUFFER_H_
#define _RL_BUFFER_H_
#include "rldefine.h"
/*! <pre>
class for handling memory buffers.
</pre> */
class rlBuffer
{
public:
rlBuffer();
virtual ~rlBuffer();
int resize(int size);
int size();
int setText(const char *text);
char *line(int i);
void *adr;
char *c;
unsigned char *uc;
int *i;
unsigned int *ui;
long *l;
unsigned long *ul;
float *f;
double *d;
private:
int _size;
};
#endif

View File

@@ -0,0 +1,45 @@
/***************************************************************************
rlbussignaldatabase.h - description
-------------------
begin : Mon Aug 02 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_BUSSIGNAL_DATABASE_H_
#define _RL_BUSSIGNAL_DATABASE_H_
#include "rldefine.h"
class rlBussignalDatabase
{
public:
rlBussignalDatabase();
virtual ~rlBussignalDatabase();
int openDatabase(const char *database, const char *table);
int writeDatabaseInt(const char *item, int val);
int writeDatabaseIntArray(const char *item, int *val, int len);
int writeDatabaseFloat(const char *item, float val);
int writeDatabaseFloatArray(const char *item, float *val, int len);
int writeDatabaseString(const char *item, char *val);
int readDatabase(const char *item, char *type, char *value);
int closeDatabase();
private:
int writeDatabaseString(const char *item);
int myquery(const char *query);
void *database;
void *connection;
char *databaseName;
char *tableName;
char buf[rl_PRINTF_LENGTH];
char typebuf[16];
};
#endif

View File

@@ -0,0 +1,137 @@
/***************************************************************************
cannode.h - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
authors : Marc Br<42>tigam, Christian Wilmes
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef NODE
#define NODE
#include "rldefine.h"
#include <iostream>
using std::cin;
using std::cout;
#include <qptrvector.h>
#include <qdir.h>
#include <qstring.h>
#include <qstringlist.h>
#include "rlcanopenstructs.h"
#include "rlcanopentypes.h"
#include "rlinifile.h"
#ifndef TOOL
#define TOOL
//#include "ToolBox.cpp"
#endif
#include "objdir.h" /* Include file for EDS file manager */
#include "cif_user.h" /* Include file for device driver API */
#include "rcs_user.h" /* Include file for RCS definition */
#include "asc_user.h" /* Include file for ASCII protocols */
#include "nvr_user.h" /* Include file for 3964R protocol */
#include "COM_USER.H"
//! class to manage one node of a CanOpenMaster board in a CanOpen network
class rlCanNode
{
public:
rlCanNode ();
/*! initializes a new node obj. node is defined by boardid, nodeid and a
telegram which contains node specific information from device's dual
ported memory */
rlCanNode (int boardnr, int nodeid, RCS_MESSAGETELEGRAM_10& _telegramm);
//! calls destructors of rlinifile obj and objdir
~rlCanNode();
//!returns the type of a specific entry in the object directory
int objecttype(int objindex, int subindex);
//!prints out the configuration of the node
void showConfiguration();
//!returns the current node ID of the node
int getNodeID();
//!returns the board ID the node is connected to.
int getBoardID();
//!returns the current number of all installed PDOs (Process Data Objects)
int getPdoCount();
//!returns the current number of all installed reiceive PDOs
int getReceivePdoCount();
//!returns the current number of all installed transmit PDOs
int getTransmitPdoCount();
/*! indicates if node mapping is available. When mapping is active, it is
possible to catch a specific Object within a PDO */
bool hasMapping();
//! contains transmit PDOs
//QPtrVector<rlCanPDO> transmit_pdoList;
//! contains receive PDOs
//QPtrVector<rlCanPDO> receive_pdoList;
// RECEIVE_LIST = 0
// TRANSMIT_LIST = 1
QPtrVector<rlCanPDO> pdoList[2];
private:
//! current node ID (1-127)
int nodeID;
//! curent board ID (0-3)
int boardID;
/*! iterates through all files in eds directory. opens every eds file and
returns a pointer to an ini-file object of the eds file matching the
product string in [DeviceInfo] ProductName */
rlIniFile* getEDS(const char* _productstr);
/*! pointer to inifile. object which handles access to the EDS file
describing the object directory of this node */
rlIniFile* ini;
/*! pointer to objdir which handles access to all items in the object
directory of this node */
ObjDir* objdir;
/*! reads out the configuration of a node from the device.
For success the device must configured by SYCon. */
void readConfigurationMessage(RCS_MESSAGETELEGRAM_10& _message);
//!Unique device number if available.
unsigned short usIdentNumber;
//!Unique vendor number if available.
unsigned char usVendorIdent;
//! specific node informations. extracted from message telegramm
QString abVendorName;
QString abDeviceName;
QString abDescription;
QString edslocation;
unsigned char pdocount;
unsigned char bMasterAddress;
unsigned char bSettings;
};
#endif

View File

@@ -0,0 +1,285 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Br<42>tigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/*!
* \section intro Introduction to rlCANopen-API
*
* The rlCANopen-Software represents a developer friendly interface for
* Hilscher CANopen Mastercard users, which ensures a comfortable
* access to CANopen nodes and also Linux and Win32 portability.
*
* Using the Server-Client-architecture a network-wide availability of
* data is feasible.
*
* <img src="uebersicht_engl.jpg">
*/
#ifndef NODES
#define NODES
#define err00 "no error, command executed"
#define err03 "DESCRIPT table not found. DEVICE is not configured by SyCon"
#define err57 "sequence error. Check requested DeviceAdr of continued message"
#define err58 "no entry found for requested DeviceAdr of request message."
#define err100 "Communication ERROR!!!"
#include "rlwthread.h"
#include "rlcannode.h"
#include <qvaluevector.h>
#include <qptrvector.h>
//! main class which provides canopen API functions and manages all nodes.
/*! This class contains a canopen specific API which accesses the canopen bus
through the bus-independ Hilscher device API. It reads the configuration
which has to be written previously to the device by SyCon. Based on this
configuration data it searches node corresponding EDS files to create
object directories. These help to enshure type security and cast warnings
when users try to write incorrect data types to can nodes.
*/
class rlCanOpen
{
public:
rlCanOpen();
rlCanOpen(char* _inifilename);
~rlCanOpen();
//! returns the number of available boards
int getBoardCount();
//! returns the number of currently active board
int getActiveBoard();
//! prints out the configuration of a specific node
bool showNodeConfiguration(int _boardnr,int _nodeid);
//! prints out the configuration off all available nodes from all boards
bool showNodeConfiguration(); // show all nodes
/*! using the sdo_read function you can read a certain object from the object
dictionary of a node. For this the SDO (Service Data Object) service
will be used. The enquired object will be written to the rlCanOpenTypes
class. To read out the correct value from this class use one of the
get_TYPE() {e.g. get_int() } functions. You can assert the type in the
class using rlCanOpenTypes::get_DaemonType();
if sdo_read failures the current error can be read out using
rlCanOpenTypes::get_rlmsgerr()*/
int sdo_read ( int _boardnr,
int _nodeid,
int _objectindex,
int _subindex,
rlCanOpenTypes &_sdo_data);
/*! using the sdo_write function you can write to a certain object from the
object dictionary of a node. For this the SDO (Service Data Object)
Service will be used. The relevant data must be written into the
rlCanOpenTypes class before. To write the data into the rlCanOpenTypes
class use one of the datatype depending functions like
rlCanOpenTypes::set_int(int _value);
if sdo_write failures the current error can be read out using
rlCanOpenTypes::get_rlmsgerr()*/
int sdo_write ( int _boardnr,
int _nodeid,
int _objectindex,
int _subindex,
rlCanOpenTypes &_sdo_data);
/*! using the pdo_receive function you can receive a PDO (Process Data Object),
which is send from the specific node to the device. The enquired object
will be written to the rlCanOpenTypes class.
The mapping is only available if mapping is configurated during the node
creation of the rlcanopen constructer. Therefore a eds file (electronic
data sheet) is needed. Use the cannode::hasMapping() function to check
if mapping is available. To read out the correct value from this class
use one of the get_TYPE() {e.g. get_int() } functions you can assert the
type in the class using rlCanOpenTypes::get_DaemonType(); */
int pdo_receive( int _boardnr,
int _nodeid,
int _pdonr,
int _mappingnr,
rlCanOpenTypes &_pdo_data);
/*! using the pdo_receive function you can receive a PDO (Process Data Object),
which is send from the specific node to the canOpen master card. The data
will be written to the rlCanOpenTypes class. This function doesn't use
mapping. So the whole 8Byte PDO data, will be received. To read out use
the rlCanOpenTypes::get_buffer({0-7}) function */
int pdo_receive( int _boardnr,
int _nodeid,
int _pdonr,
rlCanOpenTypes &_pdo_data);
/*! Using the pdo_transmit function you can transmit a PDO (Process Data
Object) to a specific node. The desired data must be written to the
rlCanOpenTypes class. The mapping is only available if mapping is
configurated during the node creation of the rlcanopen constructer.
Therefore an eds file (electronic data sheet) is needed.
Use the cannode::hasMapping() function to check if mapping is available */
int pdo_transmit( int _boardnr,
int _nodeid,
int _pdonr,
int _mappingnr,
rlCanOpenTypes &_pdo_data);
/*! Using the pdo_transmit function you can transmit a PDO (Process Data
Object) to a specific node. The desired data must be written to the
rlCanOpenTypes class. This function does not support mapping. So the
whole 8byte PDO data, will be send to write to the rlCanOpenTypes use
the rlCanOpenTypes::set_buffer({0-7}) function */
int pdo_transmit( int _boardnr,
int _nodeid,
int _pdonr,
rlCanOpenTypes &_pdo_data);
/*! Because the nodes of all boards are stored in one list, the listindex is
not equal to the nodeID(1-127). Use this function to get the listindex
of a desired node */
int getNodeIndex( int _boardnr,
int _nodeid,
int & _index);
/*! returns daemontype number of an object. The type is retrieved from the
node's objectdir. When no objectdir exists (e.g. because of a missing
EDS file) or when the requested object does not exist, this function
will return 0xFF (the corresponding value to rlCanOpenTypes::RL_NOTYPE)
*/
int getObjectType( int _boardnr,
int _nodeid,
int _objectindex,
int _subindex);
/*! Use this function to get information about a specific node.
The nodestate, nodeerror and a nodestateFlag will be written to the
rlCanOpenTypes. Read the rlCanOpenTypes.h header to get further
information about these variables. Hilscher specific function (so no
CanOpoen services) are used to receive the information */
int getNodeState( int _boardnr,
int _nodeid,
rlCanOpenTypes &_data);
/*! Using this function you are able to restart a CanOpenMaster board
(device). There are 3 possibly kinds of restarting the master:
coldstart, warmstart, bootstart.
The corresponding '#defines' are declared in canopenstructs.h
Hilscher specific function (so no CanOpoen services) are used to
execute this command */
int restartBoard( int _boardnr, int _restarttype);
/*! Using this function you can send a NMT Command to one or all nodes (of
one board). NMT (Network Management) is a CanOpen service. Because of the
device there are constrictions for the user.
You can only execute the follow NMT commands:
START_REMOTE_NODE,
STOP_REMOTE_NODE,
ENTER_PREOPERATIONAL,
RESET_NODE,
RESET_COMMUNICATION
The corresponding '#defines' are declared in canopenstructs.h */
int sendNMTCommand( int _boardnr,
int _nodeid,
unsigned char _cmd);
bool is_twisted_type(int _canopentype);
private:
/*! This function reads out the configuration of a specific node using special
Hilscher commands (CMDCODE_GET_CONFIGURATION). If the master board isn't
configurated by SyCon it is not possibly to use this function with success.
It returns false if the node is not available */
bool getNodeConfiguration(int _nodeID);
/*! this function iterates through the recieve/tramsmit pdo lists and returns
the ID number of the pdo that fits the given objektindex. The PdoId
identifies the send/receive PDO on the given node */
int getPdoID(int _boardnr, int _nodeid, int _objektindex, int _direction);
//! the currently active board
int activeboard;
/*! read properties of inifile. EDS path, logfile location and user-specific
options are set on startup */
void read_inifile(const char* _filename);
//! initialize nodes and create nodelist
bool ini();
//! clear message struct by setting all elements to zero
void delmsg();
//! Read informations about installed devices
bool iniboards();
//! this string buffer is usually written with sprintf before sent to stdout
char err_out_buf[255];
//! return value for hilscher specific message functions
short sRet;
//! Pointer to error logfile
FILE* err_fp;
//! name of logfile stdout is redirected to
QString logFileName;
//! hilscher specific message structur which will be sent to the master card
RCS_MESSAGETELEGRAM_10 message;
//! this list contains all nodes from all boards
QPtrVector <rlCanNode> nodelist;
//! the current count of CanOpenMaster cards
int boardcount;
//! message counter
unsigned char messagenr;
//! sets a desired CanOpenMaster active, so that it can be used
short setBoardActive(int _boardnr);
/*! if the user changes the mapping of a node using SDO functions,
the internal mapping list should be changed */
int refreshMappingList( int _boardnr,
int _nodeid,
int _pdoID,
int _pdoDirection);
/*! this function checks the bus for available nodes and creates
a corresponding nodelist */
int createNodes();
//! this function writes the mapping objects for each pdo of a node
int createMappingObjects( int _boardid,
int _nodeid,
int _pdoDirection);
/*! this indicator is true when stdout is redirected to file.
it is set in the ini-file */
bool enableLogging;
};
#endif

View File

@@ -0,0 +1,174 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Br<42>tigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include "rlsocket.h"
#include "rlthread.h"
#include "rlcutil.h"
#include "rlwthread.h"
#include "rlcanopentypes.h"
//! Class performs API rlcanopen functions remotely through tcp sockets
/*! this class provides the client API funcions which should be
similar to the rlcanopen API.
Main difference is that underlying code does not communicate with
the canopen device itself but with a rlcanopendaemon, which should
run in backbround or on an remote computer. */
class rlCanOpenClient
{
public:
enum rl_msg {
MSG_SEND = 0,
MSG_RECEIVE = 1,
MSG_SDO_READ = 0,
MSG_SDO_WRITE = 1,
MSG_PDO_RECEIVE = 3,
MSG_CONNECT = 5,
MSG_DISCONNECT = 6,
MSG_PDO_TRANSMIT = 4,
MSG_NMT_TRANSMIT = 7,
MSG_RESTART_BOARD = 8,
MSG_GET_NODE_STATE = 9
};
//! initializes the client on localhost port 5000
rlCanOpenClient();
//! initializes the client on given port and remove server adress
rlCanOpenClient(int _port, char* _remoteadress);
//! destructor disconnects client
~rlCanOpenClient();
//! opens a new connection to a running rlCanOpenDaemon
int connect();
//! disconnects from daemon
int disconnect();
/*! using the sdo_read function you can read a certain object from the
object dictionary of a node.
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _sdo_data.get_rlmsgerr() */
int sdo_read( int _boardnr,
int _nodeid,int _objectindex,
int _subindex,
rlCanOpenTypes &_sdo_data);
/*! using the sdo_write function you can write to a certain object
from the object dictionary of a node
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _sdo_data.get_rlmsgerr() */
int sdo_write(int _boardnr,
int _nodeid,int _objectindex,
int _subindex,
rlCanOpenTypes &_sdo_data);
/*! receives single mapped pdo object from daemon.
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _sdo_data.get_rlmsgerr() */
int pdo_receive(int _boardnr,
int _nodeid,int _pdonr,
int _mappingnr,
rlCanOpenTypes &_pdo_data);
/*! receives an 8 byte pdo from daemon.
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _sdo_data.get_rlmsgerr() */
int pdo_receive(int _boardnr,
int _nodeid,int _pdonr,
rlCanOpenTypes &_pdo_data);
/*! sends a single mapped pdo object to daemon.
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _pdo_data.get_rlmsgerr() */
int pdo_transmit(int _boardnr,
int _nodeid,int _pdonr,
int _mappingnr,
rlCanOpenTypes &_pdo_data);
/*! sends an 8 byte pdo to daemon.
Function will return NULL if connection to daemon broke down.
CanOpen interface related errors are
accessable in _pdo_data.get_rlmsgerr() */
int pdo_transmit(int _boardnr,
int _nodeid,
int _pdonr,
rlCanOpenTypes &_pdo_data);
/*! sends a NMT command to daemon. */
int sendNMTCommand( int _boardnr,
int _nodeid,
unsigned char _cmd,
bool &returnstate);
/*! forces daemon to restart canopen device. */
int restartBoard(int _boardnr, int _restarttype, bool &returnstate);
/*! receives node state data of particular node from daemon. */
int getNodeState(int _boardnr, int _nodeid,rlCanOpenTypes &_data);
//! setter for private port variable
void setPort(int _port);
//! setter for private remoteadress variable
void setAdr(char* _adr);
private:
//! variable contains process id
int pid;
//! flag indicates connection status
bool connected;
//! variable contains port
int port;
//! string of remoteadress
char remoteadress[40];
//! pointer to socket object
rlSocket* socket;
//! timeout in ms
int client_timeout;
};
//#####################################################################################
// convenience class for client users
class rlCanClient : public rlCanOpenClient
{
public:
rlCanClient(int _port, char* _remoteadress, int _boardnr);
~rlCanClient();
int sdo_read(int _nodeid, int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data);
int sdo_write(int _nodeid,int _objectindex, int _subindex, rlCanOpenTypes &_sdo_data);
int pdo_receive(int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data);
int pdo_receive(int _nodeid, int _pdonr, rlCanOpenTypes &_pdo_data);
int pdo_transmit(int _nodeid, int _pdonr, int _mappingnr, rlCanOpenTypes &_pdo_data);
int pdo_transmit(int _nodeid, int _pdonr, rlCanOpenTypes &_pdo_data);
int sendNMTCommand(int _nodeid, unsigned char _cmd, bool &returnstate);
int restartBoard(int _restarttype, bool &returnstate);
int getNodeState(int _nodeid, rlCanOpenTypes &_data);
private:
int boardnr;
};

View File

@@ -0,0 +1,100 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Bräutigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef DAEMON
#define DAEMON
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rlthread.h"
#include "rlcutil.h"
#include "rlsocket.h"
#include "rlwthread.h"
#include "rlcanopen.h"
enum rl_msg {
MSG_SEND = 0,
MSG_RECEIVE = 1,
MSG_SDO_READ = 0,
MSG_SDO_WRITE = 1,
MSG_PDO_RECEIVE = 3,
MSG_CONNECT = 5,
MSG_DISCONNECT = 6,
MSG_PDO_TRANSMIT = 4,
MSG_NMT_TRANSMIT = 7,
MSG_RESTART_BOARD = 8,
MSG_GET_NODE_STATE = 9
};
//! canopen tcp/ip interface for concurrent device-access of multiple clientprocesses
/*! this is a multi threaded server process, which listens on a tcp port for incomming
connections. It runs the only recommended instance of rlcanopen class for beeing the
very only process accessing the device.
Different processes who concurrently try to access the device will be queued autmaticly
by daemonprocess. These processes are inteded to communicate through rlcanopenclient. */
class rlCanOpenDaemon{
public:
/*! empty constructor initializes on port 5000.
creates a new rlCanOpen Object which
performs all access to canopen device */
rlCanOpenDaemon();
/*! main constructor sets port and inifilename.
creates a new rlCanOpen Object which
performs all access to canopen device */
rlCanOpenDaemon(int _port, char* _iniFileName=0);
/*! destructor destroys rlcanopen object */
~rlCanOpenDaemon();
/*! returns value of current port */
int getPort();
/*! daemon creates a listener thread which handels
incoming connections by himself creating
clientconnection threads for each client connecting to the daemon. */
void start();
/*! pointer to rlCanOpen Object which performs all access to canopen device */
rlCanOpen* nodes;
/*! rlThread object which manages basic thread functionality e.g.
locking to prevent threads
from concurrently accessing the canopen device */
rlThread daemon_thread;
private:
int port;
};
// parameter struct for passing parameters to handler thread
struct THREADTRANSFER
{
int socketdescr; // socket descriptor identifying the new connection
rlCanOpenDaemon* daemonptr; // pointer to daemon object
};
#endif

View File

@@ -0,0 +1,120 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Br<42>tigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
//!definition of CanOpen structs for CanOpen Deamon
#ifndef CanOpenStructsH
#define CanOpenStructsH
#define DIRECTION_RECEIVE 0
#define DIRECTION_TRANSMIT 1
#define RECEIVE_PDO_MAPPING_STARTADRESS 0x1600
#define RECEIVE_PDO_MAPPING_MAXADRESS 0x17FF
#define TRANSMIT_PDO_MAPPING_STARTADRESS 0x1A00
#define TRANSMIT_PDO_MAPPING_MAXADRESS 0x1BFF
#define MAX_NODES 127
#define MAX_SDO_BUFFERSIZE 246
//! Hilscher device-communication constants
#define CAN_TASK 3
#define USER_AT_HOST 16
#define CMDCODE_GET_CONFIGURATION 15
#define CMDCODE_SDO_UPDOWNLOAD 74
#define CMDCODE_Node_Diag 66
#define CMD_NMT_Module_Protocol 96
//! NMT Command specifier
#define CMD_NMT_START_REMOTE_NODE 1
#define CMD_NMT_STOP_REMOTE_NODE 2
#define CMD_NMT_ENTER_PREOPERATIONAL 128
#define CMD_NMT_RESET_NODE 129
#define CMD_NMT_RESET_COMMUNICATION 130
#define TASK_TFC_READ 1
#define TASK_TFC_WRITE 2
#define RESPONSE_CODE_GET_CONFIGURATION 15
#define DATA_DIRECTION_MASK 0x30
#define DIRECTION_INPUT 0x10
#define DIRECTION_OUTPUT 0x20
//! ERRCODES
#define ERRCODE_NOERROR 0
#define ERRCODE_INVALID_NODEID -2
#define ERRCODE_INVALID_PDOID -3
#define ERRCODE_PDOSND_FAIL -4
#define ERRCODE_INVALID_MAPID -5
#define ERRCODE_INVALID_RLTYPE -6
#define ERRCODE_PDORCV_FAIL -7
//! DEVRESET
#define COLDSTART 2
#define WARMSTART 3
#define BOOTSTART 4
//! mapping object which is part of the mappinglist of a PDO
struct rlCanMapping
{
//! the mapping ID determines the mapping object within the PDO (1 to n)
unsigned short mappingId;
//! its current type (int32, float, char, ...)
int etype;
//! its current canoptentype (int24, int40, int48, ...)
int canopentype;
//! its position in within the 8Byte
unsigned short position;
//! length of mappend object in bits
unsigned short length;
} ;
//! PDO object which is part of one of the two pdo lists in the node class
struct rlCanPDO
{
//! 1 = receive PDO / 2 = send PDO [indicate by PDO No]
short bPDODirection;
//! size of a PDO / max 8 Bytes
unsigned char bPDOSize;
//! if only one bit is set in a PDO, this value shows its position
unsigned char bDataPosition;
//! fixes the PDO position in the card memory
unsigned short usPDOAddress;
//! this list contains all mapping information of a PDO
QPtrVector<rlCanMapping> mappingList;
//! the adress of object directory of the node where the mapping is placed
int mappingOvAdress;
};
#endif

View File

@@ -0,0 +1,419 @@
/***************************************************************************
rlcanopen.cpp - description
-------------------
begin : Tue March 03 2004
copyright : (C) 2004 by Marc Bräutigam, Christian Wilmes, R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
#include "rlinifile.h"
#include <stdlib.h>
#include <string.h>
struct IPCMSGSTRUCT;
//!class to handle CANopen types
/*! Can nodes contain data objects of any type. It is necessary
to convert type secure data into type insecure rawdata to transfer it over
the canbus. Therefore this class helps to convert raw canbus data easily.
To prevent users from reading out raw data with a wrong type (e.g. performing
get_int() when a float number is stored in this class), a type number indicates
the currently stored datatype. Everytime such a type violation occurs, a warning
is written to stdout.
*/
class rlCanOpenTypes {
public:
enum rl_types{
RL_BOOL=0,
RL_UCHAR,
RL_SHORT,
RL_USHORT,
RL_INT ,
RL_LONG,
RL_FLOAT,
RL_DOUBLE,
RL_LONGLONG,
RL_STRING,
RL_BUFFER,
RL_ULONG,
RL_ULONGLONG,
RL_PDO = 13,
RL_NODESTATE,
RL_NOTYPE = 0xFF
};
enum canopen_types{
c_BOOLEAN = 0x0001,
INTEGER8_t = 0x0002,
INTEGER16_t = 0x0003,
INTEGER32_t = 0x0004,
UNSIGNED8_t = 0x0005,
UNSIGNED16_t = 0x0006,
UNSIGNED32_t = 0x0007,
REAL32_t = 0x0008,
VISIBLE_STRING = 0x0009,
OCTET_STRING_t = 0x000A,
UNICODE_STRING = 0x000B,
TIME_OF_DAY_t = 0x000C,
TIME_DIFFERENC = 0x000D,
BIT_STRING_t = 0x000E,
DOMAIN_t = 0x000F,
INTEGER24_t = 0x0010,
REAL64_t = 0x0011,
INTEGER40_t = 0x0012,
INTEGER48_t = 0x0013,
INTEGER56_t = 0x0014,
INTEGER64_t = 0x0015,
UNSIGNED24_t = 0x0016,
RESERVED1_t = 0x0017,
UNSIGNED40_t = 0x0018,
UNSIGNED48_t = 0x0019,
UNSIGNED56_t = 0x001A,
UNSIGNED64_t = 0x001B
};
//! Constructor initializes with RL_NOTYPE
rlCanOpenTypes();
//! returns number of bytes used for current type
int getLength();
//! sets all bytes in databuffer to zero
void clearBuffer();
/*! sets the type of data stored in databuffer. All getter-functions forced to
return a type different from this will produce an invalid-type-warning to
stdout
*/
void set_DaemonType(rl_types _type);
//! alternative setter receives integer typenumber
void set_DaemonType(int _type);
//! returns current of data stored in databuffer
int get_DaemonType();
/*! recieves an CANopen typenumber as defined in CiA DS-301 specification.
This type is converted to the appropiate RL-type. Therefore type-numbers
may be extracted directly from EDS file without external conversion.
*/
void set_CanOpenType(int _type);
//! returns the current type converted to CANopen typenumber
int get_CanOpenType();
/*! Function for typenumber conversion. CANopen-Type differs between 27 primitive
data types while DaemonType only consists of 13 ANSI C data types an two
more daemon specific tyes: RL_PDO and RL_NOTYPE which indicates that no
type is defined for raw data placed in this classes databuffer.
*/
static int canOpenType2DeamonType(int _canopentype);
//! Function for typenumber conversion.
static int deamonType2CanOpenType(int _deamontype);
//! sets type to RL_INT and stores passed parameter data in databuffer
void set_int(int _value);
/*! returns databuffer-content as integer type. When type is not RL_INT
this will produce an invalid-type-warning to stdout*/
int get_int();
//! sets type to RL_FLOAT and stores passed parameter data in databuffer
void set_float(float _value);
/*! returns databuffer-content as float type. When type is not RL_FLOAT
this will produce an invalid-type-warning to stdout*/
float get_float();
//! sets type to RL_DOUBLE and stores passed parameter data in databuffer
void set_double(double _value);
/*! returns databuffer-content as double type. When type is not RL_DOUBLE
this will produce an invalid-type-warning to stdout*/
double get_double();
//! sets type to RL_SHORT and stores passed parameter data in databuffer
void set_short(short _value);
/*! returns databuffer-content as short type. When type is not RL_SHORT
this will produce an invalid-type-warning to stdout*/
short get_short();
//! sets type to RL_USHORT and stores passed parameter data in databuffer
void set_ushort(unsigned short _value);
/*! returns databuffer-content as short type. When type is not RL_USHORT
this will produce an invalid-type-warning to stdout*/
unsigned short get_ushort();
//! sets type to RL_LONGLONG and stores passed parameter data in databuffer
void set_longlong(long int _value);
/*! returns databuffer-content as long long type. When type is not RL_LONGLONG
this will produce an invalid-type-warning to stdout*/
long int get_longlong();
/*! sets type to RL_STRING. the passed string-constant is copied byte-wise
to databuffer */
void set_string(const char* _value);
/*! creates a new 246 bytes string filled with databuffer-content and returns a
pointer. this pointer must be stored and memory must be freed with delete,
when the string is not longer needed, to prevent programm from producing
memory leak. */
char* get_string();
/*! This setter does not modify the current type. it is intended to transfer
raw data recieved from canbus into the databuffer and afterwards set the
approbiate daemontype with set_daemontype. _index must be within range of
246 bytes databuffer size.
*/
void set_buffer(int _index, unsigned char _databyte);
//! returns 1 byte from databuffer
unsigned char get_buffer(int _index);
//! sets type to RL_UCHAR and stores passed parameter data in databuffer
void set_uchar(unsigned char _value);
/*! returns databuffer-content as uchar type. When type is not RL_UCHAR
this will produce an invalid-type-warning to stdout*/
unsigned char get_uchar();
//! sets type to RL_BOOL and stores passed parameter data in databuffer
void set_bool(bool _value);
/*! returns databuffer-content as bool type. When type is not RL_BOOL
this will produce an invalid-type-warning to stdout*/
bool get_bool();
//! sets type to RL_LONG and stores passed parameter data in databuffer
void set_long(long _value);
/*! returns databuffer-content as long type. When type is not RL_LONG
this will produce an invalid-type-warning to stdout*/
long get_long();
//! sets type to RL_ULONG and stores passed parameter data in databuffer
void set_ulong(unsigned long _value);
/*! returns databuffer-content as ulong type. When type is not RL_ULONG
this will produce an invalid-type-warning to stdout*/
unsigned long get_ulong();
//! sets type to RL_ULONGLONG and stores passed parameter data in databuffer
void set_ulonglong(unsigned long int _value);
unsigned long int get_ulonglong();
//! sets the errornumber. refer private varibale rlmsgerr for details
void set_rlmsgerr(long _errnr);
//! returns current errnumber
long get_rlmsgerr();
/*! sets type to RL_NODESTATE. This is function is intended to store flag-data
received from the device. */
void set_nodestateFlags( unsigned char _bNodeNoResponse,
unsigned char _bEmcyBuffOverflow,
unsigned char _bPrmFault,
unsigned char _bGuardActive ,
unsigned char _bDeactivated);
/*! returns false when typenumber is not RL_NODESTATE. if true states are stored
in parameter variables */
bool get_nodestateFlags( bool &_bNodeNoResponse,
bool &_bEmcyBuffOverflow,
bool &_bPrmFault,
bool &_bGuardActive,
bool &_bDeactivated);
//! read particular nodestade with the following functions
bool get_nodestateFlag_NoResponse();
bool get_nodestateFlag_EmcyBuffOverflow();
bool get_nodestateFlag_PrmFault();
bool get_nodestateFlag_GuardActive();
bool get_nodestateFlag_Deactivated();
/*! sets current state of node. this is a code number the following meaning:
alias nr
DISCONNECTED 1
CONNECTING 2
PREPARING 3
PREPARED 4
OPERATIONAL 5
PRE_OPERATIONAL 127 */
void set_nodestate(unsigned char _nodestate);
//! returns the nodestate. refer code numbers above
unsigned char get_nodestate();
/*! sets the actual node error. refer com_pie.pdf page 15 for detailed
error code description */
void set_nodeerror(unsigned char _nodeerror);
//! returns actual node error
unsigned char get_nodeerror();
//! external buffer for pdotransfer
unsigned char pdobuffer[8];
//! exchange bytes 0-7 from databuffer to pdobuffer
void buf2pdobuf();
//! exchange bytes 0-7 from pdobuffer to databuffer
void pdobuf2buf();
//! copies all data from right object into left object
rlCanOpenTypes& operator = (rlCanOpenTypes &cp);
//! returns a IPCMSGSTRUCT filled with current object data
IPCMSGSTRUCT createIpcMsg();
//! overwrites all data with IPCMSGSTRUCT data
void getIpcMsg(IPCMSGSTRUCT _myIpcMsg);
//! prints MsgErrStr to StdOut
void rlMsgErrOut();
/*! returns a pointer to a new 22 character string containing the name of
the error in rlmsgerr. This pointer must be stored and memory must be
freed with delete, when the string is not longer needed, to prevent
programm from producing memory leak. */
char* rlMsgErrStr();
/*! returns a pointer to a new 12 character string containing the name of
the type passed by _typnr. This pointer must be stored and memory must
be freed with delete, when the string is not longer needed, to prevent
programm from producing memory leak. */
char* type2str(int _typenr);
bool translate_CanOpenType(int _canopentype);
int get_CanOpenTypeLength(int _canopentype);
private:
/*! produce an invalid-type-warning to stdout.
used by nearly all getter functions */
void invalidTypeError(int _typenr);
/*! variable that stores the current datatype. only rl_types enum values
are indented to be stored here */
int typenumber;
/*! errnumber // alias // description
rlmsgerr = 0 // ERRCODE_NOERROR // no error
rlmsgerr > 0 // // msg.f error code. Refer com_pie.pdf page 44 for details.
rlmsgerr = -1 // // msg.a or msg.nr inconsistency
rlmsgerr = -2 // ERRCODE_INVALID_NODEID // nodeid does not exist
rlmsgerr = -3 // ERRCODE_INVALID_PDOID // pdoid does not exist
rlmsgerr = -4 // ERRCODE_PDOSND_FAIL // transmit pdo failed
rlmsgerr = -5 // ERRCODE_INVALID_MAPID // mappingid does not exist
rlmsgerr = -6 // ERRCODE_INVALID_RLTYPE // type does not fit during pdo transmit
rlmsgerr = -7 // ERRCODE_PDORCV_FAIL // pdo receive failed */
long rlmsgerr;
//all different types are stored together in the same data area
union {
int t_int; // 4 Bytes 0x00
float t_float; // 4 Bytes 0x01
double t_double; // 8 Bytes 0x02
short t_short; // 2 Bytes 0x03
unsigned short t_ushort; // 2 Bytes 0x04
long int t_longlong; // 8 Bytes 0x05
char t_string[247]; // 246 Bytes 0x06
unsigned char t_databytes[247]; // 246 Bytes 0x07
unsigned char t_databyte; // 1 Byte 0x08
bool t_bool; // 1 Byte 0x09
long t_long; // 4 Bytes 0x0A
unsigned long t_ulong; // 4 Bytes 0x0B
unsigned long int t_ulonglong; // 8 Bytes 0x0C
// Error => 0xFF
struct
{
unsigned char bNodeNoResponse : 1; /* no response */
unsigned char bEmcyBuffOverflow : 1; /* emcy.buffer overflow */
unsigned char bPrmFault : 1; /* parameters faulty */
unsigned char bGuardActive : 1; /* node guarding active */
unsigned char bDeactivated : 1; /* not configured */
unsigned char bNodeState;
#define DISCONNECTED 1
#define CONNECTING 2
#define PREPARING 3
#define PREPARED 4
#define OPERATIONAL 5
#define PRE_OPERATIONAL 127
unsigned char bActualError;
} bNodeFlagState;
};
};
//! the IPCMSGSTRUCT is the transfer buffer which is send trough TCP sockets
/*
MSG_SEND 0
MSG_RECEIVE 1
#define MSG_SDO_READ 0
#define MSG_SDO_WRITE 1
#define MSG_PDO_RECEIVE 3
#define MSG_CONNECT 5
#define MSG_DISCONNECT 6
#define MSG_PDO_TRANSMIT 4
#define MSG_NMT_TRANSMIT 7
#define MSG_RESTART_BOARD 8
#define MSG_GET_NODE_STATE 9
*/
struct IPCMSGSTRUCT
{
long typenumber;
/* msgtype can be one of this values
MSG_SDO_READ 0
MSG_SDO_WRITE 1
MSG_PDO_RECEIVE 3
MSG_CONNECT 5
MSG_DISCONNECT 6
MSG_PDO_TRANSMIT 4
MSG_NMT_TRANSMIT 7
MSG_RESTART_BOARD 8
MSG_GET_NODE_STATE 9 */
long msgtype;
/* transfer type can be one of this values
MSG_SEND 0
MSG_RECEIVE 1 */
long transfertype;
long processid;
long boardid;
long nodeid;
long objectindex;
long subindex;
long pdoid;
long mappingid;
long rlmsgerr;
char mtext[247];
};

View File

@@ -0,0 +1,60 @@
/***************************************************************************
rlcommandlineinterface.h - description
-------------------
begin : Sat Mar 27 2010
copyright : (C) 2010 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_COMMANDLINE_INTERFACE_H_
#define _RL_COMMANDLINE_INTERFACE_H_
#include "rldefine.h"
#include "rlsocket.h"
#include "rlserial.h"
#include "rlspawn.h"
/*! <pre>
Commandline interface that allows applications to communicate over pipe || socket || serial line || stdio .
The parameters of start() are as follows:
start("stdio"); // use stdin and stdout
start("pipe","command"); // run "command" and connect it's stdio with us (runs on unix only)
start("host:5050"); // connect to "host" on port 5050 and communicate with the server (tip: define a server with xinted on "host" port 5050)
start("localhost:5050","command"); // run "command" and then try to connect to "localhost" port 5050 for communication with "command"
start("server.localhost:5050"); // act as a server on "localhost" port 5050 (can serve only 1 client. if you want to serve more clients use rlSocket)
start(tty); // use serial interface for communication
Return values:
start() returns -1 on error
readLine() returns the read string or NULL
readBlock() returns the number of read bytes or -1 on error
printf() returns the number of written characters or -1 on error
writeBlock() returns the number of written bytes or -1 on error
</pre> */
class rlCommandlineInterface
{
public:
rlCommandlineInterface();
virtual ~rlCommandlineInterface();
int start(const char *how, const char *command=NULL);
int start(rlSerial *tty);
const char *readLine(int timeout=0);
int readBlock(void *buf, int len, int timeout=0);
int printf(const char *format, ...);
int writeBlock(void *buf, int len);
private:
char line[rl_PRINTF_LENGTH];
rlSocket *sock;
rlSpawn *spawn;
rlSerial *tty;
};
#endif

View File

@@ -0,0 +1,163 @@
/***************************************************************************
rlcontroller.h - description
-------------------
begin : Wed Jun 16 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_CONTROLLER_H_
#define _RL_CONTROLLER_H_
#include "rldefine.h"
#include "rlthread.h"
/*! <pre>
class for closed loop control
According to: F. Doerrscheid/W. Latzel, Grundlagen der Regelungstechnik, B.G. Teubner Stuttgart
Page 436-437, Regelalgorithmen mit der Trapezregel
</pre> */
class rlController : public rlThread
{
public:
enum ControllerType
{
P = 1,
I = 2,
D_T1 = 3,
PI = 4,
PD_T1 = 5,
PID_T1 = 6,
PI_SUM = 7,
PD_T1_SUM = 8,
PID_T1_SUM = 9
};
rlController(double (*_getMeasurement)() ,void (_writeOutput)(double output));
~rlController();
void start();
void stop();
/*! <pre>
Set the reference value for the controller
</pre> */
void setReference (double _reference);
/*! <pre>
Transfer function: Gr(s) = Kp
</pre> */
void setP (double _T, double _Kp);
/*! <pre>
1
Transfer function: Gr(s) = ------
T1 * s
T = cycle time in seconds
</pre> */
void setI (double _T, double _T1);
/*! <pre>
TD * s
Transfer function: Gr(s) = ---------
1 + Td*s
T = cycle time in seconds
</pre> */
void setD_T1 (double _T, double _TD, double _Td);
/*! <pre>
1 + Tn*s
Transfer function: Gr(s) = Kp * --------
Tn*s
T = cycle time in seconds
</pre> */
void setPI (double _T, double _Kp, double _Tn);
/*! <pre>
1 + TvP*s
Transfer function: Gr(s) = Kp * ---------
1 + Td*s
T = cycle time in seconds
</pre> */
void setPD_T1 (double _T, double _Kp, double _TvP, double _Td);
/*! <pre>
1 + TnP*s 1 + TvP*s
Transfer function: Gr(s) = Kpp * --------- * ---------
TnP*s 1 + Td*s
T = cycle time in seconds
</pre> */
void setPID_T1 (double _T, double _Kpp, double _TnP, double _TvP, double _Td);
/*! <pre>
1
Transfer function: Gr(s) = Kp * ( 1 + ---- )
Tn*s
T = cycle time in seconds
</pre> */
void setPI_SUM (double _T, double _Kp, double _Tn);
/*! <pre>
Tv*s
Transfer function: Gr(s) = Kp * ( 1 + -------- )
1 + Td*s
T = cycle time in seconds
</pre> */
void setPD_T1_SUM (double _T, double _Kp, double _Tv, double _Td);
/*! <pre>
1 Tv*s
Transfer function: Gr(s) = Kp * ( 1 + ---- + -------- )
Tn*s 1 + Td*s
T = cycle time in seconds
</pre> */
void setPID_T1_SUM (double _T, double _Kp, double _Tn, double _Tv, double _Td);
/*! <pre>
Set limits for the controller output
</pre> */
void setLimits(double _yk_min, double _yk_max);
/*! <pre>
Reset limits for the controller output
</pre> */
void resetLimits();
/*! <pre>
Don't set the controller parameters directly
Use the set methods, because they will also set the coefficients
Controller parameters are for reading only
</pre> */
double Kp,Kpp,T,T1,Td,TD,Tn,TnP,TvP,Tv,reference;
int type;
int running;
double d0,d1,d2,dD;
double c1,c2,cD;
double yk,yk_1,yk_2;
double ek,ek_1,ek_2;
double y1k,y1k_1,ydk,ydk_1;
int dt;
// callbacks
/*! <pre>
You have to supply this function for getting the measurement
</pre> */
double (*getMeasurement)();
/*! <pre>
You have to supply this function for writing the output
</pre> */
void (*writeOutput)(double output);
/*! <pre>
Default sleepLocally = 1
But:
Sleeping locally might me inaccurate.
It might be better to have a central timer and wait for it in
double (*_getMeasurement)();
T = cycle time in seconds
</pre> */
int sleepLocally;
/*! <pre>
last measurement
</pre> */
double measurement;
/*! <pre>
limits
</pre> */
double yk_min;
double yk_max;
int limited;
};
#endif

View File

@@ -0,0 +1,110 @@
/***************************************************************************
rlcorba.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_CORBA_H_
#define _RL_CORBA_H_
#include "rldefine.h"
#define rlMICO
//#define rlVISIBROKER
//#define rlOMNIORB
#include <CORBA.h>
#ifdef rlMICO
#include <mico/throw.h>
#endif
template <class T, class Tvar>
class rlCorbaClient
{
public:
#ifdef rlMICO
rlCorbaClient(int ac, char **av, const char *iname)
{
idlname = adr = NULL;
if(iname == NULL) return;
idlname = new char[strlen(iname)+1];
strcpy(idlname,iname);
for(int i=0; i<ac; i++)
{
if(strncmp(av[i],"inet:",5) == 0)
{
if(adr != NULL) delete adr;
adr = new char[strlen(av[i])+1];
strcpy(adr,av[i]);
}
}
orb = CORBA::ORB_init(ac,av);
obj = orb->bind(idlname, adr);
if(CORBA::is_nil(obj))
{
cerr << "cannot bind to " << adr << endl;
delete adr;
adr = NULL;
return;
}
client = T::_narrow(obj);
if(CORBA::is_nil(client))
{
cerr << "Argument is not a " << idlname << " reference" << endl;
}
}
~rlCorbaClient()
{
if(idlname != NULL) delete idlname;
if(adr != NULL) delete adr;
}
#endif
char *idlname;
char *adr;
CORBA::ORB_var orb;
CORBA::Object_var obj;
Tvar client;
};
template <class Timpl, class Tvar>
class rlCorbaServer
{
public:
#ifdef rlMICO
rlCorbaServer(int ac, char **av, const char *)
{
orb = CORBA::ORB_init(ac,av);
obj = orb->resolve_initial_references("RootPOA");
poa = PortableServer::POA::_narrow(obj);
mgr = poa->the_POAManager();
server = server_servant._this();
CORBA::String_var str = orb->object_to_string(server);
cout << str << endl; // write reference to stdout
mgr->activate();
}
~rlCorbaServer()
{
}
#endif
void run()
{
orb->run();
}
char *adr;
CORBA::ORB_var orb;
CORBA::Object_var obj;
PortableServer::POA_var poa;
PortableServer::POAManager_var mgr;
Timpl server_servant;
Tvar server;
};
#endif

View File

@@ -0,0 +1,254 @@
/***************************************************************************
rlcutil.cpp - description
-------------------
begin : Wed Dec 11 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/*! <pre>
Some C functions.
</pre> */
#ifndef _RL_CUTIL_H_
#define _RL_CUTIL_H_
#include <stdarg.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "rldefine.h"
/*! <pre>
like printf for debugging
</pre> */
int rlSetDebugPrintf(int state);
int rlDebugPrintf(const char *format, ...);
/*! <pre>
test if input line is available
#include <sys/select.h>
</pre> */
int rlInputAvailable();
/*! <pre>
like printf in the last line of a terminal
</pre> */
int rlLastLinePrintf(const char *format, ...);
#ifdef RLUNIX
/*! <pre>
call execvp(arg[0],arg) on unix
</pre> */
#ifndef SWIG
int rlexec(const char *command);
#endif
#endif
/*! <pre>
encode plain text password p
</pre> */
const char *rlpass(const char *p);
/*! <pre>
strncpy + terminate with '\\0'
</pre> */
char *rlstrncpy(char *dest, const char *source, int n);
/*! <pre>
strncpy + terminate with '\\0'
terminates on '\\n' or '\\0'
'\\n' is not copied
</pre> */
char *rlstrlinecpy(char *dest, const char *source, int n);
/*! <pre>
like vsnprintf but portable
</pre> */
#ifndef SWIG
int rlvsnprintf(char *text, int len, const char *format, va_list ap);
#endif
/*! <pre>
like snprintf but portable
</pre> */
int rlsnprintf(char *text, int len, const char *format, ...);
/*! <pre>
set signal handler for signal SIGTERM
</pre> */
void rlSetSigtermHandler(void (*handler)(void *arg), void *arg);
/*! <pre>
context = 0 must be 0 on first call
</pre> */
const char *rlFindFile(const char *pattern, int *context);
/** <pre>
returns:
~/.name on Linux/Unix
sys$login:name on OpenVMS
%USERPROFILE%\\name on Windows
</pre> */
const char *rlGetInifile(const char *name);
/** <pre>
swaps bytes
</pre> */
int rlSwapShort(int val);
/** <pre>
Send command to a bus system
</pre> */
int rlEib1 (int command);
int rlEib2 (int command);
int rlLon1 (int command);
int rlLon2 (int command);
int rlProfibus1(int command);
int rlProfibus2(int command);
int rlCan1 (int command);
int rlCan2 (int command);
/** <pre>
Call internet browser
</pre> */
int rlBrowser(const char *htmlfile);
/** <pre>
Call system(command)
</pre> */
int rlsystem(const char *command);
/** <pre>
Submit a pvserver
Example:
rlSubmitPvserver("HOME","/temp/murx","pvs","-exit_on_bind_error -exit_after_last_client_terminates");
</pre> */
int rlSubmitPvserver(const char *env, const char *path, const char *pvs, const char *options=NULL);
/** <pre>
Get option from string
return = 0 # not found
return = 1 # found
</pre> */
int rlOption(const char *string, const char *option);
/** <pre>
Get option from string
</pre> */
int rlIntOption(const char *string, const char *option, int _default);
/** <pre>
Get option from string
</pre> */
float rlFloatOption(const char *string, const char *option, float _default);
/** <pre>
Get option from string
</pre> */
const char *rlTextOption(const char *string, const char *option, const char *_default);
/** <pre>
Copy a Textfile (no binary file)
</pre> */
int rlCopyTextfile(const char *source, const char *destination);
/** <pre>
convert str to upper case
</pre> */
int rlupper(char *str);
/** <pre>
convert str to lower case
</pre> */
int rllower(char *str);
/** <pre>
test if str starts with startstr
</pre> */
int rlStartsWith(const char *str, const char *startstr);
/** <pre>
test if str ends with endstr
</pre> */
int rlEndsWith(const char *str, const char *endstr);
/** <pre>
test if str matches with wild
</pre> */
int rlStrMatch(const char *str, const char *wild);
/** <pre>
same as stat
</pre> */
#ifndef SWIG
int rlStat(const char *filepath, struct stat *buf);
#endif
/** <pre>
read data from file
return := number of bytes read | -1
</pre> */
int rlFRead(FILE *fin, void *data, int len);
/** <pre>
write data to file
return := number of bytes written | -1
</pre> */
int rlFWrite(FILE *fout, void *data, int len);
/** <pre>
write data to file
return := number of bytes written | -1
</pre> */
int rlWriteFile(const char *filename, void *data, int len);
/** <pre>
same as mkdir
</pre> */
int rlMkdir(const char *dir, int mode=0744);
/** <pre>
Set bit bitnumber in value
Return value
</pre> */
int rlBitSet(int bitnumber, int *value);
/** <pre>
Clear bit bitnumber in value
Return value
</pre> */
int rlBitClear(int bitnumber, int *value);
/** <pre>
XOR bit bitnumber in value
Return value
</pre> */
int rlBitChange(int bitnumber, int *value);
/** <pre>
Test bit bitnumber in value
Return 0 | 1
</pre> */
int rlBitTest(int bitnumber, int *value);
/** <pre>
Push value to front of buffer.
Shift all other values.
</pre> */
void rlPushToDoubleBuffer(double val, double *buffer, int size);
/** <pre>
Push value to front of buffer.
Shift all other values.
</pre> */
void rlPushToFloatBuffer(float val, float *buffer, int size);
#endif

View File

@@ -0,0 +1,83 @@
/***************************************************************************
rldataacquisition.h - description
-------------------
begin : Mon Sep 03 2007
copyright : (C) 2007 by pvbrowser
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_DAQ_H_
#define _RL_DAQ_H_
#include "rldefine.h"
#include "rlmailbox.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is for data acquisition within pvserver according to the pvbrowser principle.
It communicates by the means of a shared memory and a mailbox.
Use it together with rlDataAcquisitionProvider.
</pre> */
class rlDataAcquisition
{
public:
// shared memory header
typedef struct
{
char ident[4]; // must be "daq"
int maxItemNameLength; // maximum length of an item name
int maxNameLength; // maximum length of the item value
int numItems; // number of items in shared memory
int readErrorCount; // 0...65536 incremented by each read error
int writeErrorCount; // 0...65536 incremented by each write error
int lifeCounter; // 0...65536 incremented on each cycle
int spare[7]; // for future use
char cspare[32]; // for future use
}SHM_HEADER;
enum DAQ_ENUM
{
DAQ_ERROR = 256*256*128
};
#ifdef RLWIN32
rlDataAcquisition(const char *mailbox="c:\\automation\\mbx\\dataacquisition.mbx", const char *shared_memory="c:\\automation\\shm\\dataacquisition.shm", long shared_memory_size=65536);
#else
rlDataAcquisition(const char *mailbox="/srv/automation/mbx/dataacquisition.mbx", const char *shared_memory="/srv/automation/shm/dataacquisition.shm", long shared_memory_size=65536);
#endif
virtual ~rlDataAcquisition();
const char *stringValue(const char *variable);
int intValue(const char *variable);
float floatValue(const char *variable);
int writeStringValue(const char *variable, const char *value);
int writeIntValue(const char *variable, int value);
int writeFloatValue(const char *variable, float value);
/*! Incremented by the daemon on each read error */
int readErrorCount();
/*! Incremented by the daemon on each write error */
int writeErrorCount();
/*! Incremented by the daemon in each cycle */
int lifeCounter();
const char *firstVariable();
const char *nextVariable();
int shmStatus(); // 0 if shared memory is ok | DAQ_ERROR if shared memory is not ok
int shmKey(); // key of shared memory
int shmId(); // id of shared memory
private:
SHM_HEADER *shmheader;
const char *shmvalues;
rlMailbox *mbx;
rlSharedMemory *shm;
int iCurrent;
};
#endif

View File

@@ -0,0 +1,82 @@
/***************************************************************************
rldataacquisitionprovider.h - description
-------------------
begin : Mon Sep 03 2007
copyright : (C) 2007 by pvbrowser
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_DAQ_PROVIDER_H_
#define _RL_DAQ_PROVIDER_H_
#include "rldefine.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is usefull to implement your own data acquisition according to the pvbrowser principle.
It is used within pvb/template/dataacquisition/client/data_acquisition_provider_template.cpp
Starting from there you can implement your data acquisition.
</pre> */
class rlDataAcquisitionProvider
{
public:
// shared memory header
typedef struct
{
char ident[4]; // must be "daq"
int maxItemNameLength; // maximum length of an item name
int maxNameLength; // maximum length of the item value
int numItems; // number of items in shared memory
int readErrorCount; // 0...65536 incremented by each read error
int writeErrorCount; // 0...65536 incremented by each write error
int lifeCounter; // 0...65536 incremented each cycle
int spare[7]; // for future use
char cspare[32]; // for future use
}SHM_HEADER;
enum DAQ_PROVIDER_ENUM
{
DAQ_PROVIDER_ERROR = 256*256*128
};
#ifdef RLWIN32
rlDataAcquisitionProvider(int maxNameLength=31, const char *shared_memory="c:\\automation\\shm\\dataacquisition.shm", long shared_memory_size=65536);
#else
rlDataAcquisitionProvider(int maxNameLength=31, const char *shared_memory="/srv/automation/shm/dataacquisition.shm", long shared_memory_size=65536);
#endif
virtual ~rlDataAcquisitionProvider();
int readItemList(const char *filename); // return DAQ_PROVIDER_ERROR | num_items
const char *firstItem();
const char *nextItem();
const char *stringValue(const char *variable);
int intValue(const char *variable);
float floatValue(const char *variable);
int setStringValue(const char *variable, const char *value);
int setIntValue(const char *variable, int value);
int setFloatValue(const char *variable, float value);
int readErrorCount();
int writeErrorCount();
int lifeCounter();
int setReadErrorCount(int count);
int setWriteErrorCount(int count);
int setLifeCounter(int count);
int shmStatus(); // 0 if shared memory is ok | DAQ_PROVIDER_ERROR if shared memory is not ok
int setAllowAddValues(int allow, int maxItemNameLength);
private:
SHM_HEADER *shmheader;
char *shmvalues;
int current_item, allow_add_values;
rlSharedMemory *shm;
long sharedMemorySize;
};
#endif

View File

@@ -0,0 +1,3 @@
#warning "Please #include \"rldataacuisition.h\" instead of \"rldataaquisition.h\""
#warning "Please replace rlDataAquisition by rlDataAcquisition"
#error "rlDataAcquisition had been misspelled to rlDataAquisition. This was fixed. Please adjust your code."

View File

@@ -0,0 +1,3 @@
#warning "Please #include \"rldataacquisitionprovider.h\" instead of \"rldataaquisitionprovider.h\""
#warning "Please replace rlDataAquisitionProvider by rlDataAcquisitionProvider"
#error "rlDataAcquisitionProvider had been misspelled to rlDataAquisitionProvider. This was fixed. Please adjust your code."

View File

@@ -0,0 +1,100 @@
/***************************************************************************
rldataprovider.h - description
-------------------
begin : Fri Dec 20 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_DATA_PROVIDER_H_
#define _RL_DATA_PROVIDER_H_
#include "rldefine.h"
#include "rlsocket.h"
#include "rlthread.h"
#include "rlinterpreter.h"
/*! <pre>
This class is a container for data.
You can get/set the data identified by id.
The run method starts a separate thread that makes rlDataProvider available over TCP.
</pre> */
class rlDataProvider
{
public:
rlDataProvider(int numInteger, int numFloat=0, int numString=0);
virtual ~rlDataProvider();
int getInt (int id);
float getFloat (int id);
int getIntArray (int id, int *i, int nmax);
int getFloatArray (int id, float *f, int nmax);
const char *getString(int id);
int setInt (int id, int i);
int setFloat (int id, float f);
int setIntArray (int id, int *i, int num);
int setFloatArray (int id, float *f, int num);
int setString(int id, const char *str);
int getIntAndReset(int id);
int setIntAndWaitForReset(int id, int i);
int setInt0Semaphore(int i);
int getInt0Semaphore();
int run(rlSocket *socket);
private:
typedef char* CHARPTR;
int *ints;
float *floats;
char **strings;
int num_integer, num_float, num_string;
rlMutex mutex;
rlSemaphore int0semaphore;
};
/*! <pre>
This class is a client that can access rlDataProvider over TCP.
</pre> */
class rlDataProviderClient
{
public:
rlDataProviderClient();
virtual ~rlDataProviderClient();
int getInt (rlSocket *socket, int id, int *status);
float getFloat (rlSocket *socket, int id, int *status);
int getIntArray (rlSocket *socket, int id, int *array, int nmax);
int getFloatArray (rlSocket *socket, int id, float *array, int nmax);
const char *getString (rlSocket *socket, int id, int *status);
int setInt (rlSocket *socket, int id, int i);
int setFloat (rlSocket *socket, int id, float f);
int setIntArray (rlSocket *socket, int id, int *i, int num);
int setFloatArray (rlSocket *socket, int id, float *f, int num);
int setString (rlSocket *socket, int id, const char *str);
int getIntAndReset (rlSocket *socket, int id, int *status);
int setIntAndWaitForReset(rlSocket *socket, int id, int i);
int getInt0Semaphore (rlSocket *socket, int *status);
private:
rlInterpreter interpreter;
char cret[rl_PRINTF_LENGTH];
};
/*! <pre>
This class starts a separate thread.
The thread is accepting clients, that want access to rlDataProvider.
</pre> */
class rlDataProviderThreads
{
public:
rlDataProviderThreads(int Port, rlDataProvider *Provider);
virtual ~rlDataProviderThreads();
void start();
rlDataProvider *provider;
rlThread thread;
int port;
};
#endif

View File

@@ -0,0 +1,109 @@
/***************************************************************************
rldefine.h - description
-------------------
begin : Wed Dec 04 2002
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/*! <pre>
The header that is included in every file of rllib.
</pre> */
#ifndef _RL_DEFINE_H_
#define _RL_DEFINE_H_
// CPP Standard
#if __cplusplus >= 199711L
#define RLCPP98
#endif
#if __cplusplus >= 201103L
#define RLCPP11
#endif
#if __cplusplus >= 201402L
#define RLCPP14
#endif
#if __cplusplus >= 201703L
#define RLCPP17
#endif
// define WIN
#ifdef _WIN32
#define RLWIN32
#include <winsock2.h>
#include <windows.h>
#define WTHREAD_GNUC0 ( __GNUC__ * 1000 ) + __GNUC_MINOR__
#if WTHREAD_GNUC0 >= 4008
#endif
#endif
// we always use this and are very lazy
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// define unix if not already defined
#ifdef __unix__
#ifndef unix
#define unix
#endif
#endif
#ifdef unix
#define RLUNIX
#endif
#if defined(__APPLE__) && defined(__MACH__)
#ifndef RLUNIX
#define RLUNIX
#endif
#endif
#define rl_PRINTF_LENGTH 4096
#define rl_PRINTF_LENGTH_SPREADSHEET 4096
#define BIT0 1
#define BIT1 2
#define BIT2 4
#define BIT3 8
#define BIT4 16
#define BIT5 32
#define BIT6 64
#define BIT7 128
#define BIT8 256*1
#define BIT9 256*2
#define BIT10 256*4
#define BIT11 256*8
#define BIT12 256*16
#define BIT13 256*32
#define BIT14 256*64
#define BIT15 256*128
#define BIT16 256*256*1
#define BIT17 256*256*2
#define BIT18 256*256*4
#define BIT19 256*256*8
#define BIT20 256*256*16
#define BIT21 256*256*32
#define BIT22 256*256*64
#define BIT23 256*256*128
#define BIT24 256*256*256*1
#define BIT25 256*256*256*2
#define BIT26 256*256*256*4
#define BIT27 256*256*256*8
#define BIT28 256*256*256*16
#define BIT29 256*256*256*32
#define BIT30 256*256*256*64
#define BIT31 256*256*256*128
#define RLCRLF "\r\n"
#endif

View File

@@ -0,0 +1,307 @@
/***************************************************************************
rldf1.cpp - description
-------------------
This Class implements basic functions of DF1 Full Duplex protocall as
described in 1770-6.5.16 Publication of AB.
This Class implements:
- Data Link Layer ( Message Frames )
- Application Layer ( Message Packets )
- Some Basic Communication Commands for reading and writting PLC files.
It is easy to add more Communication Commands.
Some basic knowledge about the related PLCs is required.
The class supports only serial communication through RS232 port.
DANGER: DON'T connect to a PLC unless you are certain it is safe to do so!!!
You are ABSOLUTELY RESPONSIBLE if you affect the operation of a running PLC.
Evangelos Arkalis
mail:arkalis.e@gmail.com
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_DF1_H_
#define _RL_DF1_H_
#include "rlserial.h"
class df1Buffer;
class rlDF1
{
public:
/*! <pre>
Initialize class
src = id of local device
timeout = receive timeout in ms
</pre> */
rlDF1(unsigned char src=0, int timeout=1000);
virtual ~rlDF1();
void registerSerial(rlSerial *serial);
enum DF1ret {
retERROR_TNS = -6,
retERROR_STS = -5,
retERROR_CRC = -4,
retERROR_NAC = -3,
retERROR = -2,
retNORESPONSE = -1,
retSUCCESS = 0
};
/*! <pre>
Command: Set CPU mode ( See page 7-26 )
destination = destination ID
mode = CPUMODE value
</pre> */
enum CPUMODE {
PROGRAM = 0,
TEST,
RUN,
NOCHANGE
};
int cmdSetCPUMode(unsigned char destination, unsigned char mode);
/*! <pre>
Command: Diagnostic Status
Reads a block of status information from an interface module.
The function returns the status information in data.
(see Chapter 10, “Diagnostic Status Information.”)
destination = destination ID
data = buffer for data return
returns the number of valid bytes in data or Error Code
</pre> */
int cmdDiagnosticStatus( unsigned char destination, unsigned char *data);
/*! <pre>
Command: protected typed logical read with three address fields
*Most Important command*. Reads data from a logical address.
Parameters:
destination = destination ID
nsize = size of data to be read
filetype = Type of file with number filenum
84 hex: status
85 hex: bit
86 hex: timer
87 hex: counter
88 hex: control
89 hex: integer
8A hex: floating point
8B hex: output logical by slot
8C hex: input logical by slot
8D hex: string
8E hex: ASCII
8F hex: BCD
filenum = filenumber in PLC memory
adr = Elements Address (see Manual)
sadr = Subelements Address (see Manual)
data = buffer for data return
returns the number of valid bytes in data or Error Code
</pre> */
int cmdLogicalRead( unsigned char destination, unsigned char nsize, unsigned char filetype, unsigned char filenum, unsigned char adr, unsigned char sadr, unsigned char *buffer);
/*! <pre>
Command: protected typed logical write with three address fields
*Most Important command*. Writes data to a logical address.
Parameters:
destination = destination ID
nsize = size of data to write
filetype = Type of file with number filenum
84 hex: status
85 hex: bit
86 hex: timer
87 hex: counter
88 hex: control
89 hex: integer
8A hex: floating point
8B hex: output logical by slot
8C hex: input logical by slot
8D hex: string
8E hex: ASCII
8F hex: BCD
filenum = filenumber in PLC memory
adr = Elements Address (see Manual)
sadr = Subelements Address (see Manual)
data = buffer of data to write
returns Error Code
</pre> */
int cmdLogicalWrite( unsigned char destination, unsigned char nsize, unsigned char filetype, unsigned char filenum, unsigned char adr, unsigned char sadr, unsigned char *buffer);
private:
/*! <pre>
Functions for Application Layer.
Normally private. If you want to add new Commands do it with new public functions.
sendCommand implements sending with retries and handling
destination = id of remote device
cmd = Command Code (see page 6-3)
sts = Status Code (see page 6-6 )
cdata = Pointer to Command Specific data packet ( Chapter 7 )
len = Length of cdata
receiveAnswer gets answer frame from remote.
</pre> */
int sendCommand( unsigned char destination, unsigned char cmd, unsigned char sts, unsigned char *cdata, unsigned char len);
int receiveAnswer( unsigned char &destination, unsigned char &cmd, unsigned char &sts, unsigned char *cdata, unsigned char &len);
/*! <pre>
Functions for Data Link Layer.
Internal Use ONLY.
</pre> */
enum DF1BytePos {
POS_DST =0,
POS_SRC =1,
POS_CMD =2,
POS_STS =3,
POS_TNSL =4,
POS_TNSH =5,
POS_DATA =6
};
enum DF1ControlChars { /// Page 2-6 of Ref Manual
SOH = 0x01,
STX = 0x02,
ETX = 0x03,
EOT = 0x04,
ENQ = 0x05,
ACK = 0x06,
DLE = 0x10,
NAC = 0x15
};
enum DF1Flags {
FLAG_TIMEOUT =-1,
FLAG_DATA =0,
FLAG_CONTROL =1
};
int writeBuffer( unsigned char *buffer, int len );
int writeBuffer( df1Buffer& buffer );
int getSymbol(unsigned char *c);
int get(unsigned char *c);
int sendENQ();
int sendACK();
int sendNAC();
rlSerial *tty;
bool active;
unsigned short tns;
int nRequests;
int nResponses;
unsigned char source;
int timeout;
public:
/*! <pre>
Some statistics...
</pre> */
int requests() {return nRequests;};
int responses() {return nResponses;};
void clearStats() { nRequests=0; nResponses=0;};
};
#endif // _RL_DF1_H_
/*
// test program for rlDF1
#include <rldf1.h>
// Remote ID
const unsigned char id=1;
rlSerial ser;
rlDF1 myplc;
int main(int argc, char *argv[])
{
int ret;
if ( ser.openDevice( "/dev/ttyS0", B19200, 0, 0 )!= 0 ) exit(-1);
printf("\nDevice OK");
myplc.registerSerial( &ser ); /// Register Serial Port
printf("\n1.TEST CONNECTIVITY");
ret = myplc.cmdSetCPUMode( id, rlDF1::NOCHANGE ); /// For Connectivity Test
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
rlsleep(3000);
printf("\n2.SET PLC IN PROGRAM MODE");
ret = myplc.cmdSetCPUMode( id, rlDF1::PROGRAM ); /// PROGRAM MODE
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
rlsleep(3000);
printf("\n3.SET PLC IN RUN MODE");
ret = myplc.cmdSetCPUMode( id, rlDF1::RUN ); /// RUN MODE
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
rlsleep(3000);
printf("\n4.GET PLC STATUS BYTES (Read Manual for details)");
unsigned char rbytes[256];
ret = myplc.cmdDiagnosticStatus( id, rbytes );
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
for(int i=0;i<ret;i++) printf("\n%d -> \t%d \t%02X", i, rbytes[i], rbytes[i]);
printf("\n");
rlsleep(3000);
printf("\n5.LOGICAL READ - Read 2 bytes from Inputs - I1:0");
ret = myplc.cmdLogicalRead( id, 2, 0x8C, 1, 0, 0, rbytes ); /// 0x8C:Read Inputs by Slot: 2 bytes from Data File I1, starting at Address 0 [ I1:0 ]
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
for(int i=0;i<ret;i++) printf("\n%d -> \t%d \t%02X", i, rbytes[i], rbytes[i]);
printf("\n");
rlsleep(3000);
printf("\n6.LOGICAL WRITE - Write 2 bytes to Outputs - Q0:0 > CYCLE FROM 0.0 to 0.7, RESET 0.8-0.15\n");
for(int i=0;i<8;i++) {
printf("SET Q0:0.%d",i);
rbytes[0]=0x01<<i;
rbytes[1]=0;
ret = myplc.cmdLogicalWrite( id, 2, 0x8B, 0, 0, 0, rbytes ); /// 0x8B:Write Outputs by Slot: 2 bytes to Data File Q0, starting at Address 0 [ Q0:0 ]
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
printf("\n");
rlsleep(1000);
}
printf("\n7.LOGICAL WRITE - Write 2 bytes to Outputs - Q0:0 > RESET 0.0-0.15");
rbytes[0]=0; /// Reset Outputs 0-15
rbytes[1]=0;
ret = myplc.cmdLogicalWrite( id, 2, 0x8B, 0, 0, 0, rbytes ); /// 0x8B:Write Outputs by Slot: 2 bytes to Data File Q0, starting at Address 0 [ Q0:0 ]
if (ret<0) {
printf("\nDevice Error %d\n",ret);
exit(-1);
}
printf("\nDuring execution of this program, we had %d Requests and %d Responses to/from PLC\n", myplc.requests(), myplc.responses());
ser.closeDevice();
}
*/

View File

@@ -0,0 +1,121 @@
/***************************************************************************
rleibnetip.h - description
-------------------
begin : Wed Apr 04 2007
copyright : (C) 2007 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_EIB_NET_IP_H_
#define _RL_EIB_NET_IP_H_
#include "rldefine.h"
#include "rludpsocket.h"
#include "rlthread.h"
#include <stdio.h>
#define EIB_ON 0x81
#define EIB_OFF 0x80
class rlDataAcquisitionProvider;
/*! <pre>
class for EIBnet/IP access
</pre> */
class rlEIBnetIP : public rlUdpSocket
{
public:
enum EIBnetIP
{
PORT = 3671,
SUCCESS = 0,
EIBERROR = 0x0ffffffff,
TIMEOUT = -1,
COULD_NOT_CONNECT = -2
};
typedef struct
{
unsigned char headersize;
unsigned char version;
unsigned short servicetype;
unsigned short totalsize;
unsigned char data[128-6];
}PDU;
typedef struct
{
unsigned char mc; // 0x29
unsigned char addi1; // 0x0
unsigned char ctrl1; // 0xbc
unsigned char ctrl2; // 0xe0
unsigned short saddr; // 0x1
unsigned short daddr; // 0x100
unsigned char apci_length; // 0x1
unsigned char apci; // 0x0
unsigned char val[14]; // 0x80
}EIB_TEL;
// this may be used by the application programmer
rlEIBnetIP(int num_signals = 1000, int debug = 0, rlDataAcquisitionProvider *provider = NULL);
virtual ~rlEIBnetIP();
int setServer(rlIpAdr *server);
int setClient(rlIpAdr *client);
int startReading();
int stopReading();
int value(const char *name);
unsigned int valueUnsigned(const char *name);
float valueFloat2(const char *name);
float valueFloat4(const char *name);
int setValue(const char *name, int val, int length=-1, int addi1=-1, int ctrl=-1, int apci=-1);
int setValueUnsigned(const char *name, unsigned int val, int length=-1, int addi1=-1, int ctrl=-1, int apci=-1);
int setValueFloat(const char *name, float val, int length=-1, int addi1=-1, int ctrl=-1, int apci=-1);
int setText(const char *name, const char *text);
int getText(const char *name, char *text, int maxlen);
int setSourceAdr(const char *adr);
int dump(FILE *fout);
int setValuesFromCSV(const char *filename);
int debug;
int watch_eib;
// the rest is for internal use only
int connect();
int disconnect();
int isConnected();
#ifndef SWIG_SESSION
int getDescription(PDU *pdu);
#endif
int recv(void *buf, int maxlen);
int storeBuffer(unsigned char *buf, int len);
int sendDisconnectRequest();
void *mem;
int memsize;
int running;
int channelid;
rlThread thread;
rlIpAdr *server;
int send_sequencecounter;
int tunnel_ack;
rlDataAcquisitionProvider *provider;
private:
int printTelegram(EIB_TEL *tel);
int storeInProvider(EIB_TEL *tel);
rlIpAdr client;
rlIpAdr from;
int maxvalues;
int is_connected;
short saddr;
};
#endif

View File

@@ -0,0 +1,64 @@
/***************************************************************************
rlevent.h - description
-------------------
begin : Wed Dec 18 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/*! <pre>
These functions allow you to send event log messages over TCP/IP to the event log server
implemented by the pvserver pcontrol (available as separate download)
See also the class rlEventLogServer.
</pre> */
#ifndef _RL_EVENT_H_
#define _RL_EVENT_H_
#include "rldefine.h"
#define rlMAX_EVENT 256 // maximum size of an event message
static const char rlevent_name[][4] = { "INF", "WAR", "ERR", "CRI", "FAT", "TST" };
enum EventTypes
{
rlInfo = 0,
rlWarning,
rlError,
rlCritical,
rlFatal,
rlTest,
rlEVENT_SIZE
};
#ifdef XXXunix
#define rlEvent(typ, format, args...) { rlSetEventLocation(__FILE__,__LINE__); rlEventPrintf( typ, format, args); }
#else
#define rlEvent rlSetEventLocation(__FILE__,__LINE__);rlEventPrintf
#endif
/*! <pre>
initialize rlEvent
parameters:
-eventhost=adr
-eventport=num
</pre> */
void rlEventInit(int ac, char **av, const char *module);
/*! <pre>
set the location where rlEvent is called
</pre> */
void rlSetEventLocation(const char *file, int line);
/*! <pre>
output the message
</pre> */
void rlEventPrintf(int event_type, const char *format, ...);
#endif

View File

@@ -0,0 +1,79 @@
/***************************************************************************
rleventlogserver.h - description
-------------------
begin : Wed Dec 18 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_EVENT_LOG_SERVER_H_
#define _RL_EVENT_LOG_SERVER_H_
#include "rldefine.h"
#include "rlevent.h"
#include "rlthread.h"
#define rlMAX_MESSAGES 128
/*! <pre>
A class for implementing an event log server.
You may use it with rlevent.h
</pre> */
class rlEventLogServer
{
public:
/*! <pre>
the event log files will be called:
filename<date-and-time>.rlEventLog
max_events = max number of events in one file
files may be purged by cron
</pre> */
rlEventLogServer(const char *filename=NULL, int max_events=10000);
virtual ~rlEventLogServer();
/*! <pre>
num is the event number
num = -1 will retrieve all events
</pre> */
const char *getEvent(char *buf, int *num);
void putEvent(const char *event);
private:
char memory[rlMAX_MESSAGES*rlMAX_EVENT];
rlMutex mutex;
int front;
int cnt;
char *filename;
void *fp;
int max_events, num_events;
};
/*! <pre>
This class starts a separate thread, that runs a rlEventLogServer log server.
It waits on TCP port for clients. See rlevent.h
</pre> */
class rlEventLogServerThreads
{
public:
/*! <pre>
event_log_server will not be deleted by the destructor
</pre> */
rlEventLogServerThreads(int port, rlEventLogServer *event_log_server);
virtual ~rlEventLogServerThreads();
void start();
int getPort();
rlEventLogServer *event_log_server;
private:
rlThread acceptThread;
int port;
};
#endif

View File

@@ -0,0 +1,57 @@
/***************************************************************************
rlfifo.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_FIFO_H_
#define _RL_FIFO_H_
#include "rldefine.h"
#include "rlthread.h"
/*! <pre>
class for a fifo. (first in first out)
</pre> */
class rlFifo
{
private:
typedef struct _MessageList_
{
char *mes;
int len;
struct _MessageList_ *next;
}MessageList;
public:
rlFifo(int maxmessages=0);
virtual ~rlFifo();
enum FifoEnum {
DATA_AVAILABLE=-1, NO_DATA_AVAILABLE=-2, MESSAGE_TO_BIG=-3, FIFO_FULL=-4
};
int read(void *buf, int maxlen);
int poll();
int nmesAvailable();
int write(const void *buf, int len);
int printf(const char *format, ...);
private:
int maxmes;
int nmes;
MessageList *list;
WSEMAPHORE semaphore;
pthread_mutex_t mutex;
};
#endif

View File

@@ -0,0 +1,50 @@
/***************************************************************************
rlfileload.h - description
-------------------
begin : Fri Jul 28 2006
copyright : (C) 2006 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_FILE_LOAD_H_
#define _RL_FILE_LOAD_H_
#include "rldefine.h"
#include "rlstring.h"
typedef struct _rlFileLines_
{
char *line;
struct _rlFileLines_ *next;
}rlFileLines;
/*! <pre>
This class loads a text file to memory.
Then you can iterate to it's lines.
</pre> */
class rlFileLoad
{
public:
rlFileLoad();
virtual ~rlFileLoad();
int load(const char *filename);
void unload();
const char *firstLine();
const char *nextLine();
void setDebug(int state);
int text2rlstring(rlString &rlstring);
private:
int loaded;
int debug;
rlFileLines file_lines;
rlFileLines *current_line;
};
#endif

View File

@@ -0,0 +1,76 @@
/***************************************************************************
rlhilschercif.h - description
-------------------
begin : Tue Feb 13 2007
copyright : (C) 2007 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_HILSCHER_CIF_H_
#define _RL_HILSCHER_CIF_H_
#include "rldefine.h"
#include "rlthread.h"
#ifdef RLUNIX
#include "cif_user.h" /* Include file for device driver API */
#else
#include "CIFUSER.h"
#endif
#include "rcs_user.h" /* Include file for RCS definition */
#include "asc_user.h" /* Include file for ASCII protocols */
#include "nvr_user.h" /* Include file for 3964R protocol */
/*! <pre>
This class is for data access to Hilscher CIF cards
like PROFIBUS ...
It uses the driver provided by Hilscher and has access to it's dual ported RAM.
Attention: In order to use this class on Linux as normal user you have to set
chmod ugoa+rw /dev/cif
</pre> */
class rlHilscherCIF
{
public:
rlHilscherCIF();
virtual ~rlHilscherCIF();
int debug;
int open(); // convenience method
int close(); // convenience method
int devGetMessage(int timeout); // use mailbox, uses tMessage
int devPutMessage(int timeout); // use mailbox, please set tMessage
int devExchangeIO(int sendOffset, int sendSize, unsigned char *sendData,
int receiveOffset, int receiveSize, unsigned char *receiveData,
int timeout);
int devOpenDriver();
int devInitBoard();
int devGetInfo(int info); // info = GET_FIRMWARE_INFO | GET_IO_INFO
int devSetHostState(int mode); // mode = HOST_READY | HOST_NOT_READY
int devPutTaskParameter();
int devReset();
int devExitBoard();
int devCloseDriver();
void printFirmwareInfo();
unsigned short usBoardNumber; // Board number, 0-3
unsigned short usDevState, usHostState;
unsigned char abInfo[300]; // Buffer for various information
ASC_PARAMETER aParameter; // Parameters for ASCII protocolls
IOINFO tIoInfo; // IO information structure
RCS_MESSAGETELEGRAM_10 tMessage;
rlMutex mutex;
private:
int isOpen;
};
#endif

View File

@@ -0,0 +1,55 @@
/***************************************************************************
rlhistorylogger.h - description
-------------------
begin : Wed Dec 06 2006
copyright : (C) 2006 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_HISTORY_LOGGER_H_
#define _RL_HISTORY_LOGGER_H_
#include "rldefine.h"
#include "rltime.h"
#include "rlthread.h"
#include <stdio.h>
typedef struct _rlHistoryLogLine_
{
_rlHistoryLogLine_ *next;
char *line;
}rlHistoryLogLine;
/*! <pre>
This class logs tab separated text including time stamp in 10 csv files + actual values in memory
This is for archiveing historical data with time stamp.
You should separate the text in pushLine with tab.
</pre> */
class rlHistoryLogger
{
public:
rlHistoryLogger(const char *csvName, int maxHoursPerFile, int maxLinesInMemory=100);
virtual ~rlHistoryLogger();
int pushLine(const char *text);
const char *firstLine();
const char *nextLine();
rlMutex mutex;
int debug;
private:
int pushLineToMemory(const char *line);
int pushLineToFile(const char *line);
int openFile();
rlHistoryLogLine *first_line,*current_line;
rlTime time,file_start_time,time_diff;
FILE *fout;
int max_hours_per_file, max_lines_in_memory, current_file;
char *csv_name, *csv_file_name;
};
#endif

View File

@@ -0,0 +1,106 @@
/***************************************************************************
rlhistoryreader.h - description
-------------------
begin : Wed Dec 06 2006
copyright : (C) 2006 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_HISTORY_READER_H_
#define _RL_HISTORY_READER_H_
#include "rldefine.h"
#include "rltime.h"
#include <stdio.h>
typedef struct _rlHistoryReaderLine_
{
_rlHistoryReaderLine_ *next;
char *line;
}rlHistoryReaderLine;
/*! <pre>
This class reads tab separated text including time stamp from 10 csv files
Use it together with rlHistoryLogger.
Example usage within pvbrowser slot function:
#include "rlhistoryreader.h"
typedef struct // (todo: define your data structure here)
{
rlHistoryReader hist;
}
DATA;
...snip...
static int slotButtonEvent(PARAM *p, int id, DATA *d)
{
if(p == NULL || id == 0 || d == NULL) return -1;
if(id == buttonShowPlot)
{
rlTime tStart, tDiff, tEnd;
tStart.year = 2009;
tStart.month = 8;
tStart.day = 29;
tStart.hour = 0;
tDiff.hour = 24;
tEnd = tStart + tDiff;
printf("start=%s diff=%s end=%s\n",tStart.getTimeString(), tDiff.getTimeString(), tEnd.getTimeString());
if(d->hist.read("test", &tStart, &tEnd) < 0)
{
printf("could not read test csv file\n");
return 0;
}
const char *line = d->hist.firstLine();
while(*line != '\\0')
{
printf("line=%s", line);
const char *values = strchr(line,'\t');
if(values != NULL)
{
float val1, val2;
sscanf(values,"\t%f\t%f", &val1, &val2);
printf("val1=%f val2=%f\n", val1, val2);
//// fill your buffer for plotting here
}
line = d->hist.nextLine();
}
//// display your xy-graphic from the filled buffer here
}
return 0;
}
</pre> */
class rlHistoryReader
{
public:
rlHistoryReader();
virtual ~rlHistoryReader();
int read(const char *csvName, rlTime *start, rlTime *end);
const char *firstLine();
const char *nextLine();
int clean();
int cat(const char *csvName, FILE *fout);
int debug;
private:
int openFile();
int pushLineToMemory(const char *line);
rlHistoryReaderLine *first_line,*current_line;
rlTime time;
FILE *fin;
int current_file;
char *csv_name, *csv_file_name;
};
#endif

View File

@@ -0,0 +1,46 @@
/***************************************************************************
rlhtml.h - description
-------------------
begin : Thu Jul 30 2015
copyright : (C) Lehrig Software Enigineering
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_HTML_H_
#define _RL_HTML_H_
#include "rldefine.h"
#include "rlstring.h"
/*! <pre>
conveniance base class for html
</pre> */
class rlHtml
{
public:
rlHtml();
virtual ~rlHtml();
/*! <pre>
html can be configured with rlhtml.css
</pre> */
const char *htmlHeader();
const char *htmlTrailer();
/*! <pre>
html representation of text file
</pre> */
int textFile(const char *filename, rlString &text);
/*! <pre>
hexdump representation of text file
</pre> */
int hexdumpFile(const char *filename, rlString &text);
};
#endif

View File

@@ -0,0 +1,70 @@
/***************************************************************************
rlhtmldir.h - description
-------------------
begin : Thu Jul 30 2015
copyright : (C) Lehrig Software Enigineering
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_HTMLDIR_H_
#define _RL_HTMLDIR_H_
#include "rlhtml.h"
#include "rlspreadsheet.h"
/*! <pre>
class for a file selector with html
</pre> */
class rlHtmlDir : public rlHtml
{
public:
enum
{
list_files_and_directories = 1,
list_directories_only = 2,
list_files_only = 3
}WHAT_TO_LIST;
rlHtmlDir();
virtual ~rlHtmlDir();
/*! <pre>
dir := ".." | "absolute_path" | "relative_path"
</pre> */
int cd(const char *dir, int is_initial_dir=0);
/*! <pre>
html can be configured with rlhtml.css
</pre> */
const char *getHtml(int generate_html_header_and_trailer=1);
/*! <pre>
list of filenames found
return: number of files found
</pre> */
int getFilenames(rlSpreadsheetRow *row);
rlString initialPath; // initial path
rlString currentPath; // current path
rlString pattern; // search pattern for rlfind, default *
int recursive; // 0|1
int list_what; // enum WHAT_TO_LIST
int hide_hidden_files; // 0|1
rlString textHome; // default Home:
rlString textPath; // default Path:
rlString textrlHtmlDirCSS; // default rlhtml.css
rlString startHtml; // default html is empty
rlString endHtml; // default html is empty
private:
rlString html; // header + startHtml + rlfind_results + endHtml + trailer
};
#endif

View File

@@ -0,0 +1,126 @@
/***************************************************************************
rlinifile.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_INI_FILE_H_
#define _RL_INI_FILE_H_
#include "rldefine.h"
#include "rlstring.h"
/*! <pre>
class for INI files as known from Windows.
</pre> */
class rlIniFile
{
public:
rlIniFile();
virtual ~rlIniFile();
int read(const char *filename);
int write(const char *filename);
const char *filename();
const char *text(const char *section, const char *name);
void setText(const char *section, const char *name, const char *text);
int printf(const char *section, const char *name, const char *format, ...);
void remove(const char *section);
void remove(const char *section, const char *name);
const char *firstSection();
const char *nextSection();
const char *firstName(const char *section);
const char *nextName(const char *section);
void setDefaultSection(const char *section);
const char *defaultSection();
/*! <pre>
Use this method for translating text within your application.
Example:
ini->setDefaultSection("german");
printf("german_text=%s\n", ini->i18n("text1","This is text1") );
</pre> */
const char *i18n(const char *tag, const char *default_text="");
/*! <pre>
Use this method for translating text within your application.
Example:
#define TR(txt) d->translator.tr(txt)
typedef struct // (todo: define your data structure here)
{
rlIniFile translator;
}
DATA;
static int slotInit(PARAM *p, DATA *d)
{
if(p == NULL || d == NULL) return -1;
d->translator.read("text.ini");
d->translator.setDefaultSection("DEUTSCH");
printf("test1=%s\n", TR("umlaute"));
printf("test2=%s\n", TR("Xumlaute"));
d->translator.setDefaultSection("ENGLISH");
printf("test1=%s\n", TR("umlaute"));
printf("test2=%s\n", TR("Xumlaute"));
}
With text.ini:
[DEUTSCH]
hello=Hallo
world=Welt
umlaute=äöüß
[ENGLISH]
hello=Hello
world=World
umlaute=german_umlaute=äöüß
</pre> */
const char *tr(const char *txt);
private:
typedef struct _rlSectionName_
{
_rlSectionName_ *nextName;
char *name;
char *param;
}rlSectionName;
typedef struct _rlSection_
{
_rlSection_ *nextSection;
rlSectionName *firstName;
char *name;
}rlSection;
void copyIdentifier(char *buf, const char *line);
void copyName(char *buf, const char *line);
void copyParam(char *buf, const char *line);
void deleteSectionNames(rlSection *section);
rlSection *_firstSection;
int currentSection, currentName;
rlString fname;
rlString default_section;
};
int rlSetTranslator(const char *language, const char *inifile=NULL);
#ifndef SWIGPYTHON
const char *rltranslate(const char *txt, char **mytext=NULL);
const char *rltranslate2(const char *section, const char *txt, char **mytext=NULL);
#define rltr(txt) rltranslate(txt)
#ifdef pvtr
#undef pvtr
#endif
#define pvtr(txt) rltranslate2(p->lang_section,txt,&p->mytext2)
#endif
#endif

View File

@@ -0,0 +1,39 @@
/***************************************************************************
rlinterpreter.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_INTERPRETER_H_
#define _RL_INTERPRETER_H_
#include "rldefine.h"
/*! <pre>
A class for interpreting text.
</pre> */
class rlInterpreter
{
public:
rlInterpreter(int Maxline=rl_PRINTF_LENGTH);
virtual ~rlInterpreter();
char *line;
int isCommand(const char *command);
void copyStringParam(char *destination, int index);
int maxchar();
private:
int maxline;
};
#endif

View File

@@ -0,0 +1,43 @@
// include all headers from rllib
#ifndef _RLLIB_H
#define _RLLIB_H
#include "rlspawn.h"
#include "rlwthread.h"
#include "rlthread.h"
#include "rlsocket.h"
#include "rltime.h"
#include "rlmailbox.h"
#include "rlfifo.h"
#include "rlsharedmemory.h"
#include "rlspreadsheet.h"
#include "rlinifile.h"
#include "rlinterpreter.h"
#include "rlpcontrol.h"
#include "rlcutil.h"
#include "rldefine.h"
#include "rlevent.h"
#include "rleventlogserver.h"
#include "rldataprovider.h"
#include "rlserial.h"
#include "rlmodbus.h"
#include "rlmodbusclient.h"
#include "rl3964r.h"
#include "rlsiemenstcp.h"
#include "rlsiemenstcpclient.h"
#include "rlcontroller.h"
#include "rlppiclient.h"
#include "rlsvganimator.h"
#include "rlsvgcat.h"
#include "rlfileload.h"
#include "rlhistorylogger.h"
#include "rlhistoryreader.h"
//#include "rlhilschercif.h" // include this separately because it will produce warnings
#include "rludpsocket.h"
#include "rleibnetip.h"
#include "rlopcxmlda.h"
#include "rldataacquisition.h"
#include "rldataacquisitionprovider.h"
#include "rlstring.h"
#endif

View File

@@ -0,0 +1,127 @@
/***************************************************************************
rlmailbox.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_MAILBOX_H_
#define _RL_MAILBOX_H_
#include "rldefine.h"
/*! <pre>
class for a mailbox.
A mailbox is for communication between processes on the same computer.
It works like a fifo.
Many processes can write to 1 mailbox.
Only 1 reader is allowed.
</pre> */
class rlMailbox
{
public:
enum MailboxEnum
{
/// return codes for write()
MAILBOX_ERROR = -1,
MAILBOX_FULL = -2,
/// wait parameter for read()
WAIT = 1,
NOWAIT = 0,
/// maximum mailbox length
MAX_MAILBOX = 256*256,
/// status:
OK = 2,
COULD_NOT_CREATE_MAILBOX = 3,
COULD_NOT_GET_KEY = 4,
COULD_NOT_GET_CHAN_ID = 5
};
/*! <pre>
construct a named mailbox
</pre> */
rlMailbox(const char *name);
/*! <pre>
destruct the mailbox
</pre> */
virtual ~rlMailbox();
/*! <pre>
write buf with length len to mailbox
return: bytes written
MAILBOX_ERROR
MAILBOX_FULL
</pre> */
int write(const void *buf, int len);
/*! <pre>
similar to printf
return: bytes written
MAILBOX_ERROR
MAILBOX_FULL
</pre> */
int printf(const char *format, ...);
/*! <pre>
read buf from mailbox, maxlen=Maximal length of buf
return: number of bytes read
wait = 0 no wait
wait = 1 wait for message
</pre> */
int read(void *buf, int maxlen, int wait=WAIT);
/*! <pre>
set the size of buffer for "const char *read(int wait)"
</pre> */
int setReadBufferSize(int size);
/*! <pre>
read buffer from mailbox
return: buffer | ""
wait = 0 no wait
wait = 1 wait for message
</pre> */
const char *read(int wait=WAIT);
/*! <pre>
write message to mailbox
return: bytes written
MAILBOX_ERROR
MAILBOX_FULL
</pre> */
int write(const char *message);
/*! <pre>
read all messages from mailbox, clear them
</pre> */
void clear();
/*! <pre>
should be: OK
can be: COULD_NOT_CREATE_MAILBOX
COULD_NOT_GET_CHAN_ID
</pre> */
int status;
/*! <pre>
Name of mailbox
</pre> */
char *name;
private:
int chanid;
int buffer_size;
char *buffer;
};
#endif

View File

@@ -0,0 +1,257 @@
/***************************************************************************
rlmodbus.h - description
-------------------
begin : Tue Mar 13 2003
copyright : (C) 2003 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_MODBUS_H_
#define _RL_MODBUS_H_
#include "rldefine.h"
#include "rlsocket.h"
#include "rlserial.h"
/*! <pre>
This class implements the modbus protocol.
You can use serial interfaces or TCP/IP.
Modbus RTU and ASCII are available.
All Modbus requests include "slave" and "function".
Then some bytes follow, which are specific to a given function.
The request is then terminated by a checksum.
This table shows the bytes that are specific to a given function.
</pre>
<TABLE CELLSPACING="0" COLS="4" BORDER="0">
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP><B>Function</B></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><B>Query</B></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><B>Response</B></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><B><BR></B></TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="62" ALIGN="LEFT" VALIGN=TOP>01 Read Coil Status</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of points high<BR>Number of points low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Data Byte Count<BR>Data1<BR>Data2 …</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>8 points per byte</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="62" ALIGN="LEFT" VALIGN=TOP>02 Read Input Status</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of points high<BR>Number of points low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Data Byte Count<BR>Data1 <BR>Data2 …</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>8 points per byte</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="77" ALIGN="LEFT" VALIGN=TOP>03 Read Holding Registers</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of points high<BR>Number of points low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Data Byte Count<BR>Data1 high<BR>Data1 low<BR>Data2 high<BR>Data2 low…</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>1 point needs 2 bytes</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="77" ALIGN="LEFT" VALIGN=TOP>04 Read Input Registers</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of points high<BR>Number of points low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Data Byte Count<BR>Data1 high<BR>Data1 low<BR>Data2 high<BR>Data2 low…</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>1 point needs 2 bytes</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="62" ALIGN="LEFT" VALIGN=TOP>05 Force Single Coil</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Coil adr high<BR>Coil adr low<BR>Force data high<BR>Force data low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Coil adr high<BR>Coil adr low<BR>Force data high<BR>Force data low </TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Force data ON = 0x0ff00<BR>Force data OFF = 0</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="62" ALIGN="LEFT" VALIGN=TOP>06 Preset Single Register</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Register adr high<BR>Register adr low<BR>Preset data high<BR>Preset data low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Register adr high<BR>Register adr low<BR>Preset data high<BR>Preset data low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>07 Read Exception Status</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Coil data</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>8 exception status coils returned</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="62" ALIGN="LEFT" VALIGN=TOP>11 Fetch Comm Event Counter</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Status high<BR>Status low<BR>Event Count high<BR>Event Count low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>12 Fetch Comm Event Log</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="136" ALIGN="LEFT" VALIGN=TOP>15 Force Multiple Coils</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Coil adr high<BR>Coil adr low<BR>Number of coils high<BR>Number of coils low<BR>Force data byte count<BR>Force data1<BR>Force data2 ...</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Coil adr high<BR>Coil adr low<BR>Number of coils high<BR>Number of coils low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>8 coils per byte</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="136" ALIGN="LEFT" VALIGN=TOP>16 Preset Multiple Registers</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of registers high<BR>Number of registers low<BR>Data byte count<BR>Data1 high<BR>Data1 low<BR>Data2 high<BR>Data2 low …</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Start adr high<BR>Start adr low<BR>Number of registers high<BR>Number of registers low</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>17 Report Slave ID</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>Data Byte count ~ device specific</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>20 Read General Reference</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>21 Write General Reference</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>22 Mask Write 4X Register</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>23 Read/Write 4X Registers</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
<TR>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" HEIGHT="17" ALIGN="LEFT" VALIGN=TOP>24 Read FIFO Queue</TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP><BR></TD>
<TD STYLE="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" ALIGN="LEFT" VALIGN=TOP>See: PI_MODBUS_300.pdf</TD>
</TR>
</TABLE>
*/
class rlModbus
{
public:
/*! <pre>
data exchanged by Modbus is either:
1byte unsigned for coils
2byte unsigned for registers
Helper union for converting Modbus data to data types that are not standard Modbus data types
Example:
rlModbus::DATA data;
data.u_short[0] = registers[0]; // store an unsigned 16 bit register in union data
printf("print registers[0] as signed int value=%d\n", data.s_short[0]);
</pre> */
typedef union
{
unsigned char u_char[4]; // 4 * 8bit_data, unsigned
char s_char[4]; // 4 * 8bit_data, signed
unsigned short u_short[2]; // 2 * 16bit_data, signed
short s_short[2]; // 2 * 16bit_data, signed
unsigned int u_int; // 1 * 32bit_data, unsigned
int s_int; // 1 * 32bit_data, signed
float s_float; // 1 * 32bit_data, signed
}DATA;
enum Modbus
{
MODBUS_CHECKSUM_ERROR = -2,
MODBUS_ERROR = -1,
MODBUS_SUCCESS = 0,
MODBUS_RTU = 1,
MODBUS_ASCII = 2
};
enum ModbusFunctionCodes
{
ReadCoilStatus = 1,
ReadInputStatus = 2,
ReadHoldingRegisters = 3,
ReadInputRegisters = 4,
ForceSingleCoil = 5,
PresetSingleRegister = 6,
ReadExceptionStatus = 7,
FetchCommEventCtr = 11,
FetchCommEventLog = 12,
ForceMultipleCoils = 15,
PresetMultipleRegs = 16,
ReportSlaveID = 17,
ReadGeneralReference = 20,
WriteGeneralReference = 21,
MaskWrite4XRegisters = 22,
ReadWrite4XRegisters = 23,
ReadFifoQueue = 24
};
rlModbus(long max_telegram_length = 1024, int mode = MODBUS_RTU, char end_delimitor = 0x0a);
virtual ~rlModbus();
int write (int slave, int function, const unsigned char *data, int len, int *transactionID = NULL);
int request (int slave, int function, int start_adr, int num_register);
int response(int *slave, int *function, unsigned char *data, int timeout=1000);
int readRequest(int *slave, int *function, unsigned char *data, int timeout=1000, int *transactionID = NULL);
void registerSocket(rlSocket *socket);
void registerSerial(rlSerial *serial);
int data2int(const unsigned char *data);
int int2data(int val, unsigned char *data);
int intsize();
int autoreconnectSocket;
int readCoilStatus (int slave, int start_adr, int number_of_coils, unsigned char *status, int timeout=1000);
int readInputStatus (int slave, int start_adr, int number_of_inputs, unsigned char *status, int timeout=1000);
/*! <pre>
We assume positive values for registers: 0 <= registers < 256*256
</pre> */
int readHoldingRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000);
/*! <pre>
We assume positive values for registers: 0 <= registers < 256*256
</pre> */
int readInputRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000);
int forceSingleCoil (int slave, int coil_adr, int value, int timeout=1000);
/*! <pre>
We assume positive values for registers: 0 <= value < 256*256
</pre> */
int presetSingleRegister (int slave, int register_adr, int value, int timeout=1000);
/*! <pre>
We assume positive values for registers: 0 <= registers < 256*256
</pre> */
int forceMultipleCoils (int slave, int coil_adr, int number_of_coils, unsigned char *coils, int timeout=1000);
/*! <pre>
We assume positive values for registers: 0 <= registers < 256*256
</pre> */
int presetMultipleRegisters (int slave, int start_adr, int number_of_registers, int *registers, int timeout=1000);
private:
int buf2int_rtu(unsigned char *buf);
void int2buf_rtu(int i, unsigned char *buf);
int buf2int_ascii(unsigned char *buf);
void int2buf_ascii(int i, unsigned char *buf);
void insertLRC(int len);
void insertCRC(int len);
int LRCerror(int len);
int CRCerror(int len);
rlSocket *s;
rlSerial *tty;
unsigned char *tel;
long maxtel;
int mode;
char delimitor;
};
#endif

View File

@@ -0,0 +1,44 @@
/***************************************************************************
rlmodbusclient.h - description
-------------------
begin : Wed Jan 07 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_MODBUS_CLIENT_H_
#define _RL_MODBUS_CLIENT_H_
#include "rldefine.h"
#include "rlmodbus.h"
#include "rlmailbox.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is for data aqusition over a modbus daemon as created by pvdevelop.
It communicates over a shared memory and a mailbox according to the pvbrowser principle.
</pre> */
class rlModbusClient : public rlMailbox, public rlSharedMemory
{
public:
rlModbusClient(const char *mbxname, const char *shmname, int shmsize);
virtual ~rlModbusClient();
int write(int slave, int function, const unsigned char *data, int len);
int writeSingleCoil(int slave, int adr, int value);
int writeMultipleCoils(int slave, int adr, const unsigned char *values, int num_coils);
int writePresetSingleRegister(int slave, int adr, int value);
int writePresetMultipleRegisters(int slave, int adr, const int *values, int num_values);
int readBit(int offset, int number);
int readByte(int offset, int number);
int readShort(int offset, int number);
};
#endif

View File

@@ -0,0 +1,78 @@
/***************************************************************************
rlopcxmlda.h - description
-------------------
begin : Mon Aug 27 2007
copyright : (C) 2007 by pvbrowser
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/**
use this class together with opcxmlda_client.
opcxmlda_client will fill the shared memory with variables read over opc xml-da.
opcxmlda_client will receive outgoing writes through it's mailbox.
*/
#ifndef _RL_OPC_XML_DA_H_
#define _RL_OPC_XML_DA_H_
#include "rldefine.h"
#include "rlmailbox.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is for data acquisition within pvserver according to the pvbrowser principle.
It communicates with the daemon opcxmlda_client by the means of a shared memory and a mailbox.
</pre> */
class rlOpcXmlDa
{
public:
// shared memory header
typedef struct
{
char ident[4]; // must be "opc"
int maxItemNameLength; // maximum length of an item name
int maxNameLength; // maximum length of the item value
int numItems; // number of items in shared memory
int readErrorCount; // 0...65536 incremented by each read error
int writeErrorCount; // 0...65536 incremented by each write error
int spare[8]; // for future use
char cspare[32]; // for future use
}SHM_HEADER;
enum OPC_XML_DA_ENUM
{
OPCXMLDA_ERROR = 256*256*128
};
#ifdef RLWIN32
rlOpcXmlDa(const char *mailbox="c:\\automation\\mbx\\opcxmlda.mbx", const char *shared_memory="c:\\automation\\shm\\opcxmlda.shm", long shared_memory_size=65536);
#else
rlOpcXmlDa(const char *mailbox="/srv/automation/mbx/opcxmlda.mbx", const char *shared_memory="/srv/automation/shm/opcxmlda.shm", long shared_memory_size=65536);
#endif
virtual ~rlOpcXmlDa();
const char *stringValue(const char *variable);
int intValue(const char *variable);
float floatValue(const char *variable);
int writeStringValue(const char *variable, const char *value);
int writeIntValue(const char *variable, int value);
int writeFloatValue(const char *variable, float value);
int readErrorCount();
int writeErrorCount();
int shmStatus(); // 0 if shared memory is ok | ERROR if shared memory is not ok
private:
SHM_HEADER *shmheader;
const char *shmvalues;
rlMailbox *mbx;
rlSharedMemory *shm;
};
#endif

View File

@@ -0,0 +1,141 @@
/***************************************************************************
rlspawn.h - description
-------------------
begin : Wed Dec 11 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_PCONTROL_H_
#define _RL_PCONTROL_H_
#include "rltime.h"
/*! <pre>
A class for starting/stoping/monitoring other processes.
</pre> */
class rlPcontrol
{
public:
/*! <pre>
construct a process control object
</pre> */
rlPcontrol();
/*! <pre>
deconstruct the process control object
</pre> */
virtual ~rlPcontrol();
/*! <pre>
set the startup command and the process_name
</pre> */
void setStartupCommand(const char *command, const char *process_name);
/*! <pre>
start the process
</pre> */
int start();
/*! <pre>
stop the process with SIGTERM
</pre> */
int sigterm();
/*! <pre>
stop the process with SIGKILL
</pre> */
int sigkill();
/*! <pre>
test if process is alive
</pre> */
int isAlive();
/*! <pre>
get startup command
</pre> */
const char *startupCommand();
/*! <pre>
get process name
</pre> */
const char *processName();
/*! <pre>
get process time start/stop
</pre> */
rlTime *processTime();
/*! <pre>
set process id
</pre> */
void setPID(long pid);
/*! <pre>
get process id
</pre> */
long pid();
/*! <pre>
get next object in list
</pre> */
rlPcontrol *getNext();
/*! <pre>
add and return a new rlPcontrol object
</pre> */
rlPcontrol *addNew();
#ifdef __VMS
/*! <pre>
set input filename or logical
</pre> */
void setInput (const char *input);
/*! <pre>
set output filename or logical
</pre> */
void setOutput(const char *output);
/*! <pre>
set error filename or logical
</pre> */
void setError (const char *error);
#endif
/*! <pre>
set priority default=8
</pre> */
void setPriority(int priority);
/*! <pre>
get priority
</pre> */
int priority();
private:
int rlstrlen(const char *str);
char *startup_command, *process_name;
#ifdef __VMS
char *m_input, *m_output, *m_error;
#endif
#ifdef RLWIN32
long m_dwProcessId;
#endif
long m_pid;
rlTime process_time;
rlPcontrol *next;
int prio;
};
#endif

View File

@@ -0,0 +1,95 @@
/***************************************************************************
rlplc.h - description
-------------------
begin : Tue Dec 11 2008
copyright : (C) 2008 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_PLC_H_
#define _RL_PLC_H_
#include "rldefine.h"
#include "rlsharedmemory.h"
class rlPlcState
{
public:
rlPlcState(int numInt=100, int numFloat=100, int numDouble=0, const char *shared_memory=NULL);
virtual ~rlPlcState();
int *i, *i_old;
float *f, *f_old;
double *d, *d_old;
void clear();
void rememberState();
int intChanged(int index);
int floatChanged(int index);
int doubleChanged(int index);
int intHasIncreased(int index);
int floatHasIncreased(int index);
int doubleHasIncreased(int index);
int intHasDecreased(int index);
int floatHasDecreased(int index);
int doubleHasDecreased(int index);
int deltaInt(int index);
float deltaFloat(int index);
double deltaDouble(int index);
void set(int index, int bit);
void clear(int index, int bit);
int isSet(int index, int bit);
int isClear(int index, int bit);
int hasBeenSet(int index, int bit);
int hasBeenCleared(int index, int bit);
int maxInt();
int maxFloat();
int maxDouble();
int getInt(int index);
float getFloat(int index);
double getDouble(int index);
int getOldInt(int index);
float getOldFloat(int index);
double getOldDouble(int index);
rlSharedMemory *shm;
private:
int max_int, max_float, max_double;
};
class rlPlcMem
{
public:
rlPlcMem();
virtual ~rlPlcMem();
int i, i_old;
float f, f_old;
double d, d_old;
void rememberState();
int intChanged();
int floatChanged();
int doubleChanged();
int intHasIncreased();
int floatHasIncreased();
int doubleHasIncreased();
int intHasDecreased();
int floatHasDecreased();
int doubleHasDecreased();
int deltaInt();
float deltaFloat();
double deltaDouble();
void set(int bit);
void clear(int bit);
int isSet(int bit);
int isClear(int bit);
int hasBeenSet(int bit);
int hasBeenCleared(int bit);
};
#endif

View File

@@ -0,0 +1,64 @@
/***************************************************************************
rlppiclient.h - description
-------------------
begin : Mon Jul 12 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_PPI_CLIENT_H_
#define _RL_PPI_CLIENT_H_
#include "rldefine.h"
#include "rlmailbox.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is for data acquisition from pvserver according to the pvbrowser principle.
The according daemon is generated by pvdevelop.
It communicates by the means of a shared memory and a mailbox.
</pre> */
class rlPPIClient : public rlMailbox, rlSharedMemory
{
public:
enum PPI_area
{
daveSD = 0x3,
daveInputs = 0x81,
daveOutputs = 0x82,
daveFlags = 0x83,
daveDB = 0x84, //data blocks
daveDI = 0x85, //not tested
daveLocal = 0x86, //not tested
daveV = 0x87, // don't know what it is
daveCounter = 28, //not tested
daveTimer = 29 //not tested
};
rlPPIClient(const char *mbxname, const char *shmname, int shmsize, int have_to_swap=1);
virtual ~rlPPIClient();
int write(int slave, int area, int dbnum, int start, int len, const unsigned char *data);
int writeFloat(int slave, int area, int dbnum, int start, int len, const float *val);
int writeDword(int slave, int area, int dbnum, int start, int len, const int *val);
int writeShort(int slave, int area, int dbnum, int start, int len, const short *val);
int writeUDword(int slave, int area, int dbnum, int start, int len, const unsigned int *val);
int writeUShort(int slave, int area, int dbnum, int start, int len, const unsigned short *val);
int read(int offset, int len);
float Float(int index);
int Dword(int index);
int Short(int index);
unsigned int UDword(int index);
unsigned int UShort(int index);
unsigned char buf[512]; // after calling read, the data is here
private:
int have_to_swap;
};
#endif

View File

@@ -0,0 +1,155 @@
/***************************************************************************
rlreport.h - description
-------------------
begin : Sun Jul 03 2011
copyright : (C) 2011 pvbrowser
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_REPORT_H_
#define _RL_REPORT_H_
#include <stdio.h>
#include "rldefine.h"
#include "rlinifile.h"
#include "rlstring.h"
/*! <pre>
class for generating PDF files with LaTeX
//### typical usage begin #############################################
int report(PARAM *p)
{
rlReport r;
rlString filename;
filename = p->file_prefix; // use an individual filename for each client
filename += ".tex";
r.open(filename.text());
r.includeHeader("\\documentclass[a4paper]{article}","\\usepackage[ngerman]{babel}"); // german article on A4 paper
//// here we may include our own header definitions
r.beginDocument();
//// --- begin here we use the methods: printf(), include(), includeCSV(), includeImage(), spawn() --------------
r.printf("\\section{Teil 1}\n");
r.printf("Hallo Welt\n");
r.includeImage("test.jpg","Testbild",0.8f);
r.includeCSV("test.csv",1,"Test CSV");
r.printf("\\cppbegin{main.cpp}\n");
r.include("main.cpp");
r.printf("\\end{lstlisting}\n");
r.printf("\\simplecodebegin{Verzeichnis Inhalt}\n");
r.spawn("ls -al");
r.printf("\\end{lstlisting}\n");
//// --- end here we use the methods: printf(), include(), includeCSV(), includeImage(), spawn() ----------------
r.endDocument();
r.close();
r.pdflatex(); // pdflatex -interaction=nonstopmode file.tex
filename = p->file_prefix;
filename += ".pdf";
pvDownloadFileAs(p,filename.text(), "report.pdf");
pvClientCommand(p,"pdf","report.pdf"); // open report.pdf on the client using the pdf-viewer
return 0;
}
//### typical usage end ###############################################
</pre> */
class rlReport
{
public:
rlReport();
virtual ~rlReport();
/*! <pre>
open the output file for writeing
</pre> */
int open(const char *filename);
/*! <pre>
close the output file
</pre> */
int close();
/*! <pre>
print text to the output file
</pre> */
int printf(const char *format, ...);
/*! <pre>
print "\\begin{document}" to the output file
</pre> */
int beginDocument();
/*! <pre>
print "\\end{document}" to the output file
</pre> */
int endDocument();
/*! <pre>
Include a file to the output.
If ini != NULL then the content of ini can be used as text modules as follows:
Withnin file we use something like \\$[SECTION][NAME] to address the text module we want to include.
</pre> */
int include(const char *filename, rlIniFile *ini=NULL);
/*! <pre>
Include the LaTeX header to the output file.
If optional_parameter == NULL then output the default parameters.
Examples:
includeHeader("\\usepackage[a4paper]{article}", "\\usepackage[ngerman]{babel}");
includeHeader("\\usepackage[a4paper]{book}", "\\usepackage[english,greek]{babel}");
See:
http://en.wikibooks.org/wiki/LaTeX/Internationalization
Our default LaTeX header is within the fprintf() statements of rlReport::includeHeader()
You may printf() or include() more header definitions and then call
r.beginDocument();
</pre> */
int includeHeader(const char *documentclass = "\\documentclass[a4paper]{article}",
const char *language = "\\usepackage[english]{babel}",
const char *inputenc = "\\usepackage[utf8]{inputenc}",
const char *layout = "\\setlength{\\parindent}{0pt} \\setlength{\\topmargin}{-50pt} \\setlength{\\oddsidemargin}{0pt} \\setlength{\\textwidth}{480pt} \\setlength{\\textheight}{700pt}");
/*! <pre>
print a CSV table to the output file
filename := name.csv
use_first_row_as_title := 0 | 1
legend := NULL | text_describing_the_table
</pre> */
int includeCSV(const char *filename, int use_first_row_as_title=1, const char *legend=NULL, char delimitor='\t');
/*! <pre>
Include a graphic into our document.
filename := name.jpg | name.png
legend := NULL | text_describeing_the_image
</pre> */
int includeImage(const char *filename, const char *legend=NULL, float scale=1.0f);
/*! <pre>
Run the external "command" and include what is printed by "command" to the output file.
This works as follows:
sprintf(cmd,"%s > %s.temp", command, file.text())
system(cmd);
include(file.text() + ".temp");
</pre> */
int spawn(const char *command);
/*! <pre>
Run "pdflatex -interaction=nonstopmode file.tex" if command==NULL or
what you specify by your own command.
</pre> */
int pdflatex(const char *command = NULL);
private:
FILE *fout; // output file pointer
rlString file; // name of the output file
};
#endif

View File

@@ -0,0 +1,135 @@
/***************************************************************************
rlserial.cpp - description
-------------------
begin : Sat Dec 21 2002
copyright : (C) 2002 by R. Lehrig
email : lehrig@t-online.de
RMOS implementation:
Copyright : (C) 2004 Zertrox GbR
Written by : Alexander Feller
Email : feller@zertrox.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/*! <pre>
With this class you can communicate over a serial line.
</pre> */
#ifndef _RL_SERIAL_H_
#define _RL_SERIAL_H_
#include "rlthread.h"
#ifdef RLUNIX
#include <termios.h>
#endif
#ifndef B0
// speed will be defined by termios.h, this is just for documentation
#define B0 0000000 /* hang up */
#define B50 0000001
#define B75 0000002
#define B110 0000003
#define B134 0000004
#define B150 0000005
#define B200 0000006
#define B300 0000007
#define B600 0000010
#define B1200 0000011
#define B1800 0000012
#define B2400 0000013
#define B4800 0000014
#define B9600 0000015
#define B19200 0000016
#define B38400 0000017
#define B57600 0010001
#define B115200 0010002
#define B230400 0010003
#define B460800 0010004
#define B500000 0010005
#define B576000 0010006
#define B921600 0010007
#define B1000000 0010010
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017
#endif
/*! <pre>
With this class you can communicate over a serial line.
</pre> */
class rlSerial
{
public:
enum Parity
{
NONE = 0,
ODD ,
EVEN
};
rlSerial();
virtual ~rlSerial();
/**
<pre>
On OpenVMS please set the tt parameters at DCL level E.g.:
$ set term /perm/pasthru -
/eightbit -
/nottsync -
/nohostsync -
/noreadsync -
/type -
/noline -
/altype -
/parity=even -
/speed=9600 tta1:
devicename := /dev/ttyX (unix) | COMx (Windows) | ttaX: (OpenVMS)
speed := B50 ... B4000000
block := 0 | 1 (bool)
rtscts := 0 | 1 (bool)
bits := 7 | 8 (unix) | 4-8 (Windows)
stopbits := 1 | 2
parity := rlSerial::NONE | rlSerial::ODD | rlSerial::EVEN
return == 0 success, return < 0 error
</pre>
*/
int openDevice(const char *devicename, int speed=B9600, int block=1, int rtscts=1, int bits=8, int stopbits=1, int parity=rlSerial::NONE);
int select(int timeout=500);
int readChar();
int writeChar(unsigned char uchar);
int readBlock(unsigned char *buf, int len, int timeout=-1);
int writeBlock(const unsigned char *buf, int len);
int readLine(unsigned char *buf, int maxlen, int timeout=1000);
int closeDevice();
//! on := 0 | 1 (bool)
void setTrace(int on);
private:
#ifdef RLUNIX
struct termios save_termios;
#endif
#ifdef __VMS
unsigned short int vms_channel;
#endif
#ifdef RLWIN32
HANDLE hdl;
#endif
#ifdef RM3
int device, uint, com, baudrate;
#endif
enum { RESET, RAW, CBREAK } ttystate;
int ttysavefd;
int fd,trace;
};
#endif

View File

@@ -0,0 +1,77 @@
/***************************************************************************
rlsharedmemory.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SHARED_MEMORY_H_
#define _RL_SHARED_MEMORY_H_
#include "rldefine.h"
#include "rlwthread.h"
/*! <pre>
class for a shared memory.
A shared memory is a piece of RAM that is shared between processes.
If many processes have access to the same RAM, it is necessary to lock the shared memory.
The read/write methods will do this and copy the data to local data.
If you want direct access, you may use getUserAdr().
</pre> */
class rlSharedMemory
{
public:
enum SharedMemoryEnum
{
OK = 0,
ERROR_FILE,
ERROR_SHMGET,
ERROR_SHMAT,
ERROR_SHMCTL
};
/*! rwmode := access rights under unix. default 0600 user=read,write */
rlSharedMemory(const char *name, unsigned long size, int rwmode=0600);
virtual ~rlSharedMemory();
int deleteSharedMemory();
int write(unsigned long offset, const void *buf, int len);
int read (unsigned long offset, void *buf, int len);
int readInt(unsigned long offset, int index);
int readShort(unsigned long offset, int index);
int readByte(unsigned long offset, int index);
float readFloat(unsigned long offset, int index);
int writeInt(unsigned long offset, int index, int val);
int writeShort(unsigned long offset, int index, int val);
int writeByte(unsigned long offset, int index, unsigned char val);
int writeFloat(unsigned long offset, int index, float val);
void *getUserAdr();
int shmKey();
int shmId();
unsigned long size();
int status;
char *name;
private:
int id;
int shmkey;
char *base_adr;
char *user_adr;
unsigned long _size;
pthread_mutex_t *mutex;
#ifdef RLWIN32
HANDLE hSharedFile;
OVERLAPPED overlapped;
#elif defined(RLUNIX)
int fdlock;
#endif
};
#endif

View File

@@ -0,0 +1,255 @@
/***************************************************************************
rlsiemenstcp.h - description
-------------------
begin : Mon Mar 08 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
S7_200 update : Wed Mar 21 2007
copyright : (C) 2007 by Aljosa Merljak
Email : aljosa.merljak@datapan.si
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SIEMENS_TCP_H_
#define _RL_SIEMENS_TCP_H_
#include "rldefine.h"
#include "rlsocket.h"
/*! <pre>
class for communication with Siemens PLC's via TCP
(1) There is the old Fetch/Write protocol from the old S5 PLC (fetch_write=1).
(2) And there is the current Siemens PLC protocol introduced with the S7 series of PLC (fetch_write=0).
According to
http://www.ietf.org/rfc/rfc0905.txt
the client will send a connection request to the PLC after it has establisched a TCP connection().
Here is a example connect_block for a Siemens S7 PLC (CBxx in hex):
CB00= 3, ISO_HEADER_VERSION
CB01= 0, ISO_HEADER_RESERVED
CB02= 0, ISO_HEADER_LENGHT_HIGH
CB03=16, ISO_HEADER_LENGHT_LOW = 22 Byte (hex 16)
CB04=11, Length Indicator Field = 17 dec = 22 byte_total_length - 1 byte_length_indicator - 4 byte_ISO_HEADER
CB05=E0, Connection Request Code (Bits 8-5) 1110=E, Initial Credit Allocation (Bits 4-1) Class 0
CB06= 0, DESTINATION-REF-HIGH
CB07= 0, DESTINATION-REF-LOW
CB08= 0, SOURCE-REF-HIGH
CB09= 1, SOURCE-REF-LOW
CB10= 0, Class and Option
CB11=C1, Identifier: Calling TSAP will follow
CB12= 2, Parameter Length, 2 byte will follow
CB13= 1, Remote TSAP, free to choose on client side (1=PG,2=OP,3=Step7Basic) suggested
CB14= 0, Remote TSAP, free to choose on client side (upper_3_bit_is_rack / lower_5_bit_is_slot) suggested
CB15=C2, Identifier: Called TSAP will follow
CB16= 2, Parameter Length, 2 byte will follow
CB17= 1, Local TSAP, set within Step7 = 1 (1=PG,2=OP,3=Step7Basic)
CB18= 0, Local TSAP, set within Step7 = 0...connectionN (upper_3_bit_is_rack / lower_5_bit_is_slot)
CB19=C0, Identifier: Maximum TPDU size will follow
CB20= 1, Parameter Length, 1 byte will follow
CB21= 9, max 512 octets
For the different PLC types the connect_block looks as follows:
s7_200 = {3,0,0,16,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2,'M','W',0xC2,2,'M','W',0xC0,1,9}
s7_300 = {3,0,0,16,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2, 1,0 ,0xC2,2, 1,2 ,0xC0,1,9} on S7_300 slot of cpu is always 2
s7_400 = {3,0,0,16,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2, 1,0 ,0xC2,2, 1,3 ,0xC0,1,9} on S7_400 slot of cpu is always 3
s7_1200 = {3,0,0,16,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2, 1,0 ,0xC2,2, 1,0 ,0xC0,1,9} slot may be 0 || 1 and TSAP 03.01 || 10.00
s7_logo = {3,0,0,22,0x11,0xE0,0x00,0x00,0x00,0x01,0x00,0xC1,2, 2,0 ,0xC2,2, 2,0 ,0xC0,1,9}
For S7_200 and S7_1200 read: (only symbolic access to DB1)
http://support.automation.siemens.com/WW/llisapi.dll?func=cslib.csinfo&lang=en&objid=21601611&caller=view
According to the Remote TSAP Siemens makes the following statement:
######################################################################################
Remote TSAP (Remote Transport Service Access Point, entfernter Dienstzugangspunkt)
The representation is the same as with the Local TSAP,
but the second byte has another meaning:
- first Byte: contains a device id (allowed 02 or 03)
02 OS (Operating Station Bedienen und Beobachten)
03 other
suggested: 02
- second Byte: contains the adressing within the SIMATIC S7-CPU,
divided in:
Bit 7 ... 5 Rack (Subsystem) of the S7-CPU
Bit 4 ... 0 Slot of the S7-CPU
Hint: It is suggested to choose the same settings for Byte 1 in Remote and Local TSAP
######################################################################################
When you use our rlSiemensTCP class you can do it as follows:
unsigned char cb[22];
rlSiemensTCP *plc = new rlSiemensTCP(adr);
plc->getDefaultConnectBlock(cb);
cb[13] = 1; // set 1 Byte of Remote TSAP
cb[14] = 0; // set 2 Byte of Remote TSAP
cb[17] = 1; // set Local TSAP of the PLC to the
cb[18] = 0; // configuration done within Step 7
plc->setConnectBlock(cb);
Now you can read/write the PLC.
The following matrix shows some combinations:
--------------------------------------------
| CB13 CB14 CB17 CB18
--------------------------------------------
S7_200 | 'M' 'W' 'M' 'W'
--------------------------------------------
S7_300 | 1 0 1 2
--------------------------------------------
S7_400 | 1 0 1 3
--------------------------------------------
S7_1200 | 1 0 1 0
--------------------------------------------
S7_logo 0BA7 | 2 0 2 0
--------------------------------------------
CB17 = (1=PG,2=OP,3=Step7Basic)
CB18 = (upper_3_bit_is_rack / lower_5_bit_is_slot)
Thus the above would be:
A TSAP within Step 7 of 10.00 results in: cb[17] = PG; cb[18] = 0; // rack=0 slot=0
A TSAP within Step 7 of 10.01 results in: cb[17] = PG; cb[18] = 1; // rack=0 slot=1
A TSAP within Step 7 of 10.02 results in: cb[17] = PG; cb[18] = 2; // rack=0 slot=2
A TSAP within Step 7 of 10.03 results in: cb[17] = PG; cb[18] = 3; // rack=0 slot=3
You may use rlSiemensTCP with the individual plc_type for conveniance.
But you can set the whole connect_block and use ANY_SIEMENS_COMPATIBLE_PLC.
Please use Wireshark or tcpdump if the settings of the above matrix do not work for you.
Send us your results.
PS: Still wondering about 'M' 'W' on S7-200
</pre> */
class rlSiemensTCP : public rlSocket
{
public:
enum ORG
{
ORG_DB = 1,
ORG_M = 2,
ORG_E = 3,
ORG_A = 4,
ORG_PEPA = 5,
ORG_Z = 6,
ORG_T = 7
};
enum PLC_TYPE
{
ANY_SIEMENS_COMPATIBLE_PLC = 1000,
S7_200 = 1,
S7_300 = 2,
S7_400 = 3,
S5 = 4,
RACK_SLOT = 5,
S7_1200 = 6, // patch from user slammera from our forum (8 Nov 2012)
LOGO = 7 // LOGO! 0BA7, according to jjmg_engenharia from our forum (3 Sep 2013)
};
enum SiemensFunctionCodes
{
WriteBit = 1,
WriteByte = 2
};
rlSiemensTCP(const char *adr, int _plc_type=rlSiemensTCP::ANY_SIEMENS_COMPATIBLE_PLC, int _fetch_write = 1, int function = -1, int rack_slot = -1);
virtual ~rlSiemensTCP();
/*! <pre>
</pre> */
int getDefaultConnectBlock(unsigned char *connect_block);
int setConnectBlock(const unsigned char *connect_block);
int getConnectBlock(unsigned char *connect_block);
int write(int org, int dbnr, int start_adr, int length, const unsigned char *buf, int function=WriteByte);
int fetch(int org, int dbnr, int start_adr, int length, unsigned char *buf);
private:
void doConnect();
int read_iso(unsigned char *buf);
int write_iso(unsigned char *buf, int len);
int getOrg(int org);
int write_bit(int& i, int org, int dbnr, int start_adr, int len, const unsigned char *buf);
int write_byte(int& i, int org, int dbnr, int start_adr, int length, const unsigned char *buf);
typedef struct
{
unsigned char version;
unsigned char reserved;
unsigned char length_high;
unsigned char length_low;
}IH; // iso header
typedef struct
{
unsigned char ident[2];
unsigned char header_len;
unsigned char ident_op_code;
unsigned char op_code_len;
unsigned char op_code;
unsigned char ident_org_block;
unsigned char len_org_block;
unsigned char org_block;
unsigned char dbnr;
unsigned char start_adr[2];
unsigned char len[2];
unsigned char spare1;
unsigned char spare1_len;
}WH; // write header
typedef struct
{
unsigned char ident[2];
unsigned char header_len;
unsigned char ident_op_code;
unsigned char op_code_len;
unsigned char op_code;
unsigned char ack_block;
unsigned char ack_block_len;
unsigned char error_block;
unsigned char spare1;
unsigned char spare1_len;
unsigned char spare2[5];
}WA; // write ack
typedef struct
{
unsigned char ident[2];
unsigned char header_len;
unsigned char ident_op_code;
unsigned char op_code_len;
unsigned char op_code;
unsigned char ident_org_block;
unsigned char len_org_block;
unsigned char org_block;
unsigned char dbnr;
unsigned char start_adr[2];
unsigned char len[2];
unsigned char spare1;
unsigned char spare1_len;
}FH; // fetch header
typedef struct
{
unsigned char ident[2];
unsigned char header_len;
unsigned char ident_op_code;
unsigned char op_code_len;
unsigned char op_code;
unsigned char ack_block;
unsigned char ack_block_len;
unsigned char error_block;
unsigned char spare1;
unsigned char spare1_len;
unsigned char spare2[5];
}FA; // fetch ack
WH wh;
WA wa;
FH fh;
FA fa;
IH ih;
int function, rack_slot;
int plc_type;
int fetch_write;
unsigned char pdu[2048];
int use_cb;
unsigned char cb[22];
};
#endif

View File

@@ -0,0 +1,67 @@
/***************************************************************************
rlsiemenstcpclient.h - description
-------------------
begin : Mon Mar 08 2004
copyright : (C) 2004 by R. Lehrig
email : lehrig@t-online.de
S7_200 update : Wed Mar 21 2007
copyright : (C) 2007 by Aljosa Merljak
Email : aljosa.merljak@datapan.si
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SIEMENS_TCP_CLIENT_H_
#define _RL_SIEMENS_TCP_CLIENT_H_
#include "rldefine.h"
#include "rlsiemenstcp.h"
#include "rlmailbox.h"
#include "rlsharedmemory.h"
/*! <pre>
This class is for data acquisition within pvserver according to the pvbrowser principle.
The corresponding daemon is generated by pvdevelop.
It communicates by the means of a shared memory and a mailbox.
</pre> */
class rlSiemensTCPClient : public rlMailbox, rlSharedMemory
{
public:
enum ORG
{
ORG_DB = 1,
ORG_M = 2,
ORG_E = 3,
ORG_A = 4,
ORG_PEPA = 5,
ORG_Z = 6,
ORG_T = 7
};
rlSiemensTCPClient(const char *mbxname, const char *shmname, int shmsize, int have_to_swap=1);
virtual ~rlSiemensTCPClient();
int write(int slave, int org, int dbnum, int start, int len, const unsigned char *buf, int function);
int writeBit(int slave, int org, int dbnum, int start, int offset, int len, const unsigned char *buf);
int writeByte(int slave, int org, int dbnum, int start, int len, const unsigned char *val);
int writeFloat(int slave, int org, int dbnum, int start, int len, const float *val);
int writeDword(int slave, int org, int dbnum, int start, int len, const int *val);
int writeShort(int slave, int org, int dbnum, int start, int len, const short *val);
int writeUDword(int slave, int org, int dbnum, int start, int len, const unsigned int *val);
int writeUShort(int slave, int org, int dbnum, int start, int len, const unsigned short *val);
int read(int offset, int len);
float Float(int index);
int Dword(int index);
int Short(int index);
unsigned int UDword(int index);
unsigned int UShort(int index);
unsigned char buf[2048]; // after calling read, the data is here
private:
int have_to_swap;
};
#endif

View File

@@ -0,0 +1,270 @@
/***************************************************************************
rlsocket.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SOCKET_H_
#define _RL_SOCKET_H_
#include "rldefine.h"
#include "rlstring.h"
#ifdef RLWIN32
#include <winsock2.h>
#include <windows.h>
#include <io.h>
#include <direct.h>
#else
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "unistd.h"
#endif
/*! <pre>
you have to call this function before you use any sockets
(at least under windows)
</pre> */
#define wsa rlwsa
int rlwsa();
int rlScoketWrite(int *socket, const void *buf, int len);
/*! <pre>
class for encapsulating TCP/IP socket calls
</pre> */
class rlSocket
{
public:
enum SocketEnum
{
SOCKET_ERR = -1,
SETSOCKOPT_ERR = -2,
LISTEN_ERR = -3,
ACCEPT_ERR = -4,
INET_ADDR_ERR = -5,
CONNECT_ERR = -6,
PORT_ERR = -7
};
/*! <pre>
construct a new rlSocket but do not connect
adr = hostname | dotted address
port = port number of socket
active = 0 wait for connections with accept()
active = 1 open the connection with connect()
active = 2 neither accept() nor connect()
</pre> */
rlSocket(const char *adr, int port, int active);
/*! <pre>
construct a new rlSocket
use connection on open socket
</pre> */
rlSocket(int socket);
/*! <pre>
destruct the socket
attention if active = 0 the socket will still be bound to port
</pre> */
virtual ~rlSocket();
/*! <pre>
set adr to a different adr than in the constructor
</pre> */
void setAdr(const char *adr);
/*! <pre>
set port to a different port than in the constructor
</pre> */
void setPort(int port);
/*! <pre>
get port
</pre> */
int getPort();
/*! <pre>
set port active = 0|1
</pre> */
void setActive(int active);
/*! <pre>
read a block of data
len = length of data to be read
timeout = 0 wait indefinite
timeout > 0 wait at maximum for timeout milliseconds
return > 0 length of message read
return == 0 timeout
return < 0 error
</pre> */
int read(void *buf, int len, int timeout=0);
/*! <pre>
read a '\n' terminated string
len = max length of data to be read
timeout = 0 wait indefinite
timeout > 0 wait at maximum for timeout milliseconds
return > 0 length of message read
return == 0 timeout
return < 0 error
</pre> */
int readStr(char *buf, int len, int timeout=0);
/*! <pre>
read a http header and return Content-Length
return < 0 error
</pre> */
int readHttpHeader(rlString *header, int timeout=0);
/*! <pre>
write a block of data
return > 0 length of data written
return < 0 error
</pre> */
int write(const void *buf, int len);
/*! <pre>
similar to printf
return > 0 length of data written
return < 0 error
</pre> */
int printf(const char *format, ...);
/*! <pre>
connect
return >= 0 socket used
return < 0 error (see: enum SocketEnum)
</pre> */
int connect();
/*! <pre>
disconnect
return = 0
</pre> */
int disconnect();
/*! <pre>
wait for data arriving on socket
timeout > 0 timeout in milliseconds
timeout == 0 indefinite timeout
return = 1 DATA_AVAILABLE
return = 0 TIMEOUT
</pre> */
int select(int timeout=0);
/*! <pre>
return == 1 socket is connected
return == 0 socket is not connected
</pre> */
int isConnected();
/*! <pre>
default: prefer IPV4
if(ip==6) prefer IPV6
else prefer IPV4
</pre> */
int setIPVersion(int version);
/*! <pre>
return == 4 IPV4
return == 6 IPV6
</pre> */
int getIPVersion();
/*! <pre>
This method is intendet for data providers implemented as ProcessViewServer
</pre> */
int sendProcessViewBrowserButtonEvent(int id);
/*! <pre>
this is the real socket used for communication
s >= 0 connected
s == -1 disconnected
</pre> */
int s;
/*! <pre>
portable version of getsockopt
</pre> */
static int rlGetsockopt(int sockfd, int level, int optname, void *optval, int *optlen);
/*! <pre>
portable version of setsockopt
</pre> */
static int rlSetsockopt(int sockfd, int level, int optname, const void *optval, int optlen);
/*! <pre>
get an option from this->s
</pre> */
int rlGetsockopt(int level, int optname);
/*! <pre>
set an option on this->s
</pre> */
int rlSetsockopt(int level, int optname);
/*! <pre>
read the response to a http get request until Content-Length is received
Tip: char line[256];
</pre> */
int readHttpContentLength(int timeout);
/*! <pre>
this array can be casted to (struct sockaddr *) &sockaddr[0];
in case of active==0 it will store sockaddr of the last client
(48 bytes spare)
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
// IPv4 AF_INET sockets:
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
struct in_addr {
unsigned long s_addr; // load with inet_pton()
};
// IPv6 AF_INET6 sockets:
struct sockaddr_in6 {
u_int16_t sin6_family; // address family, AF_INET6
u_int16_t sin6_port; // port number, Network Byte Order
u_int32_t sin6_flowinfo; // IPv6 flow information
struct in6_addr sin6_addr; // IPv6 address
u_int32_t sin6_scope_id; // Scope ID
};
struct in6_addr {
unsigned char s6_addr[16]; // load with inet_pton()
};
</pre> */
unsigned char sockaddr[16+48];
private:
char adr[132];
int port;
int active;
int os;
int first;
int prefer_ipv6;
int rl_ipversion;
};
#endif

View File

@@ -0,0 +1,169 @@
/***************************************************************************
rlspawn.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SPAWN_H_
#define _RL_SPAWN_H_
#include "rldefine.h"
#ifndef RLUNIX
//#warning This Functionality is only available under Linux/Unix
/*
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365574%28v=vs.85%29.aspx
http://www.tenouk.com/cpluscodesnippet/pipeandchildprocess.html
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365780%28v=vs.85%29.aspx
GetFileNameFromHandle
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366789%28v=vs.85%29.aspx
*/
#endif
/*! <pre>
Spawn an external program.
Redirect \<stdin> \<stdout> \<stderr> of external program to this class
Now you can communicate with this external program over a pipe.
Attention: This class is only available on unix like systems.
</pre> */
class rlSpawn
{
public:
rlSpawn();
virtual ~rlSpawn();
/*! <pre>
Start an operating system command.
The output from the command can be read with readLine()
You can write to the program with writeString() or write()
Return: 0=success -1=error
</pre> */
int spawn(const char *command);
/*! <pre>
Read a line from the spawned command.
When the command terminates NULL is returned.
</pre> */
const char *readLine();
/*! <pre>
Read a char from the spawned command.
When the command terminates EOF is returned.
</pre> */
int getchar();
/*! <pre>
Wait for characters.
return = 0 // timeout
return = 1 // characters available
</pre> */
int select(int timeout=50);
/*! <pre>
Write buf to \<stdin> of spawned command
buf must be 0 terminated
Return: number of bytes written
-1 error
</pre> */
int writeString(const char *buf);
/*! <pre>
Write buf to \<stdin> of spawned command
Return: number of bytes written
-1 error
</pre> */
int write(const char *buf, int len);
/*! <pre>
similar to printf
Return: number of bytes written
-1 error
</pre> */
int printf(const char *format, ...);
/*! <pre>
Print all outputs from spawned command to \<stdout>
</pre> */
void printAll();
/*! <pre>
Get FILE pointer fromChild
</pre> */
FILE *getFilepointer();
/*! <pre>
Kill process on other side of pipe
</pre> */
int sigkill();
/*! <pre>
Read JPEG buffer fromChild
return: length of buffer | -1 as error
Example: A thread continiously reads the mjpeg output of ffmpeg and stores it in jpegBuffer
rlThread mythread;
unsigned char jpegBuffer[256*256*16];
void *myThread(void *arg) // define your thread function
{
rlSpawn spawn;
restart:
if(arg == NULL) return NULL;
THREAD_PARAM *p = (THREAD_PARAM *) arg;
//myThreadsData *d = (myThreadsData *) p->user;
spawn.spawn("ffmpeg -f video4linux2 -i /dev/v4l/by-id/usb-046d_0825_A867B3D0-video-index0 -vf \"transpose, hflip\" -r 10 -f mjpeg pipe:1");
while(p->running)
{
int ret = spawn.readJpegBuffer(jpegBuffer,sizeof(jpegBuffer));
printf("ret=%d\n",ret);
if(ret < 0) goto restart;
}
return arg;
}
Example: The jpegBuffer can now be Send to a Image Widget on the pvbrowser client
extern rlThread mythread;
extern unsigned char jpegBuffer[];
static int slotNullEvent(PARAM *p, DATA *d)
{
if(p == NULL || d == NULL) return -1;
pvSendJpegFrame(p,imgWebcam,jpegBuffer);
return 0;
}
</pre> */
int readJpegBuffer(unsigned char *buffer, int maxbuffer);
int pid;
private:
#ifdef RLWIN32
HANDLE toChildRD;
HANDLE toChildWR;
HANDLE fromChildRD;
HANDLE fromChildWR;
HANDLE hThread;
HANDLE hProcess;
#else
void *toChild,*fromChild;
#endif
char line[4096]; // adjust this if the buffer is not big enough
};
#endif

View File

@@ -0,0 +1,116 @@
/***************************************************************************
rlspreadsheet.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SPREADSHEET_H_
#define _RL_SPREADSHEET_H_
#include "rldefine.h"
/*! <pre>
A cell of a spreadsheet.
</pre> */
class rlSpreadsheetCell
{
public:
rlSpreadsheetCell(const char *text=0);
virtual ~rlSpreadsheetCell();
const char *text();
void setText(const char *text);
int printf(const char *format, ...);
void clear();
void setNextCell(rlSpreadsheetCell *next);
rlSpreadsheetCell *getNextCell();
int exists();
private:
char *txt;
rlSpreadsheetCell *nextCell;
};
/*! <pre>
A row within a spreadsheet.
</pre> */
class rlSpreadsheetRow
{
public:
//! column = 1...N
rlSpreadsheetRow();
virtual ~rlSpreadsheetRow();
const char *text(int column);
void setText(int column, const char *text);
int printf(int column, const char *format, ...);
void clear();
void setNextRow(rlSpreadsheetRow *next);
rlSpreadsheetRow *getNextRow();
rlSpreadsheetCell *getFirstCell();
void readRow(const unsigned char *line, char delimitor='\t');
void writeRow(void *fp, char delimitor='\t');
int exists(int column);
private:
rlSpreadsheetCell *firstCell;
rlSpreadsheetRow *nextRow;
};
/*! <pre>
A spreadsheet Table.
The class works with CSV files.
</pre> */
class rlSpreadsheetTable
{
public:
//! column = 1...N, row = 1...N
rlSpreadsheetTable(char delimitor='\t');
virtual ~rlSpreadsheetTable();
const char *text(int column, int row);
void setText(int column, int row, const char *text);
int printf(int column, int row, const char *format, ...);
void clear();
int read(const char *filename);
int write(const char *filename);
void setNextTable(rlSpreadsheetTable *next);
rlSpreadsheetTable *getNextTable();
rlSpreadsheetRow *getFirstRow();
int exists(int column, int row);
void setDelimitor(char delimitor);
private:
char delimitor;
rlSpreadsheetRow *firstRow;
rlSpreadsheetTable *nextTable;
};
/*! <pre>
A series of spreadsheet tables.
The class works with CSV files.
</pre> */
class rlSpreadsheetWorkbook
{
public:
//! column = 1...N, row = 1...N, page = 1...N
rlSpreadsheetWorkbook(char delimitor='\t');
virtual ~rlSpreadsheetWorkbook();
const char *text(int column, int row, int page);
void setText(int column, int row, int page, const char *text);
int printf(int column, int row, int page, const char *format, ...);
void clear();
int read(const char *filename);
int write(const char *filename);
int exists(int column, int row, int page);
rlSpreadsheetTable *getFirstTable();
void setDelimitor(char delimitor);
private:
char delimitor;
rlSpreadsheetTable *firstTable;
};
#endif

View File

@@ -0,0 +1,274 @@
/***************************************************************************
rlstate.h - description
-------------------
begin : Sat Dec 29 2012
copyright : (C) 2012 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_STATE_H
#define _RL_STATE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "rlthread.h"
/*! <pre>
This class is used to implement a statemachine.
Under pvbaddon/templates/statemachine/plc you find the statemachine consisting of several threads.
The main thread will read/write a Modbus PLC.
The statemachine stm2 will handle a small demo statemachine.
The statemachine stm1 will start stm2 if the user selects this function.
The data will be stored in a shared memory.
The shared memory contains a complex datastructure (typedef struct {...} USER_DEFINED_STRUCTURE;) which can be used to exchange values between several processes.
The pvbrowser visualization server is located under pvbaddon/templates/statemachine/pvs
There we use a SVG graphic (stm2.svg) showing the statemachine.
This graphic is generated by graphviz from stm2.dot
pvs and plc exchange data only via shared memory.
Please start both (plc and pvs) in a separate terminal and then start the pvbrowser client
Here is some sourcecode from the template:
// ***************************************************************************
// main.cpp - description
// -------------------
// begin : Sa. Mai 4 09:29:07 2013
// generated by : pvdevelop (C) Lehrig Software Engineering
// email : lehrig@t-online.de
// ***************************************************************************
#include "plcapp.h"
SHM_DATA *shm_data;
rlSharedMemory shm("/srv/automation/shm/plc.shm", sizeof(SHM_DATA));
rlSerial tty;
rlModbus mb;
rlMutex mb_mutex;
rlState sm1, sm2;
//// helper functions
int printBinByte(unsigned char val)
{
if(val & BIT7) printf("1");
else printf("0");
if(val & BIT6) printf("1");
else printf("0");
if(val & BIT5) printf("1");
else printf("0");
if(val & BIT4) printf("1");
else printf("0");
printf(":");
if(val & BIT3) printf("1");
else printf("0");
if(val & BIT2) printf("1");
else printf("0");
if(val & BIT1) printf("1");
else printf("0");
if(val & BIT0) printf("1");
else printf("0");
return 0;
}
int printBin(unsigned char *data)
{
printf("BinData: ");
printBinByte(data[0]);
printf(" - ");
printBinByte(data[1]);
return 0;
}
//// Schneider PLC: first 4 bits are outputs then 6 bits input follow
static int readIO()
{
unsigned char data[256];
int ret;
MB_readInputStatus(1,0,10,data); // read all IO values from modbus
shm_data->plc.in.in1 = mb.data2int(data); // store data in shared memory
if(trace)
{
printf("readIO:: ret=%d ", ret);
printBin(data);
printf(" in1=%x\n", shm_data->plc.in.in1);
}
return 0;
}
static int writeIO()
{
unsigned char coils[8];
int ret;
coils[0] = shm_data->plc.out.out1 & 0x0ff;
MB_forceMultipleCoils(1,0,4,coils); // write the 4 output bits to modbus
return 0;
}
int main()
{
if(trace) printf("plc starting ...\n");
if(trace) printf("shm.status=%d\n", shm.status);
if(shm.status != rlSharedMemory::OK)
{
printf("ERROR: shared memory status is not ok\n");
return -1;
}
shm_data = (SHM_DATA *) shm.getUserAdr();
memset(shm_data,0,sizeof(SHM_DATA));
if(tty.openDevice("/dev/ttyUSB0",B9600,1,1,8,1,rlSerial::NONE) < 0)
{
printf("ERROR: openDevice(\"/dev/tty/USB0\")\n");
}
mb.registerSerial(&tty);
startStepsStm1(&sm1, 100); // start statemachine 1
startStepsStm2(&sm2, 100); // start statemachine 2
printf("going to IO loop\n");
while(1)
{
readIO();
writeIO();
rlsleep(10);
}
return 0;
}
// *****************************************************************************
// stm2.cpp - description
// -------------------
// begin : Sa. Mai 4 09:29:07 2013
// generated by : pvdevelop (C) Lehrig Software Engineering
// email : lehrig@t-online.de
// A simple template for implementing your own statemachine
// See: pvbaddon/templates/statemachine
// *****************************************************************************
#include "plcapp.h"
////TODO: define our states
//// Your states are defined by static functions which get a pointer to the statemachine
//// The pointer sm->user might be used to transfer the address of a user defined datastructure
//// A transition from one state to the next is done by sm->gotoState(theNextState);
//// Your statemachine runs within a separate thread and the current state is called within "cycletime" intervals
static void stStart(rlState *sm);
static void stProcess(rlState *sm);
static void stFinish(rlState *sm);
////TODO: implement our states
static void stStart(rlState *sm)
{
shm_data->plc.out.out1 = 1; // set output 1 in shared memory
if(sm->stepCounter > 20)
{
shm_data->plc.out.out1 = 2; // reset output 1 in shared memory
strcpy(shm_data->plc.state.stm2_name,"Process"); // set next state name in shared memory
sm->gotoState(stProcess); // goto the next state
}
}
static void stProcess(rlState *sm)
{
shm_data->plc.out.out1 = sm->stepCounter; // set output 1 in shared memory
if(sm->stepCounter > 30)
{
strcpy(shm_data->plc.state.stm2_name,"Finish"); // set next state name in shared memory
sm->gotoState(stFinish); // goto the next state
}
}
static void stFinish(rlState *sm)
{
shm_data->plc.out.out1 = 1; // set output 1 in shared memory
if(sm->stepCounter > 30)
{
shm_data->plc.out.out1 = 0; // reset output 1 in shared memory
strcpy(shm_data->plc.state.stm2_name,"NULL"); // set next state name NULL
shm_data->plc.state.stm2_running = 0; // reset running in shared memory
sm->gotoState(NULL); // goto NULL state
}
}
int startStepsStm2(rlState *sm, int cycletime) // start our statemachine
{
if(trace) printf("stm2 starting\n");
shm_data->plc.state.stm2_running = 1; // set running in shared memory
strcpy(shm_data->plc.state.stm2_name,"Start"); // set next state name in shared memory
sm->gotoState(stStart); // goto nextState
sm->startSteps(cycletime); // start a thread which handles the statemachine
return 0;
}
// ***************************************************************************
// stm1.cpp - description
// -------------------
// begin : Sa. Mai 4 09:29:07 2013
// generated by : pvdevelop (C) Lehrig Software Engineering
// email : lehrig@t-online.de
// ***************************************************************************
#include "plcapp.h"
extern rlState sm2;
////TODO: define our states
static void stStart(rlState *sm);
////TODO: implement our states
static void stStart(rlState *sm)
{
shm_data->plc.out.out2 = sm->stepCounter;
if(shm_data->plc.state.stm2_running == 0)
{
if(shm_data->pvs.state.button_start_stm2 == 1)
{
startStepsStm2(&sm2, 100); // start statemachine 2 thread
}
else if(shm_data->plc.in.in1 & BIT1)
{
startStepsStm2(&sm2, 100); // start statemachine 2 thread
}
}
}
int startStepsStm1(rlState *sm, int cycletime) // start our statemachine
{
if(trace) printf("Start stm1\n");
shm_data->plc.state.stm1_running = 1; // set running within shared memory
sm->gotoState(stStart); // goto nextState
sm->startSteps(cycletime); // start a thread that will handle our statemachine
return 0;
}
</pre>
*/
class rlState
{
public:
rlState();
~rlState();
int startSteps(int cycletime);
int runSteps(int cycletime);
void gotoState(void (*funcPtr)(rlState *sm));
void *user;
int stepCounter;
int cycletime;
static const long MAX_STEP = 1000*1000*1000;
void (*nextStep)(rlState *sm);
void (*lastState)(rlState *sm);
rlThread thread;
};
#endif

View File

@@ -0,0 +1,161 @@
/***************************************************************************
rlstring.h - description
-------------------
begin : Wed Jan 02 2008
copyright : (C) Lehrig Software Enigineering
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_STRING_H_
#define _RL_STRING_H_
#include <string.h>
#include "rldefine.h"
extern const char rlCRLF[];
/*! <pre>
class for a simple ANSI-C like string.
</pre> */
class rlString
{
public:
/*! <pre>
construct the string
</pre> */
rlString(const char *text="");
rlString(rlString &text);
rlString(rlString *text);
rlString(const rlString &text);
/*! <pre>
destruct the string
</pre> */
virtual ~rlString();
rlString& operator=(const char *s2);
rlString& operator=(rlString &s2);
rlString& operator+(const char *s2);
rlString& operator+(rlString &s2);
rlString& operator+=(const char *s2);
rlString& operator+=(rlString &s2);
int operator==(const char *s2);
int operator==(rlString &s2);
int operator==(const rlString &s2);
int operator!=(const char *s2);
int operator!=(rlString &s2);
/*! <pre>
get the text
</pre> */
char *text();
char *text() const;
/*! <pre>
set the text
</pre> */
int setText(const char *text);
/*! <pre>
printf the text
</pre> */
int printf(const char *format, ...);
/*! <pre>
copy text
</pre> */
int strcpy(const char *text);
/*! <pre>
append text
</pre> */
int cat(const char *text);
/*! <pre>
converst string to upper case
</pre> */
int upper();
/*! <pre>
converst string to upper case
</pre> */
int lower();
/*! <pre>
test if string starts with startstr
</pre> */
int startsWith(const char *startstr);
/*! <pre>
case insensitive string compare
</pre> */
int strnocasecmp(const char *other);
/*! <pre>
case insensitive string compare starting n characters
</pre> */
int strnnocasecmp(const char *other, int n);
/*! <pre>
strstr()
</pre> */
char *strstr(const char *substring);
/*! <pre>
strchr()
</pre> */
char *strchr(int c);
/*! <pre>
strchr()
</pre> */
char *strrchr(int c);
/*! <pre>
Remove quotas around a string.
This might be usefull together with CSV files.
</pre> */
int removeQuotas(char c='"');
/*! <pre>
Remove "\n" at end of string.
</pre> */
int removeNewline();
/*! <pre>
Read string from file.
</pre> */
int read(const char *filename);
/*! <pre>
Write string to file.
</pre> */
int write(const char *filename);
/*! <pre>
convert to platform independent filename
</pre> */
const char *toFilename();
/*! <pre>
convert to platform independent directoryname
</pre> */
const char *toDirname();
private:
char *txt;
char *tmp;
};
#endif

View File

@@ -0,0 +1,28 @@
// include essential header from rlllib
#include "rlcontroller.h"
#include "rlcutil.h"
#include "rldataacquisition.h"
#include "rldataprovider.h"
#include "rlevent.h"
#include "rlfifo.h"
#include "rlfileload.h"
#include "rlhistorylogger.h"
#include "rlhistoryreader.h"
#include "rlinifile.h"
#include "rlinterpreter.h"
#include "rlmailbox.h"
#include "rlmodbusclient.h"
#include "rlpcontrol.h"
#include "rlppiclient.h"
#include "rlserial.h"
#include "rlsharedmemory.h"
#include "rlsiemenstcpclient.h"
#include "rlsocket.h"
#include "rlspawn.h"
#include "rlspreadsheet.h"
#include "rlstring.h"
#include "rlsvganimator.h"
#include "rlthread.h"
#include "rltime.h"
#include "rludpsocket.h"

View File

@@ -0,0 +1,143 @@
/***************************************************************************
rlsvganimator.h - description
-------------------
begin : Tue Apr 10 2006
copyright : (C) 2006 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SVG_ANIMATOR_
#define _RL_SVG_ANIMATOR_
#include "rldefine.h"
#include "rlinifile.h"
#include "rlspreadsheet.h"
#include "rlstring.h"
/*! <pre>
This class holds the position of an SVG object.
Use it together with rlSvgAnimator::setMatrix()
</pre> */
class rlSvgPosition
{
public:
rlSvgPosition();
rlSvgPosition(float sx_init, float a_init, float x0_init, float y0_init, float cx_init, float cy_init);
virtual ~rlSvgPosition();
float sx, alpha, x0, y0, cx, cy;
struct rlPositionInit {float sx, alpha, x0, y0, w, h;} init;
void setInit(float x0_init, float y0_init, float w_init, float h_init);
void move(float x, float y);
void moveRelative(float dx, float dy);
void scale(float s);
void scaleRelative(float ds);
void rotate(float alpha, float cx, float cy);
};
/*! <pre>
This class allows you to animate SVG graphics within pvbrowser.
First the SVG is send to pvbrowser.
Then you may modify the SVG within the pvbrowser client.
</pre> */
class rlSvgAnimator
{
public:
rlSvgAnimator();
virtual ~rlSvgAnimator();
/*! initialize the socket with pvbrowser p->s */
int setSocket(int *socket);
/*! initialize the id with the pvbrowser object id */
int setId(int Id);
/*! read SVG file infile and load it into the pvbrowser client.
if inifile is given inifile will be set with properties within the SVG XML file.
The id's of the SVG objects will result in section names of the inifile. */
int read(const char *infile, rlIniFile *inifile=NULL);
/*! update the SVG graphic with:
gBeginDraw(p,id); d->svgAnimator.writeSocket(); gEndDraw(p); */
//! The following methods are for modifying a object within a SVG graphic identified by objectname
int writeSocket();
/*! change a property of tag = "name=" */
int svgPrintf(const char *objectname, const char *tag, const char *format, ...);
/*! recursively change a property of tag = "name=" */
int svgRecursivePrintf(const char *objectname, const char *tag, const char *format, ...);
/*! search for "before" within "tag=" property and replace it with "after". You may use wildcards whin "before" */
int svgSearchAndReplace(const char *objectname, const char *tag, const char *before, const char *after);
/*! recursively search for "before" within "tag=" property and replace it with "after". You may use wildcards within "before" */
int svgRecursiveSearchAndReplace(const char *objectname, const char *tag, const char *before, const char *after);
/*! change the text of "objectname" */
int svgTextPrintf(const char *objectname, const char *format, ...);
/*! remove a style option of "objectname". option must end with ':'. Example: option="stroke:" */
int svgRemoveStyleOption(const char *objectname, const char *option);
/*! recursively remove a style option of "objectname". option must end with ':'. Example: option="stroke:" */
int svgRecursiveRemoveStyleOption(const char *objectname, const char *option);
/*! change a style option of "objectname". option must end with ':'. Example: option="stroke:" value="#000000" */
int svgChangeStyleOption(const char *objectname, const char *option, const char *value);
/*! recursively change a style option of "objectname". option must end with ':'. Example: option="stroke:" value="#000000" */
int svgRecursiveChangeStyleOption(const char *objectname, const char *option, const char *value);
/*! set a style option of "objectname". option must end with ':'. Example: value="fill:#9d9d9d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" */
int svgSetStyleOption(const char *objectname, const char *value);
/*! recursively set a style option of "objectname". option must end with ':'. Example: value="fill:#9d9d9d;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" */
int svgRecursiveSetStyleOption(const char *objectname, const char *value);
/*! hide/show object state := 0=hide 1=show */
int show(const char *objectname, int state); // state := 0|1
/*! set transformation matrix of object */
int setMatrix(const char *objectname, float sx, float alpha, float x0, float y0, float cx, float cy);
/*! set transformation matrix of object */
//! The following methods are for moveing and zooming the whole SVG identified by mainObject. default: main
int setMatrix(const char *objectname, rlSvgPosition &pos);
/*! set/get the name of the MainObject . The object name holding the whole SVG graphic. default: main */
int setMainObject(const char *main_object);
const char *mainObject();
/*! set/get x0,y0 coordinates for the MainObject */
int setXY0(float x0, float y0);
float x0();
float y0();
/*! set/get mouse position 0 for the MainObject */
int setMouseXY0(float x0, float y0);
float mouseX0();
float mouseY0();
/*! set/get mouse position 1 for the MainObject */
int setMouseXY1(float x1, float y1);
float mouseX1();
float mouseY1();
/*! set/get the scaling factor for the MainObject */
int setScale(float scale);
float scale();
/*! zooms the whole SVG graphic keeping it centered to the viewport */
int zoomCenter(float newScale);
/*! zooms the whole SVG graphic so that the visible section is from x0,x0 to x1,y1 */
int zoomRect();
/*! sets the MainObject matrix according to scale,x0,y0 */
int setMainObjectMatrix();
/*! call this method when the widget is resized */
int setWindowSize(int width, int height);
float windowWidth();
float windowHeight();
/*! move MainObject to position */
int moveMainObject(float x, float y);
int isModified;
private:
int tcpsend(const char *buf, int len);
int fillIniFile(rlIniFile *inifile, const char *line);
int fileFillIniFile(const char *infile, rlIniFile *inifile);
int inifileState, inifileCount;
rlSpreadsheetCell inifileID;
rlSpreadsheetTable inifileTable;
int *s;
int id;
// zoomer variables follow
float svgX0, svgY0, svgWindowWidth, svgWindowHeight, svgScale, svgMouseX0, svgMouseY0, svgMouseX1, svgMouseY1;
rlString main_object_name;
};
#endif

View File

@@ -0,0 +1,44 @@
/***************************************************************************
rlsvgcat.h - description
-------------------
begin : Tue Apr 09 2006
copyright : (C) 2006 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_SVG_CAT_
#define _RL_SVG_CAT_
#include "rldefine.h"
/*! <pre>
This class will normalize SVG XML files so that
- lines are left justified
- 1 tag per line
</pre> */
class rlSvgCat
{
public:
rlSvgCat();
virtual ~rlSvgCat();
int open(const char *infile, const char *outfile = 0);
int reopenSocket(const char *infile, int s);
void cat();
void close();
private:
int outUntil(int i, const char *tag);
int outUntilEnd(int i);
int outValue(int i);
void catline();
void *fin, *fout;
int s;
char line[256*256];
};
#endif

View File

@@ -0,0 +1,146 @@
/***************************************************************************
rlsvgvdi.h - description
-------------------
begin : Tu Mar 22 2016
copyright : (C) 2016 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef _RL_SVGVDI_H_
#define _RL_SVGVDI_H_
#include <stdio.h>
#include "rlstring.h"
#include "rlspawn.h"
#define MAXARRAY 1024*4 // maximum array size for line(x,y,n)
#ifndef PROCESSVIEWSERVER_H
/* font alignment */
enum rlFontAlignment { /* */
ALIGN_LEFT=0, /* example */
ALIGN_CENTER, /* example */
ALIGN_RIGHT, /* example */
ALIGN_VERT_CENTER /* e */
}; /* x */
/* a */
/* m */
/* p */
/* l */
/* e */
/* */
/* linestyle for lines in axis */
enum rlLinestyle {
LINESTYLE_NONE=0,
LINESTYLE_CIRCLE,
LINESTYLE_CROSS,
LINESTYLE_RECT,
LINESTYLE_CIRCLE_NO_LINE,
LINESTYLE_CROSS_NO_LINE,
LINESTYLE_RECT_NO_LINE
};
#endif
/*! <pre>
class for drawing xy-graphics and any svg graphics either on the client or on the server.
SVG (Tiny) is a flexible and powerfull graphics format.
- It can be rendered on a pvbrowser DrawWidget on the client,
where the user will also be able to interact with the SVG (example: clicking on named objects within the SVG)
- It can be rendered into another format by SVG converters on the server and/or the client
- It can be used to implement scalable user interfaces especially when using on mobile devices
rlSvgVdi brings some conveniance functions to draw xy-graphics with SVG and
some general SVG interface functions, that produce SVG content directly.
The Output might be send to File/Socket/stdout or simply collected as a rlString with all the generated SVG.
See example within pvbaddon/demos/rlsvgvdi
HINT 1: Use rlSpawn and the rlsvgcat utility to read static SVG templates and insert the content generated by rlSvgVdi dynamically into the output stream.
You might use comment strings within the SVG for controlling the filter pipeline.
HINT 2: Use this class for the purpose of generating reports in pdf
HINT 3: Use SVG converters with a commandline interface to convert SVG to png, jpg, pdf ...
Examples: rsvg, imagemagick
https://wiki.gnome.org/action/show/Projects/LibRsvg
http://imagemagick.org/script/index.php
</pre> */
class rlSvgVdi
{
public:
rlSvgVdi();
~rlSvgVdi();
int setOutput(int *socket_out, int idForPvbrowser=0);
int setOutput(FILE *fout);
int setOutput(const char *outputfilename);
int setOutput(rlSpawn *pipe);
int endOutput();
const char *svgHeader(int width=1280, int height=1024, int rbackground=255, int gbackground=255, int bbackground=255);
const char *svgTrailer();
const char *drawEllipse(int x, int y, int rx, int ry);
const char *moveTo(int x, int y);
const char *lineTo(int x, int y);
const char *line(int x1, int y1, int x2, int y2);
const char *text(int x, int y, const char *text, int alignment=ALIGN_LEFT);
const char *textInAxis(float x, float y, const char *text, int alignment);
const char *box(int x, int y, int w, int h);
const char *boxWithText(int x, int y, int w, int h, int fontsize, const char *xlabel, const char *ylabel, const char * rylabel);
const char *rect(int x, int y, int w, int h);
const char *xAxis(float start, float delta, float end, int draw=1);
const char *yAxis(float start, float delta, float end, int draw=1);
const char *xGrid();
const char *yGrid();
const char *rightYAxis(float start, float delta, float end, int draw=1);
const char *drawSymbol(int x, int y, int type);
const char *line(float *x, float *y, int n, int linestayle=LINESTYLE_NONE);
const char *setColor(int r, int g, int b);
const char *setFont(const char *family, int size, int weight, int italic);
const char *setWidth(int w);
const char *setLinestyle(const char *dasharray);
const char *comment(const char *text);
const char *svg_put(const char *text);
const char *svg_printf(const char *format, ...);
const char *svg_d(int *x, int *y, int count);
const char *svg_points(int *x, int *y, int count);
int outputState;
int getFontsize();
int getBoxX();
int getBoxY();
int getBoxW();
int getBoxH();
private:
int *sout;
FILE *fout;
rlSpawn *pipe;
rlString filename, outputfilename;
int idForPvbrowser;
rlString svg, svg2, svg3, fontstring;
char stroke[16];
int width;
rlString dasharray;
rlString lineoptions, textoptions;
int perhapsSend(const char *text);
int xold, yold;
float xmin,dx,xmax;
float ymin,dy,ymax;
int tx(float x);
int ty(float y);
int boxx,boxy,boxw,boxh;
int fontsize;
int sr; // symbol radius
char floatFormat[80];
};
#endif

View File

@@ -0,0 +1,167 @@
/***************************************************************************
rlthread.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_THREAD_H_
#define _RL_THREAD_H_
#include "rldefine.h"
#include "rlwthread.h"
class rlThread;
/*! <pre>
This parameter is given to the thread function.
</pre> */
typedef struct
{
rlThread *thread;
void *user;
int running;
}
THREAD_PARAM;
/*! <pre>
Thread functions based on POSIX threads.
</pre> */
class rlThread
{
public:
rlThread(int max_semphore=1000);
virtual ~rlThread();
/*! <pre>
Create a new thread
Your thread function looks like:
void *threadFunction(void *arg)
{
THREAD_PARAM *p = (THREAD_PARAM *) arg;
YOUR_DATA *d = (YOUR_DATA *) p->user;
for(int i=0; i<50; i++)
{
p->thread->lock();
// do something critical
printf("this is the thread\n");
p->thread->unlock();
}
return NULL;
}
</pre> */
int create(void *(*func)(void*), void *argument);
/*! <pre>
Try to lock the mutex.
return 0 if already locked
return !0 if lock sucessfull
</pre> */
int trylock();
/*! <pre>
Lock the mutex.
</pre> */
int lock();
/*! <pre>
Unlock the mutex.
</pre> */
int unlock();
/*! <pre>
Wait until semaphore is signaled
</pre> */
int waitSemaphore();
/*! <pre>
Increment the value of the semaphore
</pre> */
int incrementSemaphore();
/*! <pre>
Wait for termination of thread and get the exit status
</pre> */
int join(void **status);
/*! <pre>
Cancel the thread
</pre> */
int cancel();
/*! <pre>
Terminate the thread and return exit status
</pre> */
void threadExit(void *status);
pthread_t tid;
pthread_attr_t attr;
pthread_mutex_t mutex;
WSEMAPHORE semaphore;
private:
THREAD_PARAM arg;
};
/*! <pre>
Mutex functions based on POSIX threads.
</pre> */
class rlMutex
{
public:
//rlMutex(const pthread_mutexattr_t *attr = NULL);
rlMutex(const void *attr = NULL);
virtual ~rlMutex();
/*! <pre>
Try to lock the mutex.
return 0 if already locked
return !0 if lock sucessfull
</pre> */
int trylock();
/*! <pre>
Lock the mutex.
</pre> */
int lock();
/*! <pre>
Unlock the mutex.
</pre> */
int unlock();
pthread_mutex_t mutex;
};
/*! <pre>
Semaphore functions based on POSIX threads.
</pre> */
class rlSemaphore
{
public:
rlSemaphore(int max_semaphore = 1000);
virtual ~rlSemaphore();
/*! <pre>
Wait until semaphore is signaled
</pre> */
int waitSemaphore();
/*! <pre>
Increment the value of the semaphore
</pre> */
int incrementSemaphore();
WSEMAPHORE semaphore;
};
#endif

View File

@@ -0,0 +1,65 @@
/***************************************************************************
rltime.h - description
-------------------
begin : Tue Jan 02 2001
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_TIME_V1_H_
#define _RL_TIME_V1_H_
#include "rldefine.h"
/*! <pre>
class for handling time.
</pre> */
class rlTime
{
public:
rlTime(int Year=0, int Month=0, int Day=0, int Hour=0, int Minute=0, int Second=0, int Millisecond=0);
virtual ~rlTime();
const char *version();
const char *getTimeString();
const char *getIsoTimeString();
const char *toString(const char *format);
void getLocalTime();
int getFileModificationTime(const char *filename);
/*! <pre>
format: sscanf(time_string,"%d-%d-%d %d:%d:%d %d",&year,&month,&day, &hour,&minute,&second, &millisecond);
</pre> */
void setTimeFromString(const char *time_string);
void setTimeFromIsoString(const char *iso_time_string);
void setLocalTime();
double secondsSinceEpoche();
rlTime& operator+= (rlTime &time);
rlTime& operator-= (rlTime &time);
rlTime operator+ (rlTime &time);
rlTime operator- (rlTime &time);
int operator== (rlTime &time);
int operator< (rlTime &time);
int operator<= (rlTime &time);
int operator> (rlTime &time);
int operator>= (rlTime &time);
int year;
int month;
int day;
int hour;
int minute;
int second;
int millisecond;
private:
char time_string[32]; // 2001-11-23 12:52:60 056
char iso_time_string[32]; // 2001-11-23T12:52:60.056
};
#endif

View File

@@ -0,0 +1,101 @@
/***************************************************************************
rludpsocket.h - description
-------------------
begin : Tue Apr 03 2007
copyright : (C) 2007 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_UDP_SOCKET_H_
#define _RL_UDP_SOCKET_H_
#include "rldefine.h"
#include "rlsocket.h"
#ifdef RLWIN32
#include <winsock2.h>
#include <windows.h>
#include <io.h>
#include <direct.h>
#define MSG_NOSIGNAL 0
#else
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "unistd.h"
#endif
/*! <pre>
class for encapsulating ip addresses
</pre> */
class rlIpAdr
{
public:
rlIpAdr();
virtual ~rlIpAdr();
int setAdr(const char *adr, int port);
int operator== (rlIpAdr &address1);
struct sockaddr_in address;
};
/*! <pre>
class for encapsulating UDP socket calls
</pre> */
class rlUdpSocket
{
public:
rlUdpSocket(int debug = 0);
virtual ~rlUdpSocket();
/*! <pre>
setsocketopt for SOL_SOCKET level
</pre> */
int setSockopt(int opt);
/*! <pre>
setsocketopt with full control
</pre> */
int setSockopt(int level, int optname, void *optval, int optlen);
/*! <pre>
return > 0 -> socket else error
</pre> */
int bind(int port);
/*! <pre>
return == 0 -> timeout
</pre> */
int select(int timeout);
/*! <pre>
return > 0 -> number of bytes read return == 0 -> timeout else error
</pre> */
int recvfrom(void *buf, int maxlen, rlIpAdr *source, int timeout = -1);
/*! <pre>
return >= 0 -> number of bytes written else error
</pre> */
int sendto(const void *buf, int len, rlIpAdr *dest);
/*! <pre>
return >= 0 -> number of bytes written else error
</pre> */
int printf(rlIpAdr *dest, const char *format, ...);
int debug, readflag, writeflag;
private:
struct sockaddr_in address;
int s;
};
#endif

View File

@@ -0,0 +1,98 @@
/***************************************************************************
rlwebcam.h - description
-------------------
begin : Mo Aug 24 2009
copyright : (C) 2009 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
#ifndef _RL_WEBCAM_H_
#define _RL_WEBCAM_H_
#include "rldefine.h"
#include "rlsocket.h"
#include "rlstring.h"
/*! <pre>
class for handling networked webcams over http:// that use motion jpeg
If you do not know under which URL your webcam provides the M-JPEG video stream
you may use tcpdump to figure it out.
Example:
tcpdump -X -i eth0 -t -q -s 0 "host 192.168.1.200 && port 80" | grep -A 10 GET
IP myhost.46727 > 192.168.1.200.http: tcp 97
0x0000: 4500 0089 edb6 4000 4006 c891 c0a8 010e E.....@.@.......
0x0010: c0a8 01c8 b687 0050 d99f 8b7d 0003 d5b2 .......P...}....
0x0020: 5018 16d0 2460 0000 4745 5420 2f63 6769 P...$`..GET./cgi
0x0030: 2d62 696e 2f53 7472 6561 6d3f 5669 6465 -bin/Stream?Vide
0x0040: 6f20 4175 7468 6f72 697a 6174 696f 6e3a o.Authorization:
0x0050: 2042 6173 6963 2059 5752 7461 5734 3663 .Basic.YWRtaW46c
0x0060: 4746 7a63 3364 7663 6d51 3d3f 7765 6263 GFzc3dvcmQ=?webc
0x0070: 616d 5057 443d 526f 6f74 436f 6f6b 6965 amPWD=RootCookie
0x0080: 3030 3030 300d 0a0d 0a 00000....
Usage example for pvbrowser slot functions:
#include "rlwebcam.h"
typedef struct // (todo: define your data structure here)
{
rlWebcam webcamBig;
}
DATA;
static int slotInit(PARAM *p, DATA *d)
{
if(p == NULL || d == NULL) return -1;
p->sleep = 20;
p->force_null_event = 0;
d->webcamBig.debug = 0;
d->webcamBig.filename.printf("%swebcam.jpg", p->file_prefix);
d->webcamBig.setUrl("http://192.168.1.200/cgi-bin/Stream?Video Authorization: Basic YWRtaW46cGFzc3dvcmQ=?webcamPWD=RootCookie00000");
return 0;
}
static int slotNullEvent(PARAM *p, DATA *d)
{
if(p == NULL || d == NULL) return -1;
if(const char *fname = d->webcamBig.getFrame()) // OR if(const char *fname = d->webcamBig.getSnapshot())
{
pvDownloadFileAs(p,fname,"webcam.jpg");
pvSetImage(p,WebcamBig,"webcam.jpg"); // WebcamBig is a pvQImage object that accepts jpeg images
}
return 0;
}
</pre> */
class rlWebcam
{
public:
rlWebcam();
virtual ~rlWebcam();
int setUrl(const char *url);
int disconnect();
const char *getSnapshot(int timeout=3000);
const char *getFrame(int timeout=3000, int requestOnly=0);
int getFrameBuffer(unsigned char *buffer, int maxbuffer, int timeout=3000);
const char *getUrl();
const char *getHost();
int getPort();
const char *getPath();
int debug;
rlString filename;
rlSocket *sock;
private:
rlString url, temp1, temp2, temp3;
};
#endif

View File

@@ -0,0 +1,130 @@
/***************************************************************************
wthread.h - description
-------------------
begin : Sun Jan 02 2000
copyright : (C) 2001 by R. Lehrig
email : lehrig@t-online.de
***************************************************************************/
/***************************************************************************
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as *
* published by the Free Software Foundation *
* *
***************************************************************************/
/***********************************************************************************
Wrapper for posix threads (UNIX,VMS,windows)
(C) R. Lehrig 2001 lehrig@t-online.de
***********************************************************************************/
#ifndef _RL_WTHREAD_H_
#define _RL_WTHREAD_H_
#ifndef SWIG
#include "rldefine.h"
#ifdef RLWIN32
#define WTREAD_GNUC10 ( __GNUC__ * 1000 ) + __GNUC_MINOR__
#if WTREAD_GNUC10 < 4008
#define RLWIN32THREAD
#else
#include <pthread.h>
#endif
#endif
#ifdef RLWIN32THREAD
#include <windows.h>
#include <winbase.h>
#include <stddef.h>
#include <string.h>
#ifndef _WRAPTHREAD_
#ifndef _WTHREAD_H_
typedef unsigned long int pthread_t;
/* Attributes for threads */
typedef struct __sched_param
{
int sched_priority;
}SCHED_PARAM;
typedef struct
{
int __detachstate;
int __schedpolicy;
struct __sched_param __schedparam;
int __inheritsched;
int __scope;
size_t __guardsize;
int __stackaddr_set;
void *__stackaddr;
size_t __stacksize;
}pthread_attr_t;
typedef HANDLE pthread_mutex_t;
//old typedef CRITICAL_SECTION pthread_mutex_t;
typedef long pthread_mutexattr_t;
#endif
#endif
#else /* VMS or UNIX or new GCC on Windows*/
#ifndef WIN_PTHREADS_H
#include <pthread.h>
#endif
#endif /* end of MSWINDOWS */
#ifndef _WRAPTHREAD_
#ifndef _WTHREAD_H_
typedef struct
{
#ifdef RLWIN32THREAD
int cmax;
HANDLE hSemaphore;
#else
int cmax;
int nready;
pthread_mutex_t mutex;
pthread_cond_t cond;
#endif
}WSEMAPHORE;
#endif
#endif
/* function prototypes */
//#ifdef __cplusplus
//extern "C" {
//#endif
int rlwthread_attr_init(pthread_attr_t *attr);
int rlwthread_create(pthread_t *tid, const pthread_attr_t *attr,
void *(*func)(void*), void *arg);
void rlwthread_close_handle(pthread_t *tid);
void rlwthread_exit(void *status);
int rlwthread_join(pthread_t tid, void **status);
int rlwthread_mutex_init(pthread_mutex_t *mptr, const pthread_mutexattr_t *attr);
int rlwthread_mutex_destroy(pthread_mutex_t *mptr);
int rlwthread_mutex_lock(pthread_mutex_t *mptr);
int rlwthread_mutex_trylock(pthread_mutex_t *mptr);
int rlwthread_mutex_unlock(pthread_mutex_t *mptr);
int rlwthread_cancel(pthread_t tid);
int rlwrapinit_semaphore(WSEMAPHORE *s, int cmax);
int rlwrapdestroy_semaphore(WSEMAPHORE *s);
int rlwrapincrement_semaphore(WSEMAPHORE *s);
int rlwrapwait_semaphore(WSEMAPHORE *s);
int rlwthread_sleep(long msec);
void rlsleep(long msec);
//#ifdef __cplusplus
//};
//#endif
#else
// SWIG
void rlsleep(long msec);
#endif
#endif

View File

@@ -0,0 +1,5 @@
#ifdef unix
int setPort(char *name, char *baud, char parity);
#else
HANDLE WINAPI setPort(char *name, char *baud, char parity);
#endif

BIN
libs/pvb/x64/rllib.lib Normal file

Binary file not shown.

BIN
libs/pvb/x64/rlsvgcat.exe Normal file

Binary file not shown.

BIN
libs/pvb/x64/serverlib.lib Normal file

Binary file not shown.

View File

@@ -1,5 +1,23 @@
cmake_minimum_required(VERSION 3.23)
###############################################################################
### define funcitons ###
## function: visual studio source group
macro(ADD_SOURCE_GROUP srcpath)
file(GLOB src_h ${PROJECT_SOURCE_DIR}/${srcpath}/*.h)
file(GLOB src_cpp ${PROJECT_SOURCE_DIR}/${srcpath}/*.cpp)
set(src_tmp ${src_h} ${src_cpp})
if (${srcpath} STREQUAL "./" OR ${srcpath} STREQUAL "." OR ${srcpath} STREQUAL "")
set(groupName src)
else()
set(groupName src/${srcpath})
endif()
source_group(${groupName} FILES ${src_tmp})
list(APPEND SOURCE_FILE ${src_tmp})
endmacro(ADD_SOURCE_GROUP)
###############################################################################
set(PROJECT_NAME EES)
project(${PROJECT_NAME})
@@ -15,6 +33,8 @@ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Od /Ob2")
# 设置 Release 模式下链接器的调试信息
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG")
add_definitions(-DWIN32_LEAN_AND_MEAN)
# Qt_PATH 为 Qt 的安装地址
set(QT_PATH "D:/Programs/Qt5/5.15.2/msvc2019_64")
set(CMAKE_PREFIX_PATH ${QT_PATH}/lib/cmake)
@@ -33,10 +53,10 @@ find_package(Qt5 COMPONENTS
WebEngineWidgets
REQUIRED)
add_definitions(-DWIN32_LEAN_AND_MEAN)
set(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set(THIRDPARTY_PATH ${ROOT_PATH}/../thirdparty)
set(PVLIBS_PATH ${ROOT_PATH}/../libs/pvb)
include_directories(
${ROOT_PATH}
@@ -46,24 +66,20 @@ include_directories(
${THIRDPARTY_PATH}
${THIRDPARTY_PATH}/mysql/include
${THIRDPARTY_PATH}/nlohmann_json-3.11.2
${PVLIBS_PATH}/include/pvserver
${PVLIBS_PATH}/include/rllib
)
macro(ADD_SOURCE_GROUP srcpath)
file(GLOB src_h ${PROJECT_SOURCE_DIR}/${srcpath}/*.h)
file(GLOB src_cpp ${PROJECT_SOURCE_DIR}/${srcpath}/*.cpp)
set(src_tmp ${src_h} ${src_cpp})
source_group(src/${srcpath} FILES ${src_tmp})
list(APPEND SOURCE_FILE ${src_tmp})
endmacro(ADD_SOURCE_GROUP)
# 设置编译源文件
ADD_SOURCE_GROUP(./)
ADD_SOURCE_GROUP(.)
ADD_SOURCE_GROUP(common)
ADD_SOURCE_GROUP(app)
ADD_SOURCE_GROUP(database)
ADD_SOURCE_GROUP(protocol)
ADD_SOURCE_GROUP(widgets)
ADD_SOURCE_GROUP(widgets/pages)
#ADD_SOURCE_GROUP(widgets)
#ADD_SOURCE_GROUP(widgets/pages)
ADD_SOURCE_GROUP(pv)
ADD_SOURCE_GROUP(pv/pages)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)
add_executable(${PROJECT_NAME} ${SOURCE_FILE})
@@ -81,5 +97,7 @@ target_link_libraries(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
ws2_32 iphlpapi
${THIRDPARTY_PATH}/mysql/lib/x64/libmysql.lib
${PVLIBS_PATH}/x64/serverlib.lib
${PVLIBS_PATH}/x64/rllib.lib
)

View File

@@ -1,5 +1,4 @@
#include "Admin.h"
#include "app/Dao.h"
#include "common/Logger.h"
Errcode Admin::longin(std::string username, std::string passwd)

49
src/app/AppData.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include "AppData.h"
#include "app/Station.h"
std::shared_ptr<Station> AppData::getStation(int stationId)
{
auto iter = mapStation.find(stationId);
if (iter!=mapStation.end())
{
return iter->second;
}
return nullptr;
}
std::shared_ptr<Station> AppData::getStationByName(std::string name)
{
for (auto iter = mapStation.begin(); iter!=mapStation.end(); ++iter)
{
if (iter->second->name == name)
{
return iter->second;
}
}
return nullptr;
}
void AppData::getStationNames(std::vector<std::string>& vecNames)
{
vecNames.resize(mapStation.size());
int i = 0;
for (auto iter = mapStation.begin(); iter!=mapStation.end(); ++iter)
{
vecNames[i] = iter->second->name;
}
}
std::shared_ptr<Device> AppData::getDevice(int stationId, int deviceId)
{
auto station = getStation(stationId);
if (station)
{
return station->getDevice(deviceId);
}
return nullptr;
}
void AppData::loadStatData()
{
}

48
src/app/AppData.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <memory>
#include <map>
#include <unordered_map>
class Station;
class Device;
class AppData
{
public:
std::shared_ptr<Station> getStation(int stationId);
std::shared_ptr<Station> getStationByName(std::string name);
void getStationNames(std::vector<std::string>& vecNames);
std::shared_ptr<Device> getDevice(int stationId, int deviceId);
// 读取统计数据: 今日统计数据,累计统计数据
void loadStatData();
public:
///////////////////////////////////////////////////////////////////////////////////////////////
// === 系统 ===
int64_t sysActivationTime {};
///////////////////////////////////////////////////////////////////////////////////////////////
// === 数据库 ===
struct {
std::string host;
int port;
std::string user;
std::string passwd;
} db;
///////////////////////////////////////////////////////////////////////////////////////////////
// === 场站信息 ===
std::unordered_map<int, std::shared_ptr<Station>> mapStation;
///////////////////////////////////////////////////////////////////////////////////////////////
// === 角色定义 ===
};

View File

@@ -1,12 +0,0 @@
#pragma once
class AppSetting
{
public:
static AppSetting& instance() {
static AppSetting inst;
return inst;
}
};

View File

@@ -1,13 +1,92 @@
#include "Application.h"
#include "common/Utils.h"
#include "Config.h"
#include "app/Dao.h"
#include "app/Device.h"
#include "database/DaoEntity.h"
#include "database/Dao.h"
#include "app/Station.h"
#include "app/Device.h"
void InitStation()
{
AppData& appdata = Application::instance().getAppData();
// 读取数据库
std::vector<DataFields> result;
DAO::queryStationList(result);
for (auto& fields: result)
{
int stationId = fields.getInt(DMStation::STATION_ID);
auto station = std::make_shared<Station>(stationId);
station->name = fields.getStr(DMStation::NAME);
station->energyCapacity = fields.getDouble(DMStation::CAPACITY);
appdata.mapStation[stationId] = station;
}
}
void InitDevice()
{
AppData& appdata = Application::instance().getAppData();
vector<DataFields> result;
DAO::queryDeviceList(result);
for (auto& fields: result)
{
int deviceId = fields.getInt(DMDevice::DEVICE_ID);
int stationId = fields.getInt(DMDevice::STATION_ID);
auto station = appdata.getStation(stationId);
if (station)
{
auto device = Device::create(fields);
station->addDevice(deviceId, device);
}
else
{
XLOGE() << "init device error: unknown station_id:[" << stationId << "] device_id=" << deviceId;
}
}
}
void InitStatData()
{
AppData& appdata = Application::instance().getAppData();
std::string curDate = Utils::dateStr();
vector<DataFields> result;
DAO::queryStatDataList(curDate, curDate, result);
for (auto& fields: result)
{
std::string dt = fields.getStr(DMStatStation::DT);
int stationId = fields.getInt(DMStatStation::STATION_ID);
auto station = appdata.getStation(stationId);
if (station)
{
station->storageIn = fields.getFloat(DMStatStation::STORAGE_ELECT_IN);
station->storageOut = fields.getFloat(DMStatStation::STORAGE_ELECT_OUT);
//station->storageNumIn = fields.getFloat(DMStatStation::STORAGE_NUM);
//station->storageNumOut = fields.getFloat(DMStatStation::STORAGE_NUM);
station->storageNumErr = fields.getFloat(DMStatStation::STORAGE_NUM_ERR);
station->solarGen = fields.getFloat(DMStatStation::SOLAR_ELECT_GEN);
station->solarGrid = fields.getFloat(DMStatStation::SOLAR_ELECT_GRID);
station->solarNumErr = fields.getFloat(DMStatStation::SOLAR_NUM_ERR);
station->chargeElect = fields.getFloat(DMStatStation::CHARGE_ELECT);
station->chargeNum = fields.getFloat(DMStatStation::CHARGE_NUM);
station->chargeNumErr = fields.getFloat(DMStatStation::CHARGE_NUM_ERR);
}
else
{
XLOGE() << "init staticis data error: unknown station_id:[" << stationId << "] dt=" << dt;
}
}
}
void Application::init()
{
// 初始化系统配置,读取配置文件
Config::init("assets/config/app.json");
// 设置数据库配置
@@ -23,79 +102,23 @@ void Application::init()
// 连接数据库,读取基础信息
// 初始化场站信息
InitStation();
// 读取设备信息,连接设备
this->initDevice();
InitDevice();
// 读取基础统计信息,在系统总览中需要展示
InitStatData();
// 创建设备处理线程
std::thread([=]() { runThreadDevice(); }).detach();
// 创建主业务循环线程
std::thread([=]() { runThreadMain(); }).detach();
}
static void addDeviceTest(vector<DataFields>& v, int device_id, int type, std::string name, std::string code, int is_open, std::string attrs = "{}")
AppData& Application::getAppData()
{
DataFields fields;
fields.set("device_id", device_id);
fields.set("type", type);
fields.set("name", name);
fields.set("code", code);
fields.set("is_open", is_open);
fields.set("attrs", attrs);
v.push_back(fields);
}
void Application::initDevice()
{
DaoEntity dao("");
std::string sql = "select * from device;";
vector<DataFields> result;
//dao.exec(sql, result);
addDeviceTest(result, 1, 1, "变压器", "", 1);
addDeviceTest(result, 2, 2, "配电柜1", "", 1);
addDeviceTest(result, 3, 3, "电表", "", 1);
addDeviceTest(result, 4, 4, "门禁", "", 1);
addDeviceTest(result, 5, 5, "空调", "", 1);
addDeviceTest(result, 6, 6, "照明", "", 1);
addDeviceTest(result, 7, 7, "消防", "", 1);
addDeviceTest(result, 8, 8, "光照监测设备", "", 1);
addDeviceTest(result, 9, 9, "风速监测设备", "", 1);
addDeviceTest(result, 10, 10, "温湿度监测设备", "", 1);
addDeviceTest(result, 11, 11, "烟感监测设备", "", 1);
addDeviceTest(result, 12, 12, "水浸传感器", "", 1);
addDeviceTest(result, 13, 13, "视频监控", "", 1);
addDeviceTest(result, 14, 101, "逆变器", "", 1);
addDeviceTest(result, 15, 102, "汇流箱", "", 1);
addDeviceTest(result, 16, 103, "光伏板", "", 1);
addDeviceTest(result, 17, 104, "风力发电机", "", 1);
addDeviceTest(result, 18, 105, "储能变流器", "", 1);
addDeviceTest(result, 19, 106, "储能电池", "", 1);
addDeviceTest(result, 20, 107, "BMS", "", 1);
addDeviceTest(result, 21, 108, "充电桩", "", 1);
addDeviceTest(result, 22, 103, "光伏板-1000", "", 1);
addDeviceTest(result, 23, 108, "充电桩-000001", "", 1);
addDeviceTest(result, 24, 103, "光伏板-1001", "", 1);
addDeviceTest(result, 25, 103, "光伏板-1002", "", 1);
addDeviceTest(result, 26, 103, "光伏板-1003", "", 1);
addDeviceTest(result, 27, 103, "光伏板-1004", "", 1);
addDeviceTest(result, 28, 103, "光伏板-1005", "", 1);
addDeviceTest(result, 29, 103, "光伏板-1006", "", 1);
addDeviceTest(result, 30, 103, "光伏板-1007", "", 1);
addDeviceTest(result, 31, 103, "光伏板-1008", "", 1);
addDeviceTest(result, 32, 103, "光伏板-1009", "", 1);
addDeviceTest(result, 33, 103, "光伏板-1010", "", 1);
addDeviceTest(result, 34, 103, "光伏板-1011", "", 1);
addDeviceTest(result, 35, 103, "光伏板-1012", "", 1);
addDeviceTest(result, 36, 106, "储能电池-001", "", 1);
addDeviceTest(result, 37, 106, "储能电池-005", "", 1);
addDeviceTest(result, 38, 106, "储能电池-002", "", 1);
addDeviceTest(result, 39, 106, "储能电池-003", "", 1);
addDeviceTest(result, 40, 106, "储能电池-004", "", 1);
for (auto& fields: result)
{
Device::add(fields);
}
return appdata_;
}
void Application::runThreadMain()
@@ -110,7 +133,6 @@ void Application::runThreadMain()
}
void Application::runThreadDevice()
{
while (!isQuit())

View File

@@ -1,85 +1,10 @@
#pragma once
#include <thread>
#include "common/Logger.h"
#include "Operator.h"
struct AppData
{
/////////////////////////////////////////////
/// === 系统 ===
int64_t sysActivationTime {};
/////////////////////////////////////////////
/// === 数据库 ===
struct {
std::string host;
int port;
std::string user;
std::string passwd;
} db;
/////////////////////////////////////////////
/// === 系统统计 ===
// 累计发电量单位kWh
double electGenTatal {};
// 累计入网电量单位kWh
double electInTotal {};
// 累计收益,单位:元
double incomeTotal {};
// 碳减排量, 单位:吨
double ccers {};
/////////////////////////////////////////////
/// === 环境 ===
// 光照度
double illuminance {};
// 辐照度
double irradiance {};
// 风速
double windspeed {};
// 温度
double temperature {};
// 湿度
double humidity {};
/////////////////////////////////////////////
/// === 日统计 ===
struct {
// 发电量
double electGen {};
// 入网电量
double electIn {};
// 发电收益金额
double incomeElect {};
// 储能电量
double electStorage {};
// 储能次数
int numStore {};
// 放电电量
double electDischarge {};
// 放电次数
int numDischarge {};
// 用电电量
double electLoad {};
// 充电电量
double electCharge {};
// 充电次数
int numCharge {};
// 充电收益
double incomeCharge {};
// 故障次数
int numFault {};
// 故障次数:光伏设备
int numFaultSolar {};
// 故障次数:储能设备
int numFaultStorage {};
// 故障次数:负荷设备
int numFaultLoad {};
} statDay;
};
#include "app/AppData.h"
class Application
{
@@ -91,7 +16,8 @@ public:
}
void init();
void initDevice();
AppData& getAppData();
bool isQuit() { return isQuit_; }
Operator& getOperator() { return op_; }
@@ -100,9 +26,12 @@ public:
void runThreadDevice();
private:
public:
bool isQuit_ = false;
// 登录的管理员信息
Operator op_;
// 应用数据
AppData appdata_;
};

View File

@@ -1,4 +1,4 @@
#include "Dao.h"
#include "Dao1.h"
#include "common/Logger.h"
#include "common/Utils.h"
#include "common/Snowflake.h"
@@ -17,7 +17,7 @@ std::shared_ptr<DaoEntity> DAO::get(std::string tableName)
Errcode DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err)
{
std::string t = Utils::timeNowStr();
std::string t = Utils::timeStr();
if (!dao)
{
dao = std::make_shared<DaoEntity>("");
@@ -90,7 +90,7 @@ bool DAO::writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string u
fieldsLog.set("user_id", userId);
fieldsLog.set("user_account", account);
fieldsLog.set("content", text);
fieldsLog.set("create_time", Utils::timeNowStr());
fieldsLog.set("create_time", Utils::timeStr());
bool ret = dao->insertFields({fieldsLog});
return ret;
}
@@ -131,7 +131,7 @@ int DAO::insertUser(DataFields& fields)
}
fields.set("user_id", Snowflake::instance().getIdStr());
fields.set("create_time", Utils::timeNowStr());
fields.set("create_time", Utils::timeStr());
ret = dao->insertFields(fields);
return (ret) ? 0 : 1;
}

View File

@@ -33,7 +33,7 @@
// return iter->second;
//}
int DeviceEntity::startComm()
int Device::startComm()
{
if (!isOpen)
{
@@ -64,36 +64,32 @@ int DeviceEntity::startComm()
return 0;
}
// ================================================================================================
// $$Device
std::map<int, std::shared_ptr<DeviceEntity>> Device::mapDevices;
void Device::add(DataFields& fields)
std::shared_ptr<Device> Device::create(DataFields& fields)
{
auto entity = std::make_shared<DeviceEntity>();
entity->deviceId = fields.getInt("device_id");
entity->type = fields.getInt("type");
entity->name = fields.getStr("name");
entity->code = fields.getStr("code");
entity->isOpen = fields.getInt("is_open");
entity->attrsJson = fields.getStr("attrs");
auto device = std::make_shared<Device>();
device->deviceId = fields.getInt("device_id");
device->type = fields.getInt("type");
device->name = fields.getStr("name");
device->code = fields.getStr("code");
device->isOpen = fields.getInt("is_open");
device->attrsJson = fields.getStr("attrs");
// 解析属性的JSON字符串转换成键值对
NJson jsonroot;
bool ret = NJsonParse(entity->attrsJson, jsonroot);
bool ret = NJsonParse(device->attrsJson, jsonroot);
if (!ret) // 解析错误
{
XLOGE() << "device attr json parse error, device_id=" << entity->deviceId;
XLOGE() << "device attr json parse error, device_id=" << device->deviceId;
}
else
{
for (auto& [key, val] : jsonroot.items()) {
std::string valType = val.type_name();
if (valType == "string") {
entity->attrs.set(key, val.get<std::string>());
device->attrs.set(key, val.get<std::string>());
}
else if (valType == "number") {
entity->attrs.set(key, val.get<int>());
device->attrs.set(key, val.get<int>());
}
else {
XLOGE() << key << ": [" << valType << "]";
@@ -101,26 +97,25 @@ void Device::add(DataFields& fields)
}
}
// 保存设备 entity 到 map
if (entity->deviceId != -1)
{
mapDevices[entity->deviceId] = entity;
}
// 启动通讯该函数中会自动判断isOpen状态选择是否进行通讯连接
entity->startComm();
device->startComm();
return device;
}
std::vector<std::shared_ptr<DeviceEntity>> Device::getDeviceByType(int type)
{
std::vector<std::shared_ptr<DeviceEntity>> vecDevice;
for (auto iter = mapDevices.begin(); iter!=mapDevices.end(); ++iter)
{
auto device = iter->second;
if (device && (type<=0 || device->type == type))
{
vecDevice.push_back(device);
}
}
return vecDevice;
}
//
//std::vector<std::shared_ptr<DeviceEntity>> Device::getDeviceByType(int type)
//{
// std::vector<std::shared_ptr<DeviceEntity>> vecDevice;
// for (auto iter = mapDevices.begin(); iter!=mapDevices.end(); ++iter)
// {
// auto device = iter->second;
// if (device && (type<=0 || device->type == type))
// {
// vecDevice.push_back(device);
// }
// }
// return vecDevice;
//}

View File

@@ -9,7 +9,7 @@
class CommEntity;
class DeviceEntity
class Device
{
public:
int deviceId = -1;
@@ -38,17 +38,19 @@ public:
// 启动通讯
int startComm();
static std::shared_ptr<Device> create(DataFields& fields);
};
class Device
{
public:
static void add(DataFields& fields);
static std::vector<std::shared_ptr<DeviceEntity>> getDeviceByType(int type);
public:
static std::map<int, std::shared_ptr<DeviceEntity>> mapDevices;
};
//class Device
//{
//public:
// static void add(DataFields& fields);
//
// static std::vector<std::shared_ptr<DeviceEntity>> getDeviceByType(int type);
//
//public:
// static std::map<int, std::shared_ptr<DeviceEntity>> mapDevices;
//};

View File

@@ -1,17 +1,17 @@
#include "Operator.h"
#include "DAO.h"
#include "common/Logger.h"
bool Operator::login(std::string account, std::string passwd, std::string& err)
{
auto ecode = DAO::login(nullptr, account, passwd, err);
if (ecode == Errcode::OK)
{
XLOGD() << "用户[" + account + "]登录成功";
}
else
{
XLOGD() << "用户[" + account + "]登录失败: " << err;
}
return (ecode == Errcode::OK);
//auto ecode; = DAO::login(nullptr, account, passwd, err);
//if (ecode == Errcode::OK)
//{
// XLOGD() << "用户[" + account + "]登录成功";
//}
//else
//{
// XLOGD() << "用户[" + account + "]登录失败: " << err;
//}
//return (ecode == Errcode::OK);
return true;
}

21
src/app/Station.cpp Normal file
View File

@@ -0,0 +1,21 @@
#include "Station.h"
Station::Station(int id) : id(id)
{
}
void Station::addDevice(int deviceId, std::shared_ptr<Device> device)
{
mapDevice_[deviceId] = device;
}
std::shared_ptr<Device> Station::getDevice(int deviceId)
{
auto iter = mapDevice_.find(deviceId);
if (iter!=mapDevice_.end())
{
return iter->second;
}
return nullptr;
}

74
src/app/Station.h Normal file
View File

@@ -0,0 +1,74 @@
#pragma once
#include <memory>
#include <unordered_map>
class Device;
class Station
{
public:
Station(int id);
void addDevice(int deviceId, std::shared_ptr<Device> device);
std::shared_ptr<Device> getDevice(int deviceId);
public:
int id {};
std::string name;
// 储能容量
double energyCapacity {};
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 系统统计 ===
// 累计发电量单位kWh
double electGenTatal {};
// 累计入网电量单位kWh
double electGridTotal {};
// 累计收益,单位:元
double incomeTotal {};
// 碳减排量, 单位:吨
double ccers {};
// 累计储能充电电量
double electStorageIn {};
// 累计储能放电电量
double electStorageOut {};
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 日统计 ===
double storageIn {}; // 储能充电电量
double storageOut {}; // 储能放电电量
int storageNumIn {}; // 储能充电次数
int storageNumOut {}; // 储能放电次数
int storageNumErr {}; // 储能故障次数
double solarGen {}; // 光伏发电电量
double solarGrid {}; // 光伏入网电量
int solarNumErr {}; // 光伏故障次数
double chargeElect {}; // 充电设备充电电量
int chargeNum {}; // 充电设备充电次数
int chargeNumErr {}; // 充电设备故障次数
double incomeElect {}; // 发电收益金额
double incomeCharge {}; // 充电收益金额
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 环境 ===
// 光照度
double illuminance {};
// 辐照度
double irradiance {};
// 风速
double windspeed {};
// 温度
double temperature {};
// 湿度
double humidity {};
///////////////////////////////////////////////////////////////////////////////////////////////
/// === 设备信息 ===
std::unordered_map<int, std::shared_ptr<Device>> mapDevice_;
};

Some files were not shown because too many files have changed in this diff Show More