/** * A sample TLM which uses the C++ API. * Feel free to delete noisy comments as you start your customization. */ /* BECAUSE THE PROGRAM IS SUBJECT TO CHANGE BY LICENSEE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include // The TLM name is "MYTLM" which should be but must not be 8 characters or shorter. DECLARE_TLM( TLM, "MYTLM", 0 ) /* DT_INT16 iw( "Input_Word" ); // Tag mapped DT words DT_INT16 ow( "Output_Word" ); */ void TLM::Init( req_init* req ) { printf( "%s: " __DATE__ " initializing...\n", Name() ); // can do file I/O here to read in configuration settings } void TLM::FirstScan() { printf( "%s: First Run Mode Scan, re-setting variables that need it.\n", Name() ); // Some drivers might want to do a first scan of only inputs while // not servicing outputs yet. If this is not the case, then you can // omit this function which will cause a default version to be // supplied by the state_logic library. } void TLM::Scan() { // If you are writing a MODULE rather than a DRIVER, then you can omit // this function, literally delete it from this file. // Otherwise your DRIVER should scan inputs and copy // them to the datatable here. And your DRIVER should read from the // datatable and send corresponding values to your outputs here. } // This is called in OPM_PROG or OPM_FAULTED modes only (non-run modes). // DT_OBJECTs are off limits in this function, because in non-run modes DT_OBJECTs // are not necessarily resolved. Using them from TLM::Idle() will usually // cause a SegFault, or worse, corrupt memory. void TLM::Idle() { // Nothing else to do in program or faulted mode. DT_OBJECTs are // off limits in these modes. // If you have nothing to do when in program mode or when in fault mode, // then you can omit this function by deleting it. } void TLM::ModeChange( int aNewMode, PLCINT* stsFile ) { printf( "%s: SetMode(old=%s, new=%s)\n", Name(), HlpShowMode( Mode() ), HlpShowMode( aNewMode ) ); if( aNewMode < OPM_RUN ) { // Zero any real world outputs here. SoftPLCs turn their // outputs off when entering TEST, PROGRAM or FAULT modes. // This function is called only on mode transitions. } } void TLM::DeInstall() { printf( "%s: deinstalling.\n", Name() ); // release any resources, close files and serial ports, etc. // If you have nothing to do, you can omit this function. }