Commit dac05358 authored by Claes Sjofors's avatar Claes Sjofors

Simulate server implemented

parent e70e755e
......@@ -244,7 +244,8 @@ static pwr_tStatus nmpsbck_write_cells( bck_ctx bckctx,
FILE *bckfile);
static pwr_tStatus nmpsbck_write_data( bck_ctx bckctx,
FILE *bckfile);
static pwr_tStatus nmpsbck_read( bck_ctx bckctx);
static pwr_tStatus nmpsbck_read( bck_ctx bckctx,
char *backupfile);
static pwr_tStatus nmpsbck_cell_handler( bck_ctx bckctx);
static pwr_tStatus nmpsbck_free( bck_ctx bckctx);
......@@ -1626,7 +1627,7 @@ static pwr_tStatus nmpsbck_check_file( bck_ctx bckctx,
*
**************************************************************************/
static pwr_tStatus nmpsbck_read( bck_ctx bckctx)
static pwr_tStatus nmpsbck_read( bck_ctx bckctx, char *backupfile)
{
pwr_tStatus sts;
nmpsbck_t_cellheader cellheader;
......@@ -1668,8 +1669,8 @@ static pwr_tStatus nmpsbck_read( bck_ctx bckctx)
/* Open file 1 */
file_num = 1;
bckfile1_sts = NMPS__SUCCESS;
nmpsbck_get_filename( bckctx->bckconfig->BackupFile,
filename, NMPSBCK_FILE_EXT1);
nmpsbck_get_filename( backupfile,
filename, NMPSBCK_FILE_EXT1);
#if defined(OS_ELN)
bckfile1 = fopen( filename, "r+", "shr=get");
......@@ -1697,8 +1698,8 @@ static pwr_tStatus nmpsbck_read( bck_ctx bckctx)
file_num = 2;
bckfile2_sts = NMPS__SUCCESS;
nmpsbck_get_filename( bckctx->bckconfig->BackupFile,
filename, NMPSBCK_FILE_EXT2);
nmpsbck_get_filename( backupfile,
filename, NMPSBCK_FILE_EXT2);
#if defined(OS_ELN)
bckfile2 = fopen( filename, "r+", "shr=get");
......@@ -2627,7 +2628,7 @@ static pwr_tStatus nmpsbck_free( bck_ctx bckctx)
return NMPS__SUCCESS;
}
int main()
int main( int argc, char *argv[])
{
bck_ctx bckctx;
pwr_tStatus sts;
......@@ -2644,6 +2645,28 @@ int main()
char mp[2000];
qcom_sGet get;
if ( argc > 2 && strcmp( argv[1], "-l") == 0) {
errh_Init("nmps_bck_load", 0);
sts = gdh_Init("nmps_bck_load");
if (EVEN(sts)) LogAndExit( sts);
bckctx = calloc( 1 , sizeof( *bckctx));
if ( bckctx == 0 ) return NMPS__NOMEMORY;
bckctx->file_num = 1;
sts = nmps_get_bckconfig( bckctx);
if (EVEN(sts)) LogAndExit( sts);
if ( !bckctx->bckconfig->NoRead) {
/* Restore the specified backup file */
sts = nmpsbck_read( bckctx, argv[2]);
}
exit(0);
}
errh_Init("rs_nmps_bck", 0);
if (!qcom_Init(&sts, 0, "rs_nmps_bck")) {
......@@ -2678,7 +2701,7 @@ int main()
if ( !bckctx->bckconfig->NoRead) {
/* Restore the old backup file */
sts = nmpsbck_read( bckctx);
sts = nmpsbck_read( bckctx, bckctx->bckconfig->BackupFile);
}
else {
/* Release the cells by setting backup done flag */
......@@ -2765,6 +2788,12 @@ int main()
else if (new_event.b.swapDone && swap) {
swap = 0;
}
else if (new_event.b.simLoadStart && !swap) {
swap = 1;
}
else if (new_event.b.simLoadDone && swap) {
swap = 0;
}
else if (new_event.b.terminate) {
exit(0);
}
......
......@@ -1981,11 +1981,46 @@ fromEvent (
setTimerActive(cMessageIdx, FALSE);
errh_Info("No supervise objects.");
}
} else if (new_event.b.swapInit & !cur_event.b.swapInit) {
}
else if (new_event.b.swapInit & !cur_event.b.swapInit) {
l.supListState = eSupListState_Wait;
errh_Info("Warm restart initiated.");
handlerEvent(eHEvent_RestartInit, l.head.nix);
} else if (new_event.b.terminate & !cur_event.b.terminate) {
}
else if (new_event.b.simLoadStart & !cur_event.b.simLoadStart) {
LstLink(sOutunit) *ol;
sOutunit *op;
l.supListState = eSupListState_Wait;
handlerEvent(eHEvent_RestartInit, l.head.nix);
for (ol = LstFir(&l.outunit_l); ol != LstEnd(&l.outunit_l); ol = LstNex(ol)) {
op = LstObj(ol);
if (op->syncedIdx == op->eventIdx)
sendToOutunit(op, mh_eMsg_OutunitClear, 0, NULL, 0);
}
printf( "rt_emon: SimLoadStart\n");
}
else if (new_event.b.simLoadDone & !cur_event.b.simLoadDone) {
printf( "rt_emon: SimLoadDone\n");
handlerEvent(eHEvent_RestartComplete, l.head.nix);
reInitSupList();
if (!LstEmp(&l.sup_l)) {
l.supListState = eSupListState_Scan;
setTimerActive(cMessageIdx, TRUE);
if (!LstEmp(&l.detect_l)) {
scanTimerList();
scanDetectList();
setTimerActive(cDetectIdx, TRUE);
}
scanSupList();
} else {
l.supListState = eSupListState_NoSup;
setTimerActive(cMessageIdx, FALSE);
}
}
else if (new_event.b.terminate & !cur_event.b.terminate) {
exit(0);
}
......
include $(pwre_dir_symbols)
-include $(pwre_sroot)/tools/bld/src/$(os_name)/$(hw_name)/$(type_name)_generic.mk
ifeq ($($(type_name)_generic_mk),)
-include $(pwre_sroot)/tools/bld/src/$(os_name)/$(type_name)_generic.mk
endif
ifeq ($($(type_name)_generic_mk),)
include $(pwre_sroot)/tools/bld/src/$(type_name)_generic.mk
endif
-include ../../special.mk
-include ../special.mk
-include special.mk
ifndef link_rule_mk
link_rule_mk := 1
link = $(ldxx) $(linkflags) $(domap) -o $(export_exe) \
$(export_obj) $(objects) $(rt_msg_objs) \
$(pwr_obj)/rt_io_user.o\
$(pwre_conf_libdir) $(pwre_conf_libpwrrt) $(pwre_conf_lib)
endif
This diff is collapsed.
/*
* Proview Open Source Process Control.
* Copyright (C) 2005-2012 SSAB EMEA AB.
*
* This file is part of Proview.
*
* 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.
*
* This program 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 Proview. If not, see <http://www.gnu.org/licenses/>
*
* Linking Proview statically or dynamically with other modules is
* making a combined work based on Proview. Thus, the terms and
* conditions of the GNU General Public License cover the whole
* combination.
*
* In addition, as a special exception, the copyright holders of
* Proview give you permission to, from the build function in the
* Proview Configurator, combine Proview with modules generated by the
* Proview PLC Editor to a PLC program, regardless of the license
* terms of these modules. You may copy and distribute the resulting
* combined work under the terms of your choice, provided that every
* copy of the combined work is accompanied by a complete copy of
* the source code of Proview (the version used to produce the
* combined work), being distributed under the terms of the GNU
* General Public License plus this exception.
*/
#ifndef rt_sim_h
#define rt_sim_h
using namespace std;
#ifndef pwr_h
# include "pwr.h"
#endif
#include "pwr_baseclasses.h"
/*! \file rt_sim.h
\brief Contains the rt_sim class. */
/*! \addtogroup rt */
/*@{*/
typedef enum {
sim_eNMpsClear_All,
sim_eNMpsClear_NoBackup
} sim_eNMpsClear;
class rt_sim {
public:
rt_sim() : scan_time(0.5), thread_cnt(0), select_thread_cnt(0), halt_order_active(false),
load_order_active(false), disable_old(0) {
memset(plcpgm_scanoff_set,0,sizeof(plcpgm_scanoff_set));}
void init( qcom_sQid *qid);
void open();
void close();
void scan();
double scantime() { return scan_time;}
pwr_tStatus print_object( FILE *fp, pwr_tOid oid);
pwr_tStatus store();
pwr_tStatus load();
void clear_timers();
void restore_timers();
void restore_timers( int thread_idx, pwr_tOid oid);
void clear_nmps( sim_eNMpsClear mode);
void store_nmps();
void load_nmps();
void delete_children( pwr_tOid oid);
double scan_time;
pwr_sClass_SimulateConfig *conf;
unsigned int thread_cnt;
pwr_sClass_PlcThread *threadp[30];
pwr_tDlid thread_dlid[30];
unsigned int select_thread_cnt;
unsigned int plcpgm_cnt;
unsigned int plcpgm_thread_idx[200];
pwr_sClass_windowplc *windowplcp[200];
pwr_tDlid windowplc_dlid[200];
int plcpgm_scanoff_set[200];
bool halt_order_active;
bool step_order_active;
bool continue_order_active;
bool load_order_active;
pwr_tBoolean disable_old;
};
/*@}*/
#endif
......@@ -264,7 +264,8 @@ init_process ( char *name)
{
plc_sProcess *pp;
pwr_tStatus sts = PLC__SUCCESS;
pwr_tObjid pp_oid;
pwr_tOid pp_oid;
pwr_tOid sim_oid;
int found;
char busidstr[10];
char pp_name[80];
......@@ -339,6 +340,13 @@ init_process ( char *name)
sts = gdh_ObjidToPointer(pp_oid, (void *)&pp->PlcProcess);
if (EVEN(sts)) return 0;
sts = gdh_GetClassList(pwr_cClass_SimulateConfig, &sim_oid);
if ( ODD(sts)) {
sts = gdh_ObjidToPointer(sim_oid, (void *)&pp->SimConfig);
if (EVEN(sts)) return 0;
}
#if defined OS_VMS
qdb->thread_lock.isThreaded = 1;
qdb->thread_lock.cond_signal = thread_CondSignal;
......
......@@ -123,6 +123,7 @@ typedef enum {
errh_eAnix_post = 21,
errh_eAnix_report = 22,
errh_eAnix_sevhistmon = 23,
errh_eAnix_sim = 24,
errh_eAnix_plc1 = 41,
errh_eAnix_plc2 = 42,
errh_eAnix_plc3 = 43,
......
......@@ -4189,8 +4189,8 @@ pwr_tStatus gdh_ArefDisabled(
}
static pwr_tStatus gdh_FWriteObjectR( FILE *fp, char *ap, char *aname, pwr_tAttrRef *arp,
pwr_tCid cid)
pwr_tStatus gdh_FWriteObjectR( FILE *fp, char *ap, char *aname, pwr_tAttrRef *arp,
pwr_tCid cid)
{
pwr_tOName name;
char value_str[512];
......@@ -4647,8 +4647,45 @@ pwr_tStatus gdh_AttrValueToString(
case pwr_eType_Time: {
char timstr[64];
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_DateAndTime,
timstr, sizeof(timstr));
if( format && format[0] == '%' && format[2] == 't') {
switch ( format[1]) {
case '1':
// Format %1t, only time, no hundredth
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_Time,
timstr, sizeof(timstr));
timstr[8] = 0;
break;
case '2':
// Format %2t, only time, with hundredth
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_Time,
timstr, sizeof(timstr));
break;
case '3':
// Format %3t, compressed date and time, no hundredth
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_ComprDateAndTime,
timstr, sizeof(timstr));
timstr[17] = 0;
break;
case '4':
// Format %4t, date only
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_DateAndTime,
timstr, sizeof(timstr));
timstr[11] = 0;
break;
case '5':
// Format %5t, compressed date only
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_ComprDateAndTime,
timstr, sizeof(timstr));
timstr[8] = 0;
break;
default:
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_DateAndTime,
timstr, sizeof(timstr));
}
}
else
sts = time_AtoAscii( (pwr_tTime *) value_ptr, time_eFormat_DateAndTime,
timstr, sizeof(timstr));
if ( EVEN(sts))
strcpy( timstr, "-");
*len = sprintf( str, "%s", timstr);
......
......@@ -292,6 +292,15 @@ gdh_FReadObject (
pwr_tAttrRef *arp
);
pwr_tStatus
gdh_FWriteObjectR (
FILE *fp,
char *ap,
char *aname,
pwr_tAttrRef *arp,
pwr_tCid cid
);
pwr_tStatus
gdh_FWriteObject (
char *filename,
......
......@@ -53,7 +53,8 @@ typedef union {
pwr_Bits( swapDone , 1),
pwr_Bits( terminate , 1),
pwr_Bits( fill_1 , 2),,
pwr_Bits( simLoadStart , 1),
pwr_Bits( simLoadDone , 1),
pwr_Bits( plcProc1 , 1),
pwr_Bits( plcProc2 , 1),
......@@ -86,9 +87,10 @@ typedef union {
#define ini_mEvent_newPlcStartDone pwr_Bit(5)
#define ini_mEvent_oldPlcStop pwr_Bit(6)
#define ini_mEvent_oldPlcStopDone pwr_Bit(7)
#define ini_mEvent_swapDone pwr_Bit(8)
#define ini_mEvent_terminate pwr_Bit(9)
#define ini_mEvent_simLoadStart pwr_Bit(10)
#define ini_mEvent_simLoadDone pwr_Bit(11)
#define ini_mEvent_plc1 pwr_Bit(12)
#define ini_mEvent_plc2 pwr_Bit(13)
#define ini_mEvent_plc3 pwr_Bit(14)
......
......@@ -148,6 +148,7 @@ enum mh_eMsg {
mh_eMsg_OutunitHello = 19,
mh_eMsg_OutunitInfo = 20,
mh_eMsg_OutunitSync = 21,
mh_eMsg_OutunitClear = 22,
mh_eMsg_ProcDown = 24,
......
......@@ -755,6 +755,11 @@ fromHandler (
if (hp->selGen != l.selGen)
sendInfo(hp);
break;
case mh_eMsg_OutunitClear:
printf( "Clear alarmlist received\n");
if (l.cbClearAlarmList != NULL)
l.cbClearAlarmList(hp->nix);
break;
default:
errh_Warning("Received unhandled messagetype: %d", p->type);
break;
......
......@@ -179,6 +179,11 @@ struct plc_sThread {
pwr_tBoolean first_scan;
int skip_count;
pwr_tBoolean emergency_break_old;
pwr_tBoolean sim_initdone_old;
pwr_tBoolean sim_disable_old;
unsigned int sim_idx;
unsigned int sim_halted;
unsigned int sim_singlestep;
};
struct plc_sProcess {
......@@ -187,6 +192,7 @@ struct plc_sProcess {
pwr_sNode *Node;
pwr_sClass_IOHandler *IOHandler;
pwr_sClass_PlcProcess *PlcProcess;
pwr_sClass_SimulateConfig *SimConfig;
pwr_tFullName nodeName;
qcom_sQid eventQ;
pwr_tOid oid;
......
......@@ -61,6 +61,7 @@
#include "pwr_baseclasses.h"
#include "co_time.h"
#include "co_time_msg.h"
#include "co_cdh.h"
#include "rt_errh.h"
#include "rt_gdh.h"
#include "rt_plc_msg.h"
......@@ -68,6 +69,7 @@
#include "rt_plc.h"
#include "rt_thread.h"
#include "rt_thread_msg.h"
#include "rt_sim_msg.h"
#include "rt_que.h"
#include "rt_io_base.h"
#include "rt_csup.h"
......@@ -219,6 +221,87 @@ plc_thread (
/* Tell main we are done. */
que_Put(&sts, &tp->q_out, &tp->event, (void *)5);
}
static int sim_scan( plc_sThread *tp)
{
pwr_sClass_SimulateConfig *sp = tp->pp->SimConfig;
unsigned int i;
if ( !tp->sim_initdone_old && sp->InitDone) {
/* Identify index in simulate configuration */
for ( i = 0; i < sizeof(sp->PlcThreads)/sizeof(sp->PlcThreads[0]); i++) {
if ( cdh_ObjidIsEqual( tp->aref.Objid, sp->PlcThreads[i])) {
tp->sim_idx = i;
sp->ThreadStatus[i] = tp->sim_halted ? SIM__THREAD_HALT : SIM__THREAD_RUNNING;
break;
}
}
tp->sim_disable_old = sp->Disable;
}
tp->sim_initdone_old = sp->InitDone;
if ( !tp->sim_disable_old && sp->Disable) {
pwr_tTime current;
/* Use nominal scantime as time since last scan */
time_GetTimeMonotonic( &current);
time_Asub( &tp->one_before_scan, &current, &tp->scan_time);
time_GetTime( &current);
time_Asub( &tp->one_before_scan_abs, &current, &tp->scan_time);
tp->sim_disable_old = sp->Disable;
return 0;
}
tp->sim_disable_old = sp->Disable;
if ( sp->PlcHaltOrder && sp->ThreadSelected[tp->sim_idx]) {
if ( !tp->sim_halted) {
tp->sim_halted = 1;
sp->ThreadStatus[tp->sim_idx] = SIM__THREAD_HALT;
sp->PlcHaltOrder--;
}
}
if ( sp->PlcContinueOrder && sp->ThreadSelected[tp->sim_idx]) {
if ( tp->sim_halted) {
pwr_tTime current;
tp->sim_halted = 0;
sp->ThreadStatus[tp->sim_idx] = SIM__THREAD_RUNNING;
sp->PlcContinueOrder--;
/* Use nominal scantime as time since last scan */
time_GetTimeMonotonic( &current);
time_Asub( &tp->one_before_scan, &current, &tp->scan_time);
time_GetTime( &current);
time_Asub( &tp->one_before_scan_abs, &current, &tp->scan_time);
}
}
if ( tp->sim_singlestep && sp->PlcStepOrder == 0)
tp->sim_singlestep = 0;
if ( sp->PlcStepOrder && sp->ThreadSelected[tp->sim_idx] && !tp->sim_singlestep) {
if ( tp->sim_halted) {
pwr_tTime current;
tp->sim_singlestep = 1;
sp->PlcStepOrder--;
/* Use nominal scantime as time since last scan */
time_GetTimeMonotonic( &current);
time_Asub( &tp->one_before_scan, &current, &tp->scan_time);
time_GetTime( &current);
time_Asub( &tp->one_before_scan_abs, &current, &tp->scan_time);
return 0;
}
}
if ( sp->PlcLoadOrder && tp->sim_halted) {
sp->PlcLoadOrder--;
}
return tp->sim_halted;
}
static void
scan (
......@@ -234,6 +317,36 @@ scan (
time_GetTime(&tp->before_scan_abs);
pp->Node->SystemTime = tp->before_scan_abs;
if ( pp->SimConfig) {
if ( !pp->SimConfig->Disable || !tp->sim_disable_old) {
if ( sim_scan( tp)) {
pwr_tDeltaTime delta;
time_GetTimeMonotonic(&tp->after_scan);
time_Aadd(NULL, &tp->sync_time, &tp->scan_time);
time_Adiff(&delta, &tp->sync_time, &tp->after_scan);
if (time_Dcomp(&delta, NULL) > 0) {
#if defined OS_LYNX && USE_RT_TIMER
sem_wait(&tp->ScanSem);
#elif defined OS_MACOS || defined OS_FREEBSD || OS_OPENBSD || OS_CYGWIN
struct timespec ts;
ts.tv_sec = delta.tv_sec;
ts.tv_nsec = delta.tv_nsec;
nanosleep(&ts, NULL);
#else
struct timespec ts;
ts.tv_sec = tp->sync_time.tv_sec;
ts.tv_nsec = tp->sync_time.tv_nsec;
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
#endif
}
return;
}
}
else
tp->sim_halted = 0;
}
if (tp->loops > 0) {
/* if (sts == TIME__CLKCHANGE) {
time_Dadd(&tp->before_scan, &tp->one_before_scan, &tp->scan_time);
......
!
! Proview Open Source Process Control.
! Copyright (C) 2005-2012 SSAB EMEA AB.
!
! This file is part of Proview.
!
! 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.
!
! This program 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 Proview. If not, see <http://www.gnu.org/licenses/>
!
! Linking Proview statically or dynamically with other modules is
! making a combined work based on Proview. Thus, the terms and
! conditions of the GNU General Public License cover the whole
! combination.
!
! In addition, as a special exception, the copyright holders of
! Proview give you permission to, from the build function in the
! Proview Configurator, combine Proview with modules generated by the
! Proview PLC Editor to a PLC program, regardless of the license
! terms of these modules. You may copy and distribute the resulting
! combined work under the terms of your choice, provided that every
! copy of the combined work is accompanied by a complete copy of
! the source code of Proview (the version used to produce the
! combined work), being distributed under the terms of the GNU
! General Public License plus this exception.
!
! rt_sev_msg.msg -- <short description>
!
.facility SIM,26 /prefix = SIM__
success <Successful completion> /succ
file <Unable to open file> /error
threadrespond <All threads have not responded yet> /warning
loading <Loading...> /warning
storing <Storing...> /warning
loaded <Database successfully loaded> /info
stored <Database successfully stored> /info
halted <Plc threads halted> /info
continued <Plc threads continued> /info
stepped <Plc threads stepped> /info
notallhalted <All plc threads are not halted> /error
disabled <Simulate function is disabled> /error
thread_halt <Thread is halted> /error
thread_running <Thread is running> /info
nohalted <No halted plc threads found> /error
norunning <No running plc threads found> /error
active <Simulate active> /info
scanon <PlcPgm scan on> /info
scanoff <PlcPgm scan off> /error
scanon_set <Scan on set on selected PlcPgms> /info
scanoff_set <Scan off set on selected PlgPgms> /info
noselplcpgm <No PlcPgm selected> /error
.end
......@@ -16,6 +16,7 @@
23 thread
24 proc
25 sev
26 sim
50 hd
100 cdh
101 ndc
......
This diff is collapsed.
......@@ -117,6 +117,10 @@ int main(int argc, char *argv[])
// Hide
hide = 1;
break;
case '-':
// Display sent to gtk
i++;
break;
default:
cout << "Unknown argument: " << argv[i] << endl;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -437,6 +437,7 @@ void GlowArray::copy_from( const GlowArray& array)
case glow_eObjectType_Node:
case glow_eObjectType_GrowNode:
case glow_eObjectType_GrowSlider:
case glow_eObjectType_GrowConGlue:
{
if ( array.a[j] == ((GlowCon *)array.a[i])->destination())
dest_node = (GlowNode *)a[k];
......@@ -446,7 +447,8 @@ void GlowArray::copy_from( const GlowArray& array)
break;
}
default:
;
if ( array.a[j]->type() != glow_eObjectType_Con)
k++;
}
}
if ( dest_node && source_node)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment