You are on page 1of 70

Runtime System Description: CoDeSys SP 32 Bit Embedded

Document Version 3.0

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 1 of 70

CoDeSys SP 32 Bit Embedded

CONTENT

1 2

OVERVIEW INTRODUCTION
2.1 2.2 Components of the PLC program environment Functions of the components

6 7
7 8

THE CODESYS SINGLE TASKING RUNTIME SYSTEM


3.1 3.2 3.3 3.4 3.5 Supported Services Functions of the runtime system Modules of the runtime system system architecture Hardware and OS requirements Functionality in detail Processing control Processing of services

10
10 11 11 14 15 15 16 16 19 19 19 19 20 21 23 24 24 25 26 26 27 27 28 28 29 29 29 30 30 30 30 30 30
Page 2 of 70

3.5.1 3.5.2

3.5.2.1 Login 3.5.2.2 Logout 3.5.2.3 Start 3.5.2.4 Stop 3.5.2.5 Reading, writing and forcing of variables 3.5.2.6 Download of the Task-Configuration 3.5.2.7 Stateless monitoring of variables (LZS_READ_VAR_DIRECT) 3.5.2.8 Stateless writing of variables (LZS_WRITE_VAR_DIRECT) 3.5.2.9 PLC Browser commands (RTS_BROWSERCOMMAND) 3.5.2.10 Reading Project Info of Boot Project 3.5.2.11 Write file to PLC 3.5.2.12 Read file from PLC 3.5.3 3.5.4 Debugging Downloading of programs

3.5.4.1 Loading of the application program 3.5.4.2 Linking of the application program 3.5.5 3.5.6 3.5.7 3.6 3.7
tech_doc_e.doc / V1.2

Sampling Trace Flow Control Call Stack

Scaling the runtime system Format of the bootproject file (DEFAULT.PRG) Header Code Task configuration Hardware configuration IO description

3.7.1 3.7.2 3.7.3 3.7.4 3.7.5

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

3.7.6

Project Info

30

ADAPTING THE RUNTIME SYSTEM


4.1 The communication interface Block-wise transfer of messages Message configuration Communication Adaptation of the communication Driver implementation for TCP/IP (Level 2 Route) Communication with CAN 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6

32
34 34 35 36 36 37 37 37 38 39 39 39 40 40 41 41 42 43 43 44 44 45 45 45 46 46 47 47 47 47 47 47 47 49 49 49 50 51
Page 3 of 70

4.1.6.1 CANOpen protocol 4.1.6.2 CANOpen driver Interface functions 4.2 The storage model Fixed memory Dynamic memory Customer specific user program data management Relocating data to areas

4.2.1 4.2.2 4.2.3 4.2.4 4.3 4.4 4.5 4.6

The timer interface Setting the Automation Alliance target id The process map The debugging interface Debugging the motorola 68000 or ColdFire Debugging the Motorola PowerPC

4.6.1 4.6.2

4.6.2.1 Breakpoints with trap 4.6.2.2 Breakpoints with function call 4.6.2.3 Flow Control 4.6.3 4.6.4 4.7 Debugging the ARM Debugging the Intel 186

Adaptation to the C compiler Motorola 68k and ColdFire Motorola PowerPC Intel 186 Infineon Tricore

4.7.1 4.7.2 4.7.3 4.7.4 4.8

Additional server services and pre/post-processing Additional server services Preprocessing services Postprocessing services

4.8.1 4.8.2
tech_doc_e.doc / V1.2

4.8.3 4.9 4.10

Time behaviour and integration into multi-tasking operating systems Libraries Linking in the development system Linking in the runtime system

4.10.1 4.10.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

4.11

Retain Data All data memory (RAM) is buffered Only a part of the data memory (RAM ) is buffered RAM is not buffered, Flash or Hard Disc available

52 52 52 53 54 55 55 55 55 55 56 56 56 56 56 57 57 57 58 58 58 59 59 60 61 61 61 62 63 64 64 64 65 65 66 66 67

4.11.1 4.11.2 4.11.3 4.12 4.13

File system functions Introducing faster Tasks The callback library Interrupt Tasks

4.13.1 4.13.2

4.13.2.1 IntCycle 4.13.2.2 UsrIntISR<n> 4.13.2.3 UsrIntInsert 4.13.2.4 IntIsTraceTask 4.14 4.15 4.16 4.17 4.18 4.19 4.20 Exception handling The PLC Browser Misc adaption functions Extended 32 bit debug services Error messages from the controller Network variables and object dictionary Some useful runtime core functions Getting address and size of data segments Setting the maximum number of POUs Reducing the memory requirements of the runtime Monitoring of system variables Symbol management

4.20.1 4.20.2 4.20.3 4.20.4 4.20.5 4.21

Access variables Overview Enabling the feature in the programming system Download format

4.21.1 4.21.2 4.21.3 4.22 4.23 4.24 4.25

Enabling SoftMotion Enabling the password functionality Support different target ids in one controller Supporting SysLibDirect.lib and #-Addresses Syntax of the Read function Syntax of the Write function

4.25.1 4.25.2 4.26


tech_doc_e.doc / V1.2

Parameter Manager Download of parameter description Monitoring of parameter values

4.26.1 4.26.2

CODESYS PROGRAMMING SYSTEM

68

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 4 of 70

CoDeSys SP 32 Bit Embedded

5.1 5.2

System variables Defining interrupt Tasks

68 69

CHANGE HISTORY

70

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 5 of 70

CoDeSys SP 32 Bit Embedded

Overview

This document describes the principal configuration and modes of operation of the CoDeSys 32 bit embedded runtime system. So as to be able to reconcile the runtime with various items of hardware, all necessary adaptations and the interfaces to the operating system are explained in detail. The program is written in ANSI-C and has already been used in a wide variety of hardware (i8051, i80x86, Motorola 68000 (68k), Motorola PowerPC (MPC), Motorola ColdFire (MCF), ARM, TriCore etc.) and operating system environments. It is designed to be system-independent, thus enabling rapid adaptation of the CoDeSys programming system to any given PLC. It implements the complete functionality of a PLC cycle and supports communication with the programming system as well as all debugging functions that are supported by the CoDeSys programming system. To make understanding of the runtime system easier, the typical components of a PLC program or programming environment are firstly presented and the imbedding of the runtime system is described. This document describes the 3S embedded runtime system that works with the Motorola 68000, Power PC and ColdFire processor families, the ARM and TriCore processor families, and other 32bit processors. The document is divided in 5 chapters: Chapter 1 Chapter 2 Chapter 3 contains this Overview. contains a description of the principal structure of the CoDeSys runtime system. contains a more detailed description of the runtime system features. This is for background information. You may read it if you want a deeper understanding of the functionality contains a step-by-step instruction how to adapt the runtime system to your processor and operating system environment. Follow these instructions. tells you how you can configure the CoDeSys programming tool according your memory model. It also shows how to enable additional features such as interrupt tasks.

Chapter 4 Chapter 5

Warning: For security reasons, controllers must not be accessible from the Internet under any circumstances. Specifically, the TCP/IP programming port of the controller (usually 1200 and 1210/1211, or the controller specific ports) must not be accessible. In case Internet access is needed, a safe mechanism has to be used, like VPN.

Warning: With the PlcBrowser command setpwd <password> (or setpwd <password> 1) you can set a password that is required for all clients, that connects to this runtime system. If your client does not support a device login or an authenticated login, you can specify a parameter for this command, to set the password only for CoDeSys: setpwd <password> 0. This leads to a security problem, because an unauthorized access is possible to this target! You can delete the password with the PlcBrowser command delpwd.
tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 6 of 70

CoDeSys SP 32 Bit Embedded

Introduction

2.1

Components of the PLC program environment

The following paragraphs illustrate, with the aid of Figure 1, the individual components of the PLC program environment and the interaction between the CoDeSys programming system, the runtime system, the operating system and the I/Os.

CoDeSys
RS232 ETHERNET

Operating system
System ticks in ms Software interrupt Call of the debugging routine

I/Os Run-time system


cyclic call

PLCprogram

Process map

Input modules Output modules CAN Profibus Sercos

Drivers

Fig. 1

Relationship between the CoDeSys, runtime system, operating system and I/O components

The CoDeSys development system is operated on a PC under the Windows operating system. This provides for painless program development in all 5 IEC 1131-3 programming languages. Source programs can thus be edited and compiled into executable programs. Testing and execution of programs on the development system can be carried out in two different ways: in the simulation mode all the hardware is simulated. Here the PC (on which CoDeSys is working) simulates all the controller hardware. Thus no additional hardware or software is required apart from the development system. This mode is used for offline testing the application program. the second option consists in allowing the program to run directly on the controller. This requires a so-called runtime system (for which the German abbreviation is LZS) on the controller. For debugging purposes the development system communicates continuously and exchanges data with the runtime system. The runtime system integrates the PLC program and calls it cyclically. The development system is able to communicate using various media with the runtime system. Communication usually takes place via an RS232 interface. If the operating system that is being used provides network services, communication can also take place via Ethernet or CAN etc.
tech_doc_e.doc / V1.2

The operating system of the controller (e.g. pSOS+, OS9, VxWorks or others) must provide the following services to the runtime system: Bootup code serial communication interface (read and write blocks) memory management (malloc / free)
Page 7 of 70

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

ANSI standard libraries <stdio.h>, <string.h>, <math.h> for memory management (malloc / free), string manipulation (strcmp) 1 ms timer tick Block-oriented interface to permanent storage for the BootProject (CstFileRead(), ...) A debugging interface helps to port the runtime system to your environment

The runtime can also be run without OS, if this base functionality is given. See the interface functions in main.c to get details of the OS dependencies. The last group of components are the I/Os (see Figure 1). These are usually hardware modules via which PLC program data can either be read in or given out. The data are written by the PLC program to a common data interface or read from the interface. In the following paragraphs the data interface is called a process map. From the runtime system these I/O data are either forwarded directly to the modules or forwarded via special drivers to the field buses. Field bus drivers are not included in the runtime system. After identifying the four components of the PLC program environment the interaction between them will now be explained (CoDeSys runtime system operating system I/Os). 3S also offers a 32 bit full runtime system which includes pre-emptive multitasking and multi-clientsupport. It is bigger in code and data size, and needs a multi tasking operating system as a base. It is described in a separate document.

2.2

Functions of the components

After the program source text has been entered using the development system and an error-free compilation has proved possible, communication to the controller (i.e. to the runtime system) can be initiated. For this purpose CoDeSys sends a query to the runtime system (LZS) via the interface to establish the connection. If this query is positively confirmed by the runtime system, the compiled program is loaded into the controller and called cyclically by the runtime system. In this manner the controller is connected to CoDeSys. This status is called on-line operation. From this point in time all current variable values and the status of the loaded PLC program (run, stop) are displayed by the development system. For this purpose the variable values and program location currently being processed are interrogated by CoDeSys cyclically (e.g. every 200 ms). This interrogation takes place directly on the runtime system. The runtime system evaluates the queries and answers these immediately. If a timer block has been used in the PLC program, this block interrogates a function in the runtime system (GetTime()), that returns a timer value. This timer value is increased by 1 every millisecond. This functionality must be supplied by the operating system (see Figure 1). A breakpoint can now be set in the program. For this purpose the mouse is used to click on the line number in the desired line in the development system. The location of the breakpoint is then sent to the runtime system. Before the call of the PLC program the runtime system now overwrites the corresponding program line with a command to call a debug function (or with a command to trigger a software interrupt). The PLC program is then called. At the interrupt location in the program the function is then called (or a software interrupt is triggered). The debug function or the operating system then calls a special debugging routine in the runtime system that restores the old program code at the breakpoint position and waits for queries from CoDeSys. The runtime system pauses in this debug function or interrupt routine and waits for control commands from the development system (e.g. step over, run, ). The runtime system or PLC program communicates with the inputs and outputs (abbreviated to I/Os) as follows:
tech_doc_e.doc / V1.2

At the beginning of each PLC cycle all data of the inputs or input modules of the runtime system are copied into a common memory area (process map). In the same way at the end of each PLC cycle all the runtime system output data are transferred from the process map to the outputs or output modules. When writing and reading the I/Os the PLC program now accesses only the process map. Here the task of the runtime system consists in transferring the process map to the I/Os. For this purpose field bus drivers can also be integrated, so as to control I/O modules via field buses. The following picture shows the embedding of the IEC user code and libraries into the runtime system:
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 8 of 70

CoDeSys SP 32 Bit Embedded

CoDeSys SP Runtime Code Architecture


IEC User Program (Customer specific)

Call of Task Entry (or Callback)

Call using interal Library

Call ext. Lib

Internal IEC-Library (3S or customer specific) Call ext. Lib

External C-Library (obj File, customer specific)

Call using external Library

System C Libraries (linked with runtime, 3S)

Runtime System CoDeSys SP (3S)

External C Library (linked with runtime, Customer specific)

Operating System

Fig. 2
tech_doc_e.doc / V1.2

Embedding of the IEC user code and libraries into the runtime system

The preceding sections have given an overview of the principal functions and interactions between the individual components. In the next section the runtime system is described in more detail and the interfaces to the operating system and the I/Os are explained further.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 9 of 70

CoDeSys SP 32 Bit Embedded

The CoDeSys single tasking runtime system

The CoDeSys single tasking runtime system is implemented in ANSI-C and has already been used under various processors and operating systems (pSOS+, OS9, ...). It is also possible to run it without operating system, just with a boot loader. The interface to the surrounding (operating) system are very small. The runtime system is designed to be system-independent and guarantees fast adaptation of the CoDeSys programming system to any given PLC/IPC environment. The runtime system implements the complete functionality of a PLC cycle and enables communication with the programming system and also all debugging functions that the CoDeSys programming system supports.

3.1

Supported Services

The following services are recognised and processed by the runtime system: LOGIN (login) LOGOUT (logout) START (start controller) STOP (stop controller) RESET (reset application program warm/cold/hard) DEFINE_VARLIST (load list of variables for reading) READ_VAR (read variables) DELETE_VARLIST (delete list of variables) WRITE_VAR (write variables) FORCE_VARIABLES (write variables before and after each cycle) RELEASE_VARIABLES (delete force list) STEP_IN (stepping, step into called functions) STEP_OVER (stepping, step over called functions) BP_SET (set breakpoint) BP_DEL (delete breakpoint) BP_DEL_ALL (delete all breakpoints) READ_BP_LIST (read list of all breakpoints) READ_STATUS (read status of the controller (RUN, STOP, ..) and current processing position) READ_IDENTITY (read identity number of the application program) CALLSTACK (read call stack) CYCLE (execute one controller cycle and then stop) DEFINE_FLOW_CONTROL (the lines executed of a defined block are recorded) READ_FLOW_CONTROL (output buffer with the lines last executed)
tech_doc_e.doc / V1.2

STOP_FLOW_CONTROL (stop recording) DEFINE_TRACE (store a sampling trace description) START_TRACE (start trace recording) READ_TRACE (read out sampling trace buffer) STOP_TRACE (stop trace recording)
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 10 of 70

CoDeSys SP 32 Bit Embedded

READ_VAR_DIRECT (stateless monitoring service for reading variable values) WRITE_VAR_DIRECT (stateless monitoring service for writing variable values)

3.2

Functions of the runtime system

The individual functions of the runtime system can be assembled into 4 groups: 1. Communication: For all functions it is necessary that the development system can exchange data with the runtime system. This communication is enabled by the runtime system via various media 1 (RS232, Ethernet, CAN ). 2. Cyclic call of the PLC program: After the program has been compiled it is transferred to the controller and must then be called cyclically. Both the transfer and the call are undertaken by the runtime system. 3. Debugging: Setting and deleting of program interrupts (breakpoints), stepwise execution of a program (stepping), display of the call stack, process control (flow control), exception handling. 4. Servicing of the I/Os: Read in of the I/O data, either directly from the modules or via a driver of various field buses (e.g. CAN, Profibus, Sercos, Interbus-S). The output of I/O data takes place in the same manner. The common data interface between program and I/Os is the process map (see Figure 1). These functions must be made available by the runtime system. To guarantee this, the points cited above must be adapted to the controller hardware in question and the operating system that is being used. The necessary adaptations are described in Chapter 4. In the next section there follows a listing and description of the individual modules in the runtime system by key words; also the assignment to the individual function groups.

3.3

Modules of the runtime system system architecture


Name mainxxx.c commxxx.c codelzs.c codeman.c convert plc_com.c server.c ocdebug.c trace.c rtscopyna.c rtsevent.c real_libxxx.c rtscfg.c Contents adaptations communication driver main loop code management string and float conversion communication processing of services debugging trace packing/de-packing of messages Implements the SysLibCallback.lib Floating point arithmetic functions I/O config parser OS specific libraries Task download Scope specific specific core core core core core core core core optional core core specific specific

The CoDeSys 32 bit embedded runtime consists of the following code modules:

tech_doc_e.doc / V1.2

syslibxxx.c Interuptxxx.c

Communication via a shared memory.


Page 11 of 70

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

rtsbrows.c serverex.c

PLC browser Extended debug services

optional optional

Files of scope core must be included in the project. Files of scope specific must be adapted to the operating system and hardware environment. Files of scope optional may be included to support additional features. If you receive a new version of the runtime system from 3S, just take the core files and keep your specific files. Block archticture of the CSP32E runtime system:

The following combinations of the specific files mainxxx.x and commxxx.x exist:
Processor OS Defines to set Specific Files

Motorola 68k Motorola PPC Intel x68 Hitachi SH MIPS ARM ARM Philips LPC2294 Hitachi SH Intel 186
tech_doc_e.doc / V1.2

OS9 OS9 Win32 WindowsCE WindowsCE WindowsCE Keil Compiler Hitachi Workbench specific specific specific

OSNINE, FASTRACK Main.c, comm.c, real_lib.c MPC, OSNINE X86 SHx MIPS STRONGARM STRONGARM SHx X86, TRG_186_CPU TRICORE TRICORE MainPPC.c, comm.c, real_libMPC.c MainX86, commX86, real_libMPC.c MainSA.c commSA.c, real_libMPC.c MainSA.c commSA.c, real_libMPC.c MainSA.c commSA.c, real_libMPC.c Subdirectoy ARM7 Philips LPC2294 MainSH.c commSH.c, real_libMPC.c i186\Main186.c, i186\comm186.c, i186\real_lib186.c, i186\interupt186.c Subdirectoy TriCore TC1130, Real_libMPC.c Subdirectoy TriCore TC1796, Real_libMPC.c

Infineon TriCore Infineon TriCore

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 12 of 70

CoDeSys SP 32 Bit Embedded

If you make a adaptation for a new processor or OS, or use a combination that is not listed in the table, choose the combinations that fits best, copy the specific files and adapt them according your OS. The following picture shows the system architecture of the CSP32E runtime system:

The files can be assigned to the function groups as follows:


1. Communication:

Comm.c

Communication Level 2 (interface to the communication services of the operating system, adaptation of the communications takes place here). The file comm.c contains a sample implementation of a serial and a TCP/IP driver under the operating system OS9. XComm.c is a empty frame containing just the functions needed. Implementation examples for other environments are available in the comm<processorname>.c files. Use one of the these files for your adaptation. Part of the adaptation takes place here (and in main.c). Communication Level 4 (send and receive data). Communication Level 7 (interpret receive buffer, execution of services such as reading, writing and forcing of variables). Communication Level 7 (interpret receive buffer, execution of services such as reading, writing and forcing of variables). 32 bit version of monitoring services, extended trace capabilities (analogue trigger). Remove trace.c from the project if you use this file. Copies downloaded data to and from processor natural aligned structures. Encryption of target id.

Plc_com.c: server.c: serverex.c:


tech_doc_e.doc / V1.2

rtscopyna.c rtsenctarget.c

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 13 of 70

CoDeSys SP 32 Bit Embedded

2. Cyclic call of the PLC program:

Main.c:

Main program with initialisation of the runtime system, call of the central function ControllerCyclus() of the module Codelzs.c. Adaptation of the runtime system takes place here (and in comm.c). Adation examples are available for 68k/OS9 (main.c), PowerPC/OS9 (mainPPC.c), ARM (mainsa.c), intel x86/QNX (mainQNX.c) and intel x68/Win32 (MainWin.c) and intel x86/RT-Targer (MainWin.c). Processing control and initialisation.

Codelzs.c:
3. Debugging:

Codeman.c: OCDebug.c: Trace.c:

Routines for the management of the PLC program code. Breakpoints, stepping, call tree and flow control. Sampling trace functionality (display the history of variable values).

4. Servicing of the I/Os

Main.c:
5. I/O-Configuration

Updating of the process map.

RtsCfg.c:

Processes the downloaded data of the PLC configuration of loads them to a data structure.

6. Interupt task handling

Interupt.c:

Extension to create interrupt triggered tasks.

The individual functions within the modules are described in separate documentation. No further detail is therefore provided at this point. Only the modules and the functions that must be adapted are described in Section 4

3.4

Hardware and OS requirements

The utilized hardware has to fulfil the following minimum requirements: Only processors actually supported can be utilized (Processors where CoDeSys code generator exists) A remanent storage medium (hard disk, flash disk). The required memory consumption depends on the utilized operating system. The typical memory requirement lies at around 90 kByte for the runtime system and a maximum of 1 MB for the deposit of the IEC program code (depending on the user program). The RAM requirements depend on the configuration, i.e. on how much memory space is reserved for the IEC program codes and for data. The normal memory requirements lie between 1MB and 4MB . At least one free serial interface and/or one Ethernet link have to be available for the configuration. Timer tick milliseconds (depending on the operating system) dynamic memory management (malloc/free) is nice, but optional the runtime runs also without. Call of init routine and cyclic call of PLC code, or sleep function.
tech_doc_e.doc / V1.2

To estimate the memory size needed on the controller to run the runtime system and application program, these figures can be a help. The runtime was compiled with the Microware Hawk compiler for 68k (, which is comparable to the ColdFire processor). Runtime system Code Size: 90k (including debug information) 64k (without debug information) Runtime system Data Size (Static):
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

32k
Page 14 of 70

CoDeSys SP 32 Bit Embedded

The runtime also uses some dynamically allocated memory for download of the plc configuration. Typical size: less than 5k

Download of the task configuration (needed only if you want to use the optional interrupt task extension). Typical size: less than 1k

The Data Size for the application program depends on the application. The runtime system needs memory space for application data, and it needs 2 buffers for application code. The second code buffer is used for the online change feature. Assuming the application program needs 64k of code and 64k of data, we need the following memory on the controller: RAM Memory: 192k

The runtime system stores some information in a file system. The file system can be a real file system, or it can be based on flash memory. The most important file that has to be stored is the boot project. It is about the same size as the downloaded code. Non-volatile memory (Flash, File System): 64k

The application program may contain retentive data; these are variables declared with the RETAIN keyword. Retain data is normally stored in buffered RAM. If this is not available, it can also be stored in Flash memory. The size depends on the application program. Non-volatile memory (buffered RAM): Typical size: 16k

If you want to use additional features like source code download, additional disc or flash space is needed. The zipped source code file is about the size of the downloaded code (in our example 64k).

3.5
3.5.1

Functionality in detail
Processing control

To initialise the modules of the CoDeSys runtime system correctly, the function main in the module main.c contains at the beginning some initialisation function calls. Processing of the controller cycle then follows in an endless loop. Controller cycle: Read inputs Call ControllerCyclus (controller cycle) Erite outputs The function "ControllerCyclus" (ControllerCycle) is located in the module codelzs.c and executes the following: ControllerCycle execute user service if Application program is running reset CallTree if Flow Control
tech_doc_e.doc / V1.2

reset Flow Control if Force List is defined write variable from Force List execute Application Program if Force List is defined write variable from Force List
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 15 of 70

CoDeSys SP 32 Bit Embedded

if Sampling Trace is running write into the Trace Buffer

3.5.2

Processing of services

The decoding of the incoming services is undertaken by the function SrvComputeService() in the module server.c. The type of operation is coded in a byte. If the controller system has initiated a service, it waits for a confirmation that the service has been executed. The runtime system must also send a response immediately regarding each service. The response consists in each case of a 2 byte error number. According to the service in question response data can then follow. Simple services are processed directly in the function. To handle more complicated services other functions are called. The format of important services is described in the following chapters. 3.5.2.1 Login

Connecting with the runtime system. Query sent by CoDeSys V 2.3 SP2:
Structure of a service Offset Size [Bytes] Description

byCommand = RTS_LOGIN (0x01)

Service for connection

Query sent by CoDeSys V 2.3 SP3 and newer: Structure LOGIN_TYPE in RtsSrv.h
Structure of the service Offset Size [Bytes] Description

byCommand = RTS_LOGIN (0x01) dwApplicationType

0 1

1 4

Service for building up the connection Application type of the Client: APPLTYPE_VISUALIZATION APPLTYPE_OPC_SERVER

1 2

APPLTYPE_CUSTOM_APPLICATION 3 APPLTYPE_PROGRAMMING_SYSTEM 4 dwAccessMode 5 4 Desired access type: ACCESS_READ_ONLY ACCESS_READ_WRITE ACCESS_FORCE_VARIABLES ACCESS_DEBUGGING ACCESS_SYSTEM_CONFIG ACCESS_ALL ulPasswordLength
tech_doc_e.doc / V1.2

1 2 3 4 5 6

9 13

4 N

Length of the succeeding password, if none is succeeding, Length = 0 Password (optional), if a password was issued on the controller

szPassword

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 16 of 70

CoDeSys SP 32 Bit Embedded

Answer: Structure LZS_METRICS in RtsGlb.h


Structure of the answer Offset Size [Bytes] Description

wTest = TEST_MESSAGE ( = 0x03E8 = 1000) dwVersion DwFlags ulSizeBuffer ulSizeTrace ulSizeVar

0 2 6 14 18 22

2 4 8 4 4 4

Answer to the login service. Version of the subsequent structure Reserved flags for a backward compatibility Size of the communication buffer Size of the trace buffer Size of the variable buffer (Buffer, which is reserved for the monitoring variables for CoDeSys) Size of the force buffer Currently set maximum number of POUs in an IEC program (is adjusted automatically with each download) Maximum number of possible breakpoints in CoDeSys Maximum stack depth in the stack hierarchy Maximum number of possible flow positions (for flow control) Maximum number of possible trace variables Version of the runtime system: z.B. V1.100 = 1100

ulSizeForce ulMaxPOUs

26 30

4 4

ulMaxBPs ulMaxStackDepth ulMaxFlow ulMaxTraceDev dwRtsVersion

34 38 42 46 50

4 4 4 4 4

dwProcessor

54

Type of processor: CPU_INTEL_X86 0x00010001

CPU_INTEL_STRONGARM 0x00010002 CPU_MOTOROLA_PPC 0x00030001 SzOS 58 32 Operating system: OS_WIN32 OS_VXWORKS OS_LINUX OS_QNX "Windows" "VxWorks" "Linux" "QNX"

OS_RTKERNEL32 "RTKernel-32" szOSVersion


tech_doc_e.doc / V1.2

80

32

Version of the operating system as a string, e.g. for Windows-CE 3.0 = CE 3.0 Name of the manufacturer of the controller (can be set in the custom module) Data which can be overloaded according to customers specifications:
Page 17 of 70

szVendor

112

32

CstMetrics Struktur:

144

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

ulSizeRetain ulRetainCycleTime sRetainSaveTyp

144 148 152

4 4 2

Size of the retain memory Cycle times for saving retain variables cyclically Settings of the retain memory principle: CST_RETAIN_NONE 0

CST_RETAIN_ONPOWERFAIL 1 CST_RETAIN_CYCLIC CST_RETAIN_TASK CST_RETAIN_DIRECT ulFileNumberOfBlocks ulFileBlockSize bWatchdogEnable 154 158 162 4 4 1 2 4 8

Number of available memory blocks for customized file access File block size for customized file access Activating the software watchdog: Switch on Switch off 1 0

ulWatchDogInterval ulWatchDogCycleTime

163 167

4 4

Interval of the software watchdog Interval in which a connected hardware watchdog is triggered (Watchdog must be connected in the custom part) Settings of the file system: CST_FILESYSTEM_BLOCK block file system 1

sFileSystem

171

CST_FILESYSTEM_CUSTOM 2 Access to files can be programmed in the custom part CST_FILESYSTEM_SYSTEM 3 Standard file system of the operating systems is used byIECBasePriority BBasicIO ulSizeInput ulSizeOutput ulSizeMemory ulSizeCode ulSizeData 173 174 175 179 183 187 191 1 1 4 4 4 4 4 1 Basic priority of the IEC task with the highest priority Setting of the IO driver Size of the input areas Size of the output area Size of the flag area Size of the IEC program memory Size of the IEC data memory Setting whether set memory sizes can be adapted to the loaded program dynamically Switch to switch off the loading of the boot project If value is 0, all the outputs are assigned the value of bOutputValue on stop = 0, outputs are set on 0 on stop = 1, outputs are set on 1 on stop
Page 18 of 70

bCodeAndDataSizeDynamic 195

tech_doc_e.doc / V1.2

bNoBootProject bOutputForce bOutputValue

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

3.5.2.2

Logout

Disconnecting. Query:
Structure of a service Offset Size [Bytes] Description

RTS_LOGOUT (0x02) Answer:


Structure of a service

Service for disconnection

Offset

Size [Bytes]

Description

RTS_OK (0x0000)

OK acknowledgement

3.5.2.3

Start

Starting all IEC tasks. Query:


Structure of a service Offset Size [Bytes] Description

RTS_START (0x03) Answer:


Structure of a service

Starting the PLC.

Offset

Size [Bytes]

Description

RTS_OK (0x0000)

OK Acknowledgement

3.5.2.4

Stop

Stopping all IEC tasks. Query:


Structure of a service Offset Size [Bytes] Description

RTS_STOP Answer:
Structure of a service

Stop PLC

Offset

Size [Bytes]

Description

RTS_OK (0x0000)

OK Acknowledgement

3.5.2.5

Reading, writing and forcing of variables

The functions that these services execute are: WORD void SrvReadVarList() SrvWriteVarList(char *WriteList)

They are located in the module server.c. The generated code contains a function GetAddress that supplies to each block the starting address regarding its data region. Inputs, outputs, flags region and global data region have their own block numbers. A pointer to the instance that is currently being processed is supplied for the function blocks. If the processing is not taking place in this function block, the function supplies ZERO. To enable a cycle-consistent reading of several variables, a list of variables to be read can be sent to the controller. To keep a read cycle as short as possible, a list of variables is sent to the controller using the service Define Read and stored there. If reading is to take place, the service Read Variables is sent to the controller. There the defined variables are read and the values are sent to the
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 19 of 70

tech_doc_e.doc / V1.2

CoDeSys SP 32 Bit Embedded

programming system. To release the list in the controller once again, a service End Read is sent, that renders the defined list invalid. The configuration of the variables list is as follows: 1 byte Service ID 1 byte No. of elements 2 bytes 2 bytes 2 bytes Size ...... ...... 2 bytes 2 bytes 2 bytes Size

POU Ref Offset 1

POU Ref n Offset

Bits have the size 0. If the size is 0, the offset is calculated as a bit offset, otherwise as a byte offset. A list is similarly transferred for the writing of variables. All variables in the list are written so as to be cycle-consistent. The writing list looks like the above variable list, except that each size byte is followed by the corresponding number of bytes that are to be written. To be able also to write individual bits, one data byte follows after the size = 0. The read values are simply written one after another in a buffer that can then be interpreted in the programming system using the read list. To be able to force variables, the write list is stored in the controller. The variables of this list are set to the corresponding values before and after each loop of the application program. 3.5.2.6 Download of the Task-Configuration

This service downloads the task configuration. Query:


Structure of a service Offset Size [bytes] Description

RTS_DOWNLOAD_TASK CFG (55) ByTasks ByTaskNr ByPriority Linterval POURef

0 1 2 3 4 8

1 1 1 1 4 2

Service for download of task configuration Number of tasks Index of the first task Priority (0-31) Interval in milliseconds Segment number of the event-variable. Is 1 (or 0xFFFF), if no event was configured for this task. Offset of the event-variable. Size of the event-variable. POU-Index of task-POU. Length of the task name, including the terminating \0-character. The length is rounded up to the next even number. Task name as zero-terminated string Description of the next task (starting at byTaskNr).

Offset Size Windex ulNameLen

10 14 18 20

4 4 2 4

SzName

24

ulNameLen

24 + ulNameLen uiNameL en
tech_doc_e.doc / V1.2

Answer:
Structure of the answer Offset Size [bytes] Description

Wreply

RTS_OK

0x0000

Positive acknowledge, if tasks could be loaded successfully


3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 20 of 70

CoDeSys SP 32 Bit Embedded

3.5.2.7

Stateless monitoring of variables (LZS_READ_VAR_DIRECT)

Reading values of variables. This service does not need a buffer with registered values. Variable definitions are downloaded with every message. This allows multiple client to monitor variable values at the same time. Query:
Structure of a service Offset Size [bytes] Description

RTS_READ_VAR_DIREC T (46) Dummy ulCount POURef Offset Size POURef Offset Size Answer:
Structure of a service

0 1 2 6 8 12 16 18 22 26

1 1 4 2 4 4 2 4 4

Service id Dummy byte Number of variable definitions Reference number of data segment for var 1 Offset inside data segment for var 1 Size of variable for var 1 Reference number of data segment for var 2 Offset inside data segment for var 2 Size of variable for var 2 POURef, Offset, Size for following definitions

Offset

Size [bytes]

Description

RTS_OK (0x0000) ulTimeStamp bQuality Value bQuality Value

0 2 6 7 7+Size1

2 4 1 Size 1

OK Acknowledgement Timestamp in microseconds Quality indicator: 1 = ok, 0 = error for var 1 Variable value, size according definition for var 1 Quality indicator: 1 = ok, 0 = error for var 2 Variable value, size according definition for var2 Quality and Value for following variables

7+Size1+ Size 1

The memory of the user program data is divided into segments. Variables with memory addresses (%M) are in segment 0, variables with input addresses (%I) are in segment 1, variables with output addresses (%Q) are in segment 2. If the option retain in own segment is active, retain variables are in segment 3, and global and pou local variables without direct address are in the following segments, starting with segment 4. If the option is off, they start at segment 3. For segment number, also the word POURef can be used. The dataref of a variable, consisting of POUref, Offset and size can be read from the symbol file (symbol data base *.sdb). This file is generated during compile of a project if the appropriate option is set.
tech_doc_e.doc / V1.2

Note: Size is 0 for Bit variables (for example %MX0.0). In this case, the offset is a bit offset. The value is stored in one byte. In normal cases, offset is a byte offset, and the size is given in bytes. Special codes for POURef are defined for extended monitoring features: #define MON_ABSOLUTEADDRESS Used for monitoring of memory addresses. 0xFFFF

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 21 of 70

CoDeSys SP 32 Bit Embedded

MON_ABSOLUTEADDRESS nDescSize nSize ulAddress

X+0 2 4 8

2 2 4 4

Type of monitoring Size of description Size of variable Address of variable in memory

#define MON_CONSTANT Used for monitoring of constant values. MON_CONSTANT nDescSize nSize Constant Value X+0 2 4 8 2 2 4

0xFFFE

Type of monitoring Size of description Size of variable Constant value to monitor

nSize

#define MON_COMPONENT Used for monitoring of structure components. MON_COMPONENT nDescSize NSize ulOffset POURef Offset Size X+0 2 4 8 12 14 18 2 2 4 4 2 4 4

0xFFFD

Type of monitoring Size of description Size of variable Offset within structure Reference number of data segment of structure Offset inside data segment of structure Size of variable of structure

#define MON_POINTER

0xFFFC

Used for monitoring of the content of pointer variables. MON_POINTER nDescSize Nsize POURef Offset Size X+0 2 4 8 10 14 2 2 4 2 4 4 Type of monitoring Size of description Size of variable Reference number of data segment of pointer Offset inside data segment of pointer Size of variable of pointer

#define MON_BITACCESS Used for monitoring of bit accesses.


tech_doc_e.doc / V1.2

0xFFFB

MON_COMPONENT nDescSize Nsize usBitOffset POURef

X+0 2 4 8 12

2 2 4 4 2

Type of monitoring Size of description Size of variable Bit-Offset within variable Reference number of data segment of variable
Page 22 of 70

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

Offset Size

14 18

4 4

Offset inside data segment of variable Size of variable of variable

#define MON_ARRAYACCESS

0xFFF9

Used for monitoring of array accesses with variable index. MON_ARRAYACCESS nDescSize nSize usDimensions ulDimSize[1] ulDimSize[2] ulLowerBounds[0] ulLowerBounds[1] ulLowerBounds[2] X+0 2 4 8 10 14 18 12 16 2 2 4 2 4 4 4 4 4 Type of monitoring Size of description Size of variable, contains number of Elements for dimension 0 Count of Dimensions of the arrays, maximum 3 Count of elements for dimension 1 (only if usDimensions > 1) Count of elements for dimension 1 (only if usDimensions > 2) Lower bound for dimension 0 Lower bound for dimension 1 (only if usDimensions > 1) Lower bound for dimension 2 (only if usDimensions > 2)

3.5.2.8

Stateless writing of variables (LZS_WRITE_VAR_DIRECT)

Writing values of variables. This service does not need a buffer with registered values. Variable definitions are downloaded with every message. Query:
Structure of a service Offset Size [bytes] Description

RTS_WRITE_VAR_DIRE CT (60) Dummy ulCount POURef Offset Size Value Answer:


tech_doc_e.doc / V1.2

0 1 2 6 8 12 16 26

1 1 4 2 4 4 Size

Service id Dummy byte Number of variable definitions Reference number of data segment for var 1 Offset inside data segment for var 1 Size of variable for var 1 Value to write for var 1 POURef, Offset, Size for following definitions

RTS_OK (0x0000)

OK Acknowledgement

See also the comments for the LZS_READ_VAR_DIRECT message.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 23 of 70

CoDeSys SP 32 Bit Embedded

3.5.2.9

PLC Browser commands (RTS_BROWSERCOMMAND)

Sends a PLC Browser command string to the runtime. The answer message contains the answer string. Query:
Structure of a service Offset Size [bytes] Description

RTS_BROWSERCOMMA ND (146) SubCommand iBlockNr pszCommand Answer:


Structure of a service

0 1 3 5

1 2 2 n

Service id PLC_SUB_COMMAND, PLC_SUB_ABBORT or PLC_SUB_SENDNEXT Block number Zero-terminated command string

Offset

Size [bytes]

Description

RTS_OK (0x0000) 0 SubCommand iBlockNr pszAnswer

0 2

2 1

OK Acknowledgement Dummy byte PLC_SUB_LAST or PLC_SUB_FOLLOWINGS

2 4

2 n

Block number Zero-terminated answer string

A new PLC browser command is sent with the SubCommand PLC_SUB_COMMAND followed by the command string. PLC_SUB_ABBORT is used if a multiblock command is aborted by the user. It the answer text is short enougth to be sent in one block, the SubCommand of the answer message is set to PLC_SUB_LAST. If the answer text is longer, the SubCommand of the answer message is set to PLC_SUB_FOLLOWINGS to indicate that more blocks follow. In the last block of the multiblockanswer message , the SubCommand is set to PLC_SUB_LAST. The Block number is increased with every block. 3.5.2.10 Reading Project Info of Boot Project This service can be used to read the project information from the boot project. The runtime opens the DEFAULT.PRG and read the project info section. Query:
Structure of a service Offset Size [bytes] Description

LZS_READ_BOOTPRJ_INFO (84) 0 Answer:


Structure of a service Offset

Service id

Size [bytes]

Description

RTS_OK (0x0000)
tech_doc_e.doc / V1.2

0 2 6

2 4 Strlen+ 1 Strlen+ 1

OK Acknowledgement Creation data of the boot project Zero-Terminated string, contains the project name Zero-Terminated string, contains the project title
Page 24 of 70

dwDate SzProject SzTitle

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

szVersion SzAuthor szDescription

Strlen+ 1 Strlen+ 1 Strlen+ 1

Zero-Terminated string, contains the project version Zero-Terminated string, contains the project author Zero-Terminated string, contains the project description as entered in the project information dialog of CoDeSys

3.5.2.11 Write file to PLC Files are transferred block by block. The first block contains service RTS_FILE_WRITE_START with an extended header, followed by RTS_FILE_WRITE_CONT. Request, first block:
Structure of the service Offset Size [Bytes] Description

RTS_FILE_WRITE_START (47) bContinue uCount uFileNameLen pszFileName Data Answer:


Structure of the answer

0 1 2 4 6 6+n

1 1 2 2 n uCount

Start of a file download Indicates whether this ist the last block (1: last block, 0: Block will follow) Number of data bytes Length of file name, in Bytes Name of the file, zero-terminated string Content of file, first block

Offset

Size [Bytes]

Description

WReply

RTS_OK 0x0000 If block could be written SRV_FILE_ERROR 0x0050 If file could not be written

Request, subsequent blocks:


Structure of the service Offset Size [Bytes] Description

RTS_FILE_WRITE_CONT (48) bContinue uCount Data Answer:


Structure of the answer

0 1 2 4

1 1 2 uCount

Continuation of a file download Indicates whether this ist the last block (1: last block, 0: Block will follow) Number of data bytes Content of file, subsequent block

Offset

Size [Bytes]

Description

tech_doc_e.doc / V1.2

Wreply

RTS_OK 0x0000 If block could be written SRV_FILE_ERROR 0x0050 If file could not be written

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 25 of 70

CoDeSys SP 32 Bit Embedded

3.5.2.12 Read file from PLC Files get transferred block by block. The first block contains service RTS_FILE_READ_START with an extended header, followed by RTS_FILE_READ_CONT. Request, first block:
Structure of the service Offset Size [Bytes] Description

RTS_FILE_READ_START (49) bDummy uFileNameLen pszFileName Answer:


Structure of the answer

0 1 4 6

1 1 2 n

Start of file upload Not used Length of file name, in Bytes Name of the file, zero-terminated string

Offset

Size [Bytes]

Description

wReply

RTS_OK 0x0000 If block could be read SRV_FILE_ERROR 0x0050 If file could not be read

wContinue uCount Data Request, subsequent blocks:


Structure of the service

2 4 6

2 2 uCount

Indicates whether a further block will follow (1: Block will follow, 0: this is the last block) Number of data in this block, in Bytes Content of the file, first block

Offset

Size [Bytes]

Description

RTS_FILE_READ_CONT (50) Answer:


Structure of the answer

Continuation of a file download

Offset

Size [Bytes]

Description

wReply

RTS_OK 0x0000 If block could be read. SRV_FILE_ERROR 0x0050 If file could not be read.

wContinue uCount Data

2 4 6

2 2 uCount

Indicates whether a further block will follow (1: Block will follow, 0: this is the last block) Number of data in this block, in Bytes Content of the file, first block

tech_doc_e.doc / V1.2

3.5.3

Debugging

When a breakpoint is set in the PLC program a subprogram call is inserted by the runtime system at the appropriate location in the program code. The subprogram call branches off into the routine for the handling of breakpoints. If a breakpoint is reached, the controller runs from that point onwards in debugging mode, i.e. it runs in a waiting loop of the server, until a Run service repositions it back into the normal state.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 26 of 70

CoDeSys SP 32 Bit Embedded

Sequence when a breakpoint is reached: The program runs on the patched-in code and calls the function CoDeSysBP in the module main.c; in turn this function calls SrvDebugLoop. SrvDebugLoop calls the server in a loop. The server executes the incoming services quite normally. If the controller is once again in a run state, it goes back to the debugger. The latter hands back control to the application program. void SrvDebugLoop() /* This function is called by the debugger if the controller is running in step mode or a breakpoint has been reached. */ { /* While stepping the I/Os are updated */ UpdateIO(); while (ControllerStatus == STOP_BP) { DrvReceiveMessage(); } UpdateIO(); return; }

3.5.4
3.5.4.1

Downloading of programs
Loading of the application program

The loading of a program signifies the overwriting of the current application program with a new program. Since the whole of the application program cannot be written into the receive buffer, this service must be recognised at communication level 2. The incoming data are then written directly into the code memory. The download of the user application consists of several services containing (among others) the compiled code, task configuration and hardware configuration. The services are sent in the following order: LZS_GL_DOWNLOAD (resp. LZS_DOWNLOAD) LZS_DOWNLOAD_TASKCFG LZS_DLACCESSLIST LZS_DLTASKACCESSLIST LZS_DOWNLOAD_PRJINFO LZS_DEFINE_CONFIG Compiled code Task configuration Optional: Access variables list Optional: Task access list Project information Hardware configuration

For a online change, the services are sent in the following order: LZS_GL_DOWNLOAD (resp. LZS_DOWNLOAD) LZS_DOWNLOAD_PRJINFO
tech_doc_e.doc / V1.2

Compiled code Project information

If the used makes changed in the task configuration or the hardware configuration, a complete download is performed. This means that these services are never sent with a online change.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 27 of 70

CoDeSys SP 32 Bit Embedded

3.5.4.2

Linking of the application program

Apart from the application program the CoDeSys runtime system can be loaded into the ROM. A modified application program is then compiled on the PC and linked with the libraries and loaded into the controller. The linking in the controller then takes place dynamically via function pointers. In order that dynamic linking may be possible, the function CodeInit from the application program must be recognised by the runtime system. The dynamic linking between runtime system and application program takes place in the initialisation phase. CodeInit is called in the function InitProgram() of the module codelzs.c. A pointer is passed to this function to the PLC_CONF_TAB structure (defined in anchor.h). In this structure the pointers to the process map for the inputs and outputs are allocated. The PLC_CONF_TAB structure forms the (only) interface between the runtime system and the application program. In this structure are entered the pointers to all functions that serve as interface functions between the runtime system sitting in the ROM and the application program. The following functions must be identified: From the application program: void PLC_PRG(void); long GetIdentity(void); void GlobalInit(char); From the runtime system: unsigned long pGetTime(void); supplies the system time in ms. main function of the application program supplies an identification number of the application program

char *GetAddress(unsigned short); supplies the address to a data object initialises the data of the application program

3.5.5

Sampling Trace

The functions for implementation of the sampling trace are located in the module trace.c. If a trace is defined, the values of the defined variables are written into a ring buffer at the end of each cycle and the write pointer (tbIndex) is incremented by the number of written bytes. If the buffer is full, the write pointer is reset to the start of the buffer. When the Boolean variable TraceEvent has the edge specified in wRising, then exactly wAfterEvent times will be written. The trace afterwards stops. The functions are: WORD TrcDefine(BYTE *pbyBuffer); /* Scans the Receive Buffer and stores the definition of the Sampling Trace in the structure TRACE_DEF */ WORD TrcStart(); /* Starts the recording of the Trace */ void TrcFill(); /* Executes a Write Cycle. The values of all the variables defined in Tracevar are, if the necessary wScanTime time has elapsed since the last write, written into the Trace Buffer. Checks whether the condition for ending the Write is fulfilled. */
tech_doc_e.doc / V1.2

WORD TrcWrite(BYTE *pbyBuffer, int *iSize); /* Writes the Trace Buffer into the Send Buffer. Supplies the current state of processing of the Trace. */ void TrcStop(); /* Executes a user defined stop of the Trace. */

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 28 of 70

CoDeSys SP 32 Bit Embedded

3.5.6

Flow Control

For the Flow Control expanded code is produced for the selected block in the development system. This is loaded into the controller. There this code is called instead of the normal block. The expanded code fills a buffer with information that is used by the development system to display breakpoint positions that have been reached.

3.5.7

Call Stack

The block calls that have taken place are carried in a call stack starting from PLC_PRG. This call stack can be read out from the programming system.

3.6

Scaling the runtime system

Using preprocessor defines, the runtime system can be scaled in means of size versus functionality. The following flags are available: PLCBROWSE INCLUDE_SOCKETS EXT_SERVICES INCLUDE_DRV_ROUTE EXCLUDE_CONFIG EXCLUDE_DEBUG SM INCLUDE_PASSWORD INCLUDE_PERSISTENT INCLUDE_OD NO_SYSLIBTIME NO_PORTS NO_SHM NO_FILES NO_REALS EXCLUDE_TRACE EXCLUDE_ONLINECHANGE INCLUDE_EVENTS CODE_IN_FLASH PROJECTINFO_IN_FLASH enable the plc browser include the socket library functions enable extended 32 bit online services enable the routing driver as second channel, needed for webserver disable interpretation of hw configuration download disable breakpoints enable the CoDeSys SoftMotion functionality enable the password functionality enable the feature VAR PERSISTENT enable the OD download services exclude the SysLibTime-functions exclude the SysLibPort-functions exclude the SysLibShm-functions exclude the SysLibFile-functions exclude the help functions for float operations disable trace disable online change enable the event callback mechanism store and execute code in flash memory store projectinformation in flash memory

The following flags are for additional features: USR_TARGETVISU_ENABLE enable Targetvisualisation SAFETYMODE_ENABLE
tech_doc_e.doc / V1.2

enable safety mode

Set these flags in your compilers preprocessor environment. For a 68k system, the following code sizes can be expected: PLCBROWSE, INCLUDE_SOCKETS, EXT_SERVICES, INCLUDE_DRV_ROUTE: No define set EXCLUDE_CONFIG EXCLUDE_CONFIG, EXCLUDE_DEBUG
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

89k 78k 71k 59k


Page 29 of 70

CoDeSys SP 32 Bit Embedded

3.7

Format of the bootproject file (DEFAULT.PRG)

The file is dumped in 4-byte aligned format to be easily interpreted on various hardware platforms. The byte order is according the target platform. When loading the boot project, the runtime system checks the consistency of the file. Therefore it uses a checksum file. The checksum file is generated by the runtime system after creating the boot project. The checksum file contains the checksum as a unsigned long value. It is calculated by adding all bytes of the bootproject file as unsigned chars. The bootproject file consists of: <Header> <Code> <Task configuration> <Hardware configuration> <IO description> <Project Info>

3.7.1

Header

The header consists of: struct PrgHeader { ULONG ulVersion; ULONG ulPrgSize; ULONG ulTaskSize; ULONG ulConfigSize; ULONG ulIOSize; ULONG ulInfoSize; };

// currently 2

// Since version 1 // Since version 2

3.7.2

Code

Compiled user code. Has to be copied into CodeArea0. Then run the same procedures like after a download service: SrvDownload(LZS_GL_DOWNLOAD, TRUE, ulPrgSize).

3.7.3

Task configuration

Task configuration as defined for service LZS_DOWNLOAD_TASKCFG.

3.7.4

Hardware configuration

Hardware configuration as defined for service LZS_DOWNLOAD_IODESC. The format is described in the document Steuerungskonfiguration_CoDeSys_22_D.pdf resp. PLC_Configuration_CoDeSys22_E.pdf.

3.7.5

IO description

Task specific IO-description (not used in embedded runtime).

3.7.6
tech_doc_e.doc / V1.2

Project Info

Project information as defined for service LZS_DOWNLOAD_PRJINFO. It consists of: struct ProjectInfo { ULONG dwDate; char szProjectName[];
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 30 of 70

CoDeSys SP 32 Bit Embedded

char char char char };

szTitle[]; szVersion[]; szAuthor[]; szDescription[];

Each String is zero-terminated and immediately followed by the next string.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 31 of 70

CoDeSys SP 32 Bit Embedded

Adapting the runtime system

The runtime system can be adapted to any operating system environment. For some environments, it already contains specific adaptations: For 68000 processors and the operating system OS9 and the Microware Hawk-Compiler, a readyto-use adaptation is included. Define the FASTRACK and OSNINE compiler switches to enable this feature. Microware assembler notation and parameter passing conventions will be used. The PARA compiler switch is automatically set. If you use 68000 processors with the Microtec compiler, set the MICROTEC compiler switch. Microtec assembly notation will be used. For other 68000 or ColdFire processor environments, dont define any of these compiler switches. Check main.c for adaptations. For Power PC environments and the operating system OS9 and the Microware Hawk-Compiler, set the OSNINE and the MPC compiler switches. The runtime system has run on a MPC555 board, for example. Use the real_libMPC.c and real_libMPC.h files instead of real_lib.c and real_lib.h to support LREAL trigonometric functions. Use MainPPC.c and commPPC.c instead of main.c and comm.c. For Intel x86 Processors, set the X86 compiler switch. The runtime system has been adapted to Windows NT, RT-Target and QNX, so far. Use mainWin.c and commWin.c istead of main.c and comm.c. For ARM Processors, set the STRONGARM compiler switch. Use mainsa.c and commsa.c instead of main.c and comm.c, or the contents of the ARM Philips LPC2294 subdirectory. For Infineon TriCore Processors, set the TRICORE compiler switch. Use the contents of the subdirectory TriCore TC1130 or TriCore TC1796 instead of main.c and comm.c. Use Real_libMPC.c. Eventually, the workspace has to be adapted to your directory structure (or copy the runtime core *.h and *.c files to the h_3S and src_3s subdirectory).

Follow these steps to do an adaptation: Compile the C-Files with your target compiler Adapt the Step 1 issues Run the runtime system on your hardware and test it with the CoDeSys programming system Adapt the other issues as needed.

If you already have a runtime compatible to CoDeSys 2.1 or lower, and want to make it compatible to the CoDeSys 2.2 programming environment, all you have to do in the first step is to include the target id check service to your runtime. Follow chapter 4.4 Setting the Automation Alliance target id. All program elements of the runtime system that must be adapted to the environment are assembled in the two modules main.c and comm.c (mainPPC.c, mainsa.c, mainx86.c resp.). Here are located all the functions that must be adapted to the operating system, C compiler, storage model and I/O map being used. In the header file custom.h definitions like data and code memory size can be made. Between the runtime system and the operating system or between the runtime system and the inputs and outputs there exist the following interfaces: Communication interface (Step 1): The operating system must enable communications via a serial interface or a network with the development system. The driver for the interface (Comm.c) must be adapted to the operating system. Comm.c contains as an example a serial and a TCP/IP driver for the OS 9 operating system. Xcomm.c contains a frame with the empty interface functions. Storage model (Step 1): Only to be implemented in Step 1, if no dynamic memory management (malloc, free) is available. Management of the memory necessary for the execution of the PLC program.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 32 of 70

CoDeSys SP 32 Bit Embedded

Timer interface (Step 1): Interrogation of the system time for the implementation of timer blocks in a PLC program. Setting the Automation Alliance target id (Step 1): The target id is checked by the programming system at login. Interface to I/Os process map: Hardware accesses to inputs and outputs or via special drivers. Debugging interface: Mechanism for implementation of breakpoints in the controller. Adaptation to a C compiler (Step 1): Adaptation to the calling conventions of the C compiler being used. Additional server services: Optional further services of the runtime system. Time behaviour and integration into multi-tasking operating systems: Division of the runtime system into an initialisation part and a cyclic part. Libraries: Integration of the IEC standard library and other libraries. Retain Data: Saving data declared as VAR RETAIN to retentive memory. File System functions: Allow the user to access the file system or flash memory. Needed to store the boot project. The boot project is needed to restart the application after power down. Interrupt tasks: An extension to define tasks that run independently from the PLC cycle. These tasks can be triggered by an interrupt that is more frequent than the PLC cycle. The comment Step 1 signifies that these items must be adapted in all circumstances. The other items are optional. These interfaces must now be adapted not only to the operating system but also to the configuration of the controller. The necessary adaptations are described in the following sections.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 33 of 70

CoDeSys SP 32 Bit Embedded

4.1

The communication interface

In this section the principal mode of operation of the communications is firstly explained, before the steps to adaptation of the communications are described in section 4.1.4. The driver in Comm.c and Plc_com.c implements the Level 2 and Level 4 communication with the programming system. Incoming messages are received in blocks of the size BLOCK_SIZE (default of 128 bytes). After a block has been transferred, an acknowledgement message (receipt) must be sent. If all blocks of a message have been received, this message is forwarded to the server. The server processes a service and sends the result back to the driver. The latter divides the send message once again into blocks of 128 bytes and sends all blocks via the serial interface to the programming system.

4.1.1

Block-wise transfer of messages

For the transfer at Level 2 blocks are transferred with a maximum of 128 data bytes (without header). Each block has a block header with the following configuration: typedef struct { WORD wBlockIdentification; /* must be 0xAAAA */ WORD wBlockSize; /* number of data bytes */ WORD wBlockNumber; /* serial number of blocks belonging to one message. begins with 1)!! */ BYTE byCheckSum; /* checksum over data and header, the checksum being set to 0 for the analysis */ BYTE byLastBlock; /* 0: further blocks follow 1: this message is complete */ }LZS_BLOCK_HEADER; Each received block must be receipted with an acknowledgement (6 bytes). An acknowledgement comprises: 2 bytes acknowledgement identifier, (0x5555). 2 bytes acknowledgement identifier (POS_ACKN (0x000A), NEG_ACKN (0x0014)). 2 bytes number of the block, whose receipt is being confirmed (byBlockNumber). If a complete message has been transferred and correctly receipted, a further acknowledgement is sent from the sender. This acknowledgement signals readiness to receive. Example: A service is sent in two blocks to the controller; the response similarly comprises two blocks. The following messages are sent: Control panel Send 1 block Send acknowledgement of first block (block number 1) Send 2 block
tech_doc_e.doc / V1.2
nd st

Controller

Send acknowledgement of second block (block number 2) Send service acknowledgement (block number 0) Send 1 block Send acknowledgement of 1 block (block number 1)
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 34 of 70
st st

CoDeSys SP 32 Bit Embedded

Send 2 block Send acknowledgement of 2 block (block number 2) Send service acknowledgement (block number 0) In this manner the programming system after execution of the service is again ready to send and the controller is ready to receive.
nd

nd

4.1.2

Message configuration

A message to the controller always comprises one byte with the service ID that uniquely identifies the service. For many services such as login, logout, start, stop it is not necessary to transfer any further data other than the service ID. As a response an error number is always sent in the first two bytes by the runtime system. This error number is LZS_OK, if no error has occurred. At the start of each communication a login service must always be sent to the controller. This login service has for example the following communication sequence (service ID for login = 0x01):
Run-time system

CoDeSys

Development system Send login service (1 data byte): 0xAA, 0xAA, 0x01, 0x00, 0x01, 0x00, 0x58, 0x01, 0x01

Runtime system

Send acknowledgement of first block: 0x55, 0x55, 0x0A, 0x00, 0x01, 0x00 Send service acknowledgement 0x55, 0x55, 0x0A, 0x00, 0x00, 0x00 Send response (1 data byte): 0xAA, 0xAA, 0x02, 0x00, 0x01, 0x00, 0x56, 0x01, 0xFF, 0x00 Send acknowledgement of 1 block: 0x55, 0x55, 0x0A, 0x00, 0x01, 0x00 Send service acknowledgement 0x55, 0x55, 0x0A, 0x00, 0x00, 0x00
st

The decoding of the incoming services is undertaken by the function SrvComputeService() in the module server.c.
tech_doc_e.doc / V1.2

If the development system has initiated a service, it waits for a confirmation that the service has been executed. The runtime system must also send a response immediately regarding each service. The response consists in each case of a 2 byte error number. According to the service additional response data follow.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 35 of 70

CoDeSys SP 32 Bit Embedded

4.1.3

Communication

For communications all necessary functions are held in the module Plc_com.c. The module Plc_com.c possesses the following six interface functions. In general it is not necessary for these functions to be adapted and they are presented here only for the sake of completeness. void DrvInit(BOOL bOpenCom); Initialises all global variables and opens the serial interface if bOpenCom == TRUE. void DrvReceiveMessage(void); This function is called once per cycle. It reads in the received characters and calls the function DrvReadMessage() when a complete block has been transferred. If the function answers by TRUE, a complete message has entered. Thereafter the server with the received message is called. BOOL DrvReadMessage(void); This function tests whether a valid block has been received. If the block is valid a positive response is sent back to the development system and the block is written into a receive buffer. This now takes place for each block until a message is complete. Following that a TRUE message is returned. BOOL DrvWriteMessage(void); This function sends a requested message to the development system. This transfer is requested from the server using the flag MessageSend == TRUE. The function interrogates all return messages and resets this flag if it has been possible to transfer the message correctly to the development system. WORD DrvReadAckn(INT iBlockNr); This function reads a receipt (acknowledgement) from the development system. void DrvSendAckn(WORD acknowledge, INT iBlockNr); This function itself sends a receipt (acknowledgement) to the development system.

4.1.4

Adaptation of the communication

This point must be implemented in each case. For communications the driver Plc_com.c is supported by a system-dependent serial driver. The latter must be adapted to the operating system. In this system-dependent driver three functions must be available. These are stored in a separate file (comm.c) and must be compiled together with the runtime system. The runtime system then assembles the received data blocks into a message (codelzs.c) and evaluates them (server.c). The routines must fulfil the following functions: int SerOpen (int comParam); Opens and initialises the serial interface (or any other communication interface such as TCP/IP). A baud rate can be selected as desired. In the dialogue for the communication parameters of the programming system the appropriate setting is selected for logging in. For the serial protocol, use the data lines only and disable the control lines such as RTS etc. CoDeSys uses a binary protocol, so exclude any possible special treatment of symbols such as Backspace, Bell or the zero character. int SerClose ();
tech_doc_e.doc / V1.2

Closes the current connection and re-opens it again for the next login. unsigned int SerBlckIn (char * p_ch, int nBufferSize); Reads a maximum of nBufferSize characters from the receive buffer into the p_ch buffer and supplies the number of characters actually read as a result. The reading should be non-blocking, i.e. the function should return immediately. If momentarily no characters are present at the interface, it returns 0.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 36 of 70

CoDeSys SP 32 Bit Embedded

void SerBlckOut (char * p_ch, int nSendSize); Delivers nSendSize characters from the p_ch buffer to the interface and immediately returns. void DrvLevel4ReceiveMessage(void); Interface function for a Level 4 Driver. This function is called every PLC cycle in addition to DrvReceiveMessage (DrvReceiveMessage is the core function that calls the Level 2 Functions decribed above). The function is meant to receive messages, and, when a complete message was received, call SrvComputeService.

4.1.5

Driver implementation for TCP/IP (Level 2 Route)

Runtime version 2.3 also supports another CoDeSys Gateway driver, the tcp/ip (Level 2 Route) driver. The runtime driver listens to TCP/IP port 1202 (while the TCP/IP (Level 2) driver listens to port 1200.) This new driver is needed to allow the WebServer to communicate with the runtime system, as the WebServer uses this protocol. You can use the #define INCLUDE_DRV_ROUTE to enable this protocol.

4.1.6
4.1.6.1

Communication with CAN


CANOpen protocol

With the file rts302.c, the CSP32E runtime also supports download and debugging over CAN. The CANOpen protocol defined in the DS301 specification is used. Both expedited and segmented transfer are supported. Please refer to CANopen Application Layer and Communication Profile CiA Draft Standard 301 Version 4.01 for further details of the protocol specification. The protocol is described in chapter 9.2.2 Service Data Object (SDO). Some examples for messages are shown below: For expedited download, the CAN messages are built like this: Byte0: 3 bit command (001) 1 bit unused 2 bit size 1 bit expedited transfer (1) 1 bit size indicated (1) Byte1: Low byte of Index Byte2: High byte of Index Byte3: SubIndex Byte4 Byte 7: Data Expedited download is used for message that are shorter or equal 4 bytes, if expedited transfer is enables in the gateway. For segmented downoad, the CAN messages are built like this: Byte0: 3 bit command (001) 1 bit unused 2 bit size 1 bit expedited transfer (0) 1 bit size indicated (1) Byte1: Low byte of Index Byte2: High byte of Index Byte3: SubIndex Byte4 Byte 7: Data The COB id of the download messages is NodeId + 0x600 For the upload request, the CAN messages are built like this: Byte0: 3 bit command (010) 1 bit unused 2 bit size 1 bit expedited transfer (0) 1 bit size indicated (1) Byte1: Low byte of Index Byte2: High byte of Index Byte3: SubIndex
tech_doc_e.doc / V1.2

The COB id of the upload message is NodeId + 0x580 Standard messages are sent to Index 0x1025, Subindex 1, the download of the application program is sent to Index 0x1F50, Subindex 1.

A physical low level driver has to register itself with a call to Drv302Define. Here, function pointers have to be passed in a structure. The structure is called DrvInt. The 2 functions are:
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 37 of 70

CoDeSys SP 32 Bit Embedded

- a function to open a channel char (*Open)(struct tagDrvInt* pthis); - and a function to send a can message unsigned short (*Send)(struct tagDrvInt* pthis, unsigned char* pbyData, unsigned short uCount); Then, the functions s_pDrvL4-> Init() and s_pDrvL4-> Open() of the Level 4 Driver can be called. When a CAN message is received, the function s_pDrvL4->Receive() must be called. The receive of a CAN message can be interrupt-driven, or by polling. The runtime calls the function DrvLevel4ReceiveMessage cyclically. Here, s_pDrvL4->GetStream has to be called to read the received data. To send the answer, s_pDrvL4->Send has to be called. 4.1.6.2 CANOpen driver Interface functions

The CANOpen communication consists of 2 parts: The DSP302 (Level4) driver, and the Level2 low level driver. The DSP302 (Level4) driver are additional files that have to be added to the the runtime system core, while the Level2 driver has to be adapted to the system. The Level2 driver registers itself at the Level4 driver. It is later called to open the interface and to send a packet. When a packet is received by the Level2 driver, a function of the Level4 driver has to be called. The receiving of a packet can be done in an interrupt, or by polling the physical CAN interface. The DSP302 (Level4) consists of 2 source code files, rts302.c and rtsdrv.c, and the respective header files RtsDrv.h and rts302.h. The file rts302.c is responsible for CAN DSP302 handling The file rtsdrv.c is responsible for stream buffer handling. Initialization: A low level driver has to register itself at the 302 (Level4) driver with calls to Can1_DrvDefine(&s_drvCAN1); Drv302Define(&s_drv302, &s_drvCAN1.drvbase); Can1_Set302(&s_drv302); Then, the interface is opened with s_pDrvL4 = &s_drv302.drvbase; s_pDrvL4->Init(s_pDrvL4); s_pDrvL4->Open(s_pDrvL4); Finally, the send and receive buffers are set: L4StreamSetBuffer(s_pDrvL4->GetStream(s_pDrvL4, DRVL4S_RECEIVE), ReceiveBuffer, LZS_BUFFER_SIZE); L4StreamSetBuffer(s_pDrvL4->GetStream(s_pDrvL4, DRVL4S_SEND), SendBuffer, LZS_BUFFER_SIZE); Send: The function registered as send function will be called from the 302 (Level4) driver. It is defined as follows: static unsigned short Send(DrvCAN* pthis, unsigned char *pbyData, unsigned short uCount) Receive The receive function of the 302 (Level4) driver has to be called. It is defined like this: char (*Receive)(struct tagDrvL4* pthis, unsigned char* pbyData, unsigned short uCount);
tech_doc_e.doc / V1.2

Example: s_pDrvL4->Receive(s_pDrvL4, (unsigned char*)&co, sizeof(co)); DrvLevel4ReceiveMessage Similar to chapter 4.1.4, the function DrvLevel4ReceiveMessage has to be adapted. This function is called in every PLC cycle. It has to call SrvComputeService. Download and config download messages have to be copied directly to the code buffer. An example of this function with adaptations to the stream buffers of the DSP302 driver can be found in commsa.c.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 38 of 70

CoDeSys SP 32 Bit Embedded

4.2

The storage model

There are two principal options for organising the memory for the code and the data of the PLC program. Either there is a fixed schema for the memory distribution on the controller, or the necessary memory is allocated dynamically. CoDeSys calculates the size of data memory needed for the application program as follows, using parameters of the target settings: TotalDataMemoryNeeded = SizeOfMemorySegment + SizeOfInputSegment + SizeOfOutputSegment + SizeOfRetainSegment + (SizeOfDataMemory * <Number of global segments>) + (MaxNumberOfPOUs * 12); In principle memory for the code and the data of the application program is required in two independent regions. If the feature Online Change is to be used, two code regions of equal size are actually required. In the following paragraphs the necessary adaptations are described for both models:

4.2.1

Fixed memory

In this model it is defined in advance where the free memory for the PLC program is located. Define the start and the length of the memory areas in the file custom.h as in this example: /* Memory areas of the PLC executable code */ #define #define #define #define #define PLC_DATA_BEG PLC_CODE_BEG PLC_CODE_BEG1 PLC_DATA_LEN PLC_CODE_LEN 0x00380000 0x00390000 0x003A0000 0x00010000 0x00010000

Here, 3 equal size regions of 64K each have been defined. In order to inform the runtime system of these regions, activate the following code in the file main.c. pcCodeArea0 = PLC_CODE_BEG; pcCodeArea0 = PLC_CODE_BEG1; pbyDataArea = PLC_DATA_BEG; The variables pcCodeArea0, pcCodeArea0 and pbyDataArea are used in the remainder of the runtime system. At the end of the file main.c there are the functions CstGetAccuFlowMemory and CstFreeAccuFlowMemory. They serve the memory management for the data of the expanded code generation (Flow Control). The function of CstGetAccuFlowMemory is to supply a pointer to a memory area for the acceptance of these data. The parameter iSize, that defines the desired size of the region, is of course irrelevant in the case of fixed memory distribution. The size of the required memory is defined by settings in the programming system. The function CstGetAccuFlowMemory is empty in our case.
tech_doc_e.doc / V1.2

4.2.2

Dynamic memory

In this model the memory is requested from the operating system with functions such as malloc. Define the length of the memory areas in the file custom.h as in this example. /* Memory areas of the PLC executable code */ #define PLC_DATA_LEN
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

0x00010000
Page 39 of 70

CoDeSys SP 32 Bit Embedded

#define PLC_CODE_LEN

0x00010000

In this manner regions of equal size of 64K each are defined. This method is used in main.c as the default. At the end of the file main.c there are the functions CstGetAccuFlowMemory and CstFreeAccuFlowMemory. They serve the memory management for the data of the expanded code generation (Flow Control). The function of CstGetAccuFlowMemory is to supply a pointer to a memory area for the acceptance of these data. The parameter iSize defines the desired size of the region. The function of CstGetAccuFlowMemory is to release the memory region once again. Please note that the hardware configuration (rtscfg.c) needs a dynamic memory model, as it uses free and malloc.

4.2.3

Customer specific user program data management

This interface allows to customize the memory management for the code areas. We recommend to use the runtime systems standard method. If you have extremely low resources on RAM memory, you can use this feature. The adaptijon function CstReallocDataArea is called every time a download happens. It is not called at a online change service. If you return 0, the runtime system will allocate user data according the target settings (recommeded). To implement a customer specific user program data management, return the pointer to the user data buffer Set the size of the user data buffer in *pulCstDataSize

Function interface: unsigned char* CstReallocDataArea(unsigned long dwDataSize, unsigned long dwGlobalDataSize, unsigned long *pulCstDataSize) dwDataSize: Maximum data size as set in the target settings This value does not change during online change. dwGlobalDataSize: Actual data size needed by the user program. Attention: This value may increase on a online change.

4.2.4

Relocating data to areas

The actual position of the data memory area is not known by the CoDeSys programming system (and it does not need to know it). The base address for the data area is assumed as 0 (see target settings). After download, the runtime system relocates the data accesses in the downloaded code. This is, it corrects the addresses used in the code for data accesses by adding the actual data area address. The function in the runtime system that implements this is TrgRelocateCode(). It is implemented processor-specific in the respective adaptation parts. Every processor has a different binary code for data access. User data can be located in 2 different memory areas: One for standard data, and one for RETAIN data. TrgRelocateCode already supports this. You can see this in the function by
tech_doc_e.doc / V1.2

case DATAAREA_GLOBAL: and case DATAAREA_RETAIN: If you need to support more than these 2 memory areas, you have to adapt TrgRelocateCode(). Add more cases for the additional data areas. In correspondence, set the data area number in the target settings dialog box of the CoDeSys programming system.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 40 of 70

CoDeSys SP 32 Bit Embedded

4.3

The timer interface

This point must be implemented in each case. For the implementation of


-

timer blocks in a PLC program time monitoring in IEC steps IEC task management logging out after a communication interrupt (timeout after 10 s)

there is in the runtime system the function GetTime(). This function is located in the module main.c and supplies back the system time in milliseconds in a DWORD. This function can be implemented by means of an operating system call, or one allows a variable to increase to a high value by means of an interrupt. The value of this variable is then returned by the function. The variable overflows in an interval of approximately 30 days, i.e. it begins to count from 0 once again. This overflow is however non-critical, since in the whole of the runtime system and application program only the difference between two of these values is analysed. This difference is independent of a possible overflow. Only in the case of times that are greater than 30 days does an overflow actually occur in the time that is being assessed.

4.4

Setting the Automation Alliance target id

The programming system CoDeSys for Automation Alliance (CoDeSys 2.2 or newer) checks the target id given in the selected configuration against the target id in the controller. To get a positive result of this check, you have to set the same target id in the controller as in the installed configuration. If you use a Hook-DLL with your target, you also have to set the HookId. Otherwise, set the HookId to 0. You can set the target id in the file main.c with the function CstGetTargetIds. Example: void CstGetTargetIds(unsigned long* ulTargetId , unsigned long* ulHookId) { *ulTargetId = 10000; *ulHookId = 0; } Enter the target id to the contents of the pointer ulTargetId. If you have an older version of the runtime system (before Automaton Alliance resp CoDeSys version 2.1 or older), the function CstComputService() has to be extended to the service RTS_CHECKTARGETID like this to be compatible to the CoDeSys 2.2 programming system: int CstComputeService(char *ReceiveBuffer, char *SendBuffer) /* Execute additional services here */ { unsigned char service; int SendBufferLen = 0; service=ReceiveBuffer[0];
tech_doc_e.doc / V1.2

switch (service) { /* New service to check target id */ case RTS_CHECKTARGETID: {


3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 41 of 70

CoDeSys SP 32 Bit Embedded

unsigned long ulKey; memcpy(&ulKey , &ReceiveBuffer[1] , sizeof (unsigned long)); *(unsigned long*) SendBuffer = RtsGetTargetEncryption(ulKey); SendBufferLen = sizeof (unsigned long); break; } } return SendBufferLen; } The function RtsGetTargetEncryption() is located in the file RtsEncTarget.c. This file has to be included in the project workspace.

4.5

The process map

The process map for the communication of the PLC program with the inputs and outputs of the controller consists of a common memory area to which both the PLC program and the runtime system have access. This memory area lies within the memory reserved for the data of the PLC program. There is a region each for the inputs and outputs. The size of the regions is determined by the development system. In each cycle the input region is filled with data from the peripherals before the call of the PLC program. After the execution of the program the values of the output region are written into the physical outputs. The pointers to the two memory regions of the process map are obtained in the runtime system by means of the following functions: char* GetInputAddress(void) char* GetOutputAddress(void) The reading of the inputs of two 16 bit input modules can then appear as follows for example: /* read inputs */ p = (short *)GetInputAddress(); if (p != NULL) { p[0] = *INPUT_MODUL0; p[1] = *INPUT_MODUL1; } Here INPUT_MODUL0 and INPUT_MODUL1 are the physical address of the input modules. This code is located ahead of the call of the function ControllerCyclus that actually calls the PLC program. The outputs are written after the call of ControllerCyclus. We again assume two 16 bit output modules. /* write outputs */ p = (short *)GetOutputAddress(); if (p != NULL) { *OUTPUT_MODUL0 = p[0]; *OUTPUT_MODUL1 = p[1]; } Here OUTPUT_MODUL0 and OUTPUT_MODUL1 are the physical address of the output modules.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 42 of 70

CoDeSys SP 32 Bit Embedded

When using field bus cards corresponding functions of the appropriate driver must be used to read or write the data. In the programming system, the process map for the I/Os is defined. For Motorola processors switch off the byte aligned option. In this case, please note that the number in the WORD-Addresses indicates the WORD-Address (%IW3 starts at byte 6), and the number in a DWORD-Address indicates the DWORD-Address (%QD2 starts at byte 8). The access to bits (%MX, %IX and %QX) is word-aligned. This means that in a IEC Bit-Address, the first number indicates the word, the second the bit within the word. This means that %IX0.0 is the lowest byte in the first word. It is located in byte 1 (and not in byte 1). The following picture may illustrate the mapping: ------------------------------------------------------------------------------------------------------------------------------| DWORD 0 | ------------------------------------------------------------------------------------------------------------------------------| WORD 0 | WORD 1 | ------------------------------------------------------------------------------------------------------------------------------| Byte 0 | Byte 1 | Byte 2 | Byte 3 | ------------------------------------------------------------------------------------------------------------------------------| X0.15 X0.0 | X1.15 X1.0 | -------------------------------------------------------------------------------------------------------------------------------

4.6

The debugging interface

If the user sets a breakpoint in the programming system, the user code is patched at the appropriate location in the controller. The breakpoint code can be specified in the function unsigned long SysGetBPOpcode() Use the appropriate code for your progressor. For example, for the Motorola 68000 or ColdFire processor, return 0x000081CD (jsr (a5)). For the intel x86 processor, return 0x000070CD (INT 70).

4.6.1

Debugging the motorola 68000 or ColdFire

When a breakpoint is set in the PLC program a subprogram call is inserted by the runtime system at the appropriate location in the program code. The subprogram call branches off into the routine for the handling of breakpoints. The subprogram call takes place relative to the register A5. In each cycle this register is occupied with a pointer to the breakpoint routine before the call of the application program. It is called CoDeSysBP() and is located in the module main.c. The setting of the register and the call of the PLC program take place in the function CstCallPLC_PRG in the module main.c. The function can for example appear as follows: ASM("move.l ASM("move.l (*pPLC_PRG)(); ASM("movea.l (a7)+,a5"); a5,-(a7)"); _pCoDeSysBP,a5"); /* save A5 */ /* BP function to A5 */ /* call PLC program/ /* restore A5 */

Here care must be taken to ensure that the C compiler that is being used does not overwrite the register A5 during the call of PLC_PRG. The function is to be adapted with regard to the assembler notation of the C compiler that is being used.
tech_doc_e.doc / V1.2

If now the program execution of the PLC program achieves the location of the breakpoint, the function CoDeSysBP is called. In it the function OCDebugTrap() in the module OCDebug.c of the runtime system must be called, so the following is defined: void OCDebugTrap (unsigned long ulProgramCounter); The parameter ulProgramCounter should thereby contain the current status of the program counter in the PLC program. This value is the return address of the called function, corrected by the length of the
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 43 of 70

CoDeSys SP 32 Bit Embedded

command for the subprogram call (2 bytes). The function CoDeSysBP can thus be implemented as follows: ASM("sub.l ASM("move.l #2,(sp)"); (sp),d0") /* correct return address */ /* return address to D0 */

ASM("movem.l d1-d7/a0-a6,-(sp)"); /* save register */ ASM("move.l ASM("jsr ASM("addq.l d0,-(sp)"); _OCDebugTrap"); #04,sp"); /* return address on stack */ /* call OCDebugTrap */ /* correct stack */

ASM("movem.l (sp)+,d1-d7/a0-a6"); /* restore register */ The parameter transfer takes place in this case via the stack. This is dependent upon the C compiler that is being used. If the parameter transfer takes place, for example, via D0, the lines return address on stack and correct stack are deleted after the call of OCDebugTrap. For processors other than the 68k, use DbgDebugTrap instead. Many C compilers place further data on the stack when entering a C function. The return address does not then lie directly on the stack pointer sp, but is correspondingly displaced. If the compiler, for example, places 2 registers (8 bytes) on the stack, the first two lines must then be written as follows: ASM("sub.l ASM("move.l #2,8(sp)"); 8(sp),d0"); /* correct return address */ /* return address to D0 */

The function is to be adapted with regard to the assembler notation of the C compiler that is being used. The beakpoint routine of the runtime system requires a further function that must be adapted to the C compiler that is being used. This is called CstGetStack and is also located in the module main.c. Its function is to supply the current value of the stack pointer (register A7). It can, for example, be implemented as follows: unsigned long* CstGetStack() { unsigned long* pulStack; pulStack = (unsigned long *)ASM("move.l return pulStack; }

a7,d0");

The function is to be adapted with regard to the assembler notation of the C compiler that is being used. Instead of using the subprogram call the debugging can also be implemented with the aid of interrupts. Instead of the JSR (A5) a TRAP 7 can be patched in at the beakpoint position. For this purpose the Define OP_BP must be set to 0x4E47 in the module ocdebug.c. The function CoDeSysBP must then be inserted into the interrupt table as an interrupt service routine. It is recommended to use the JSR (A5) method described above.

4.6.2

Debugging the Motorola PowerPC

Two methods can be used to realize debugging for risc processors: Using a trap, or using a function call. We recommend to use the method with function call. It is easier to implement and it is operating system independent.
tech_doc_e.doc / V1.2

4.6.2.1

Breakpoints with trap

To set a breakpoint, code is patched that results to a call to the function DbgDebugTrap(). Return the BP opcode in the function SysGetBPOpcode() in main.c. DbgDebugTrap is defined as follows: void DbgDebugTrap(unsigned long ulProgramCounter , unsigned long eaxRegister , unsigned long *pulEbp)
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 44 of 70

CoDeSys SP 32 Bit Embedded

The parameter ulProgramCounter is the address of the code that caused the exception, which is the breakpoint position. The parameter eaxRegister is not used and can be 0. In the parameter called pulEbp the stack pointer of the calling function (r1) is to be passed. The code produced by CoDeSys creates the following stack frame: R1 + 0 R1 + 4 R1 + 8 ... R1 + n R1 + n + 4 -> -> -> -> previous stack pointer return address stack for local data ... stack for local data previous stack pointer

4.6.2.2

Breakpoints with function call

To enable this option in the programming system, set the target flag PPC_DebugWithCall. In SysGetBPOpcode(), return a relative call to a debug help function that was generated by the programming system as part of the user code. You can use the function CtrlGetDebugger() to get the function pointer. This function will call the function SysDebugHandler() in the adaptation part, where you have to call DbgDebugTrap() with the parameters as described above. Example: /* Debugging for PPC with jump */ unsigned long SysGetBPOpcode(unsigned long ulAddressToPatch) { /*bl: branch with link*/ unsigned long ul; unsigned long ulDebug = (unsigned long)CtrlGetDebugger(); long lAddress = ((long)ulDebug - (long)ulAddressToPatch); if (abs(lAddress) > 0x01ffffff) return SysGetNOPOpcode(); /* no relative jump is possible: offset too large */ ul = (unsigned long)lAddress & 0x03FFFFFF; return ul | 0x48000001; } 4.6.2.3 Flow Control

Flow control is realized with breakpoints set on every breakpoint position. The value of the current variable is retrieved with the functions long CstGetTrapGPR(long ucRegNum) respectively double CstGetTrapFPR(long ucRegNum)
tech_doc_e.doc / V1.2

for float values. The parameter ucRegNum contains the register number that contains the value. In the MainPPC.c example, the current values of the registers are stored in SysDebugHandler() to global variables. They can later be retrieved by the CstGetTrapxxx-Functions.

4.6.3

Debugging the ARM

For ARM processors, the same debug mechanism can be used as for the PowerPC processor. To use the breakpoint by function call method, set the target option ARM_DebugWithCall in your target file
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 45 of 70

CoDeSys SP 32 Bit Embedded

(normally this done by 3S in ARM target files). The function SysGetBPOpcode() has been adapted to ARM operation codes. In SysGetBPOpcode(), return a relative call to a debug help function that was generated by the programming system as part of the user code. You can use the function CtrlGetDebugger() to get the function pointer. This function will call the function SysDebugHandler() in the adaptation part, where you have to call DbgDebugTrap() with the parameters as described above. Example for SysDebugHandler: void SysDebugHandler(void) _asm(" ; Push used registers str lr, [sp, #-4]! str r0, [sp, #-4]! str r1, [sp, #-4]! str r2, [sp, #-4]! ; Parameter passing for DbgDebugTrap ;void DbgDebugTrap(unsigned long ulProgramCounter, unsigned long eaxRegister, unsigned long *pulEbp) ;DbgDebugTrap(Pc, R0, R10); mov r2, r10 ; Parameter 3: Actual stack frame pointer, ; passed on stack ; Parameter 2: TODO: Pseudo-eax ; Parameter 1: Actual PC ; Adjust code address on BP code ; Call DbgDebugTrap ; stack adjustment

mov r1, r0 ldr r0, [r10, #-4] sub r0, r0, #4 bl DbgDebugTrap ldr r10, [sp], #+4 ; Pop used registers ldr r2, [sp], #+4 ldr r1, [sp], #+4 ldr r0, [sp], #+4 ldr lr, [sp], #+4 mov pc, lr "); }

; return

4.6.4

Debugging the Intel 186

Attach the function DebBPIsr to INT70. SysGetBPOpcode determines the used interrupt. If you have to use another interrupt, adapt SysGetBPOpcode accordingly.
tech_doc_e.doc / V1.2

In DebBPIsr, adapt the call to DbgDebugTrap according the example.

4.7

Adaptation to the C compiler

This point must be implemented in each case. The runtime system already contains implementations for Microtec and Microware compiler. If the define #define FASTRACK
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 46 of 70

CoDeSys SP 32 Bit Embedded

is set, assembler syntax for the Microware 68000 compiler are used. If it is not set, the commands for the Microtec compiler are used. Functions are called, from the runtime system written in C, that are located in the PLC program produced by the development system. If the call convention of the C compiler being used deviates from that of the development system, frame functions must be written that reconcile the deviation.

4.7.1

Motorola 68k and ColdFire

The development system expects transfer parameters to be transferred on the stack to functions. This is with reference to the functions CstGetAddress, CstCodeInit and CstGlobalInit. Some compilers pass parameters in the registers D0 and D1. In this cases, you have to insert dummy parameters. The assembly functions like pGetAddress always return values in D0.

4.7.2

Motorola PowerPC

The development system expects transfer parameters to be transferred in r3, r4, r5. This is with reference to the functions CstGetAddress, CstCodeInit and CstGlobalInit. The assembly functions like pGetAddress always return values in r3.

4.7.3
X86

Intel 186

The following defines have to be set in the makefile:

TRG_186_CPU

4.7.4

Infineon Tricore

The following defines have to be set in the makefile: TRICORE

4.8
4.8.1

Additional server services and pre/post-processing


Additional server services

Most server services are handled by the function SrvComputeService in the module server.c. Services that are not handled there are forwarded to the function CstComputeService in the module main.c: int CstComputeService(char *ReceiveBuffer, char *SendBuffer) The function contains as parameters one buffer with the received message and one for the response from the runtime system. Return the length of the answer in bytes. If 0 is returned, the standard message for unrecognized messages is returned to the programming system.

4.8.2

Preprocessing services

The function int CstPreComputeService(char *ReceiveBuffer, char *SendBuffer, int ReceiveBufferLen)


tech_doc_e.doc / V1.2

is called before a service is processed by the runtime system. You can examine the service and preprocess it. The function returns the length of the reply message. If a value greater zero is returned, the contents of SendBuffer are sent to the programming system as answer. In this case, the service is not executed by the runtime system core. If a value of zero is returned, the default processing is done. This function is also used to realize a kind of a hook function. It allows the runtime system to inform the adaptation part, without needing the interface of the adaptation part to be changed. Some virtual commands were introduced. The virtual commands are:
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 47 of 70

CoDeSys SP 32 Bit Embedded

#define LZS_HOOK_NEW_PLC_STATE

210

CstPreComputeService is called with this service when the plc status changes. ReceiveBuffer: Pointer to command byte SendBuffer: Pointer to a unsigned short containing the new plc state in the lowbyte and the old plc state in the highbyte. #define LZS_COMM_TIMEOUT 211

CstPreComputeService is called with this service when a communication timeout occurs. ReceiveBuffer: Pointer to command byte SendBuffer: NULL. 212

#define LZS_NO_INIT_INPUTS

CstPreComputeService is called with this service at download when the runtime is about to initialize the input segment with 0. Return 1 to prevent the initialization of the input segment. If 0 is returned, the input segment is initialized with 0. ReceiveBuffer: Pointer to command byte SendBuffer: NULL. 213

#define LZS_GETSEGMENTSIZE

CstPreComputeService is called with this service when segment sizes are calculated. In some cases, the standard implementation of CtrlGetSegmentSize is not working. This is the case if input and output segment are located in different areas. ReceiveBuffer: Pointer to command byte, followed by the segment type (DATAID_INPUT etc.) SendBuffer: NULL. 214

#define LZS_HOOK_APPEND_RTSINFO

CstPreComputeService is called with this service when plc browser command "rtsinfo" is answered. ReceiveBuffer: Pointer to text buffer SendBuffer: length of buffer. 215

#define LZS_HOOK_PROCESSORTYPE

CstPreComputeService is called with this service for Processor Type ReceiveBuffer: Pointer to Processortype SendBuffer: NULL. 216

#define LZS_HOOK_DENY_NEW_PLC_STATE

CstPreComputeService is called with this service before the plc status changes. ReceiveBuffer: Pointer to command byte SendBuffer: Pointer to a unsigned short containing the new plc state in the lowbyte and the old plc state in the highbyte
tech_doc_e.doc / V1.2

return value:

Return 1 if you want to forbid the new state, 0 for default processing. 217

#define LZS_HOOK_LOGIN

CstPreComputeService is called with this service when a CoDeSys instance is logged in ReceiveBuffer: Pointer to command byte
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 48 of 70

CoDeSys SP 32 Bit Embedded

SendBuffer: #define LZS_HOOK_LOGOUT

NULL 218

CstPreComputeService is called with this service when a CoDeSys instance is logged out ReceiveBuffer: Pointer to command byte SendBuffer: NULL.

4.8.3

Postprocessing services

The function int CstPostComputeService(char *ReceiveBuffer, char *SendBuffer, int ReceiveBufferLen) is called after a service was processed by the runtime system. You can examine the service and postprocess it. The function returns the length of the reply message. If a value greater zero is returned, the contents of SendBuffer are sent to the programming system as answer. If zero is returned, the default answer is sent.

4.9

Time behaviour and integration into multi-tasking operating systems

The current implementation of the main function comprises an initialisation part and an endless loop (for (;;)...) that is never subsequently left. The runtime system therefore never terminates. The cycle is executed as often as possible, i.e. after the ending of one cycle the next is executed immediately. The cycle time is therefore a function of the run time of the PLC program and communications. If a deterministic time-wise behaviour is to be achieved, a pause function must be constructed inside the endless loop that delays the processing until a defined period of time since the beginning of the cycle has expired. A further option for the implementation of deterministic time-wise behaviour consists in dividing the main function into an initialisation function and a runtime function. The first part of main up to the for loop becomes a function that can, for example, be named LZSInit. The content of the for loop becomes the content of the runtime function, that can, for example, be named LZSMain. The function LZSInit should be called once at the start; the function LZSMain should be called cyclically. This can be achieved by: producing a task with the function in a multi-tasking operating system capable of real-time operation, or by inserting the function into a time-controlled interrupt. Here it must be noted that in the case of a breakpoint the service routine remains in a loop until the user gives the run command. As a result the processing of the program is halted and the interrupt routine is not left.

4.10 Libraries
CoDeSys and the runtime system support the use of libraries implemented in the C language. The IEC standard library is already available as C source code with compiler and linker command files for the Microtec compiler. Manufacturer-specific libraries can be implemented after the same pattern.
tech_doc_e.doc / V1.2

When using C libraries there are two different options in the first instance. Linking in the PC by the development system at the compilation, and linking in the controller in the runtime system after the download. The two options can also be combined. Both options are described in the following paragraphs. The runtime system already contains all the standard library functions for dynamic linking.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 49 of 70

CoDeSys SP 32 Bit Embedded

4.10.1 Linking in the development system


To be able to link library functions in the development system, the compiled C code of a library must be available as a file in Motorola S record format. For each IEC library a hex file of the same name must be created (e.g. a STANDARD.HEX file is created for STANDARD.LIB). It must be configured such that at the start there is firstly a function table, then a field for data exchange and then the code of the functions. This configuration is achieved by first linking the module anchorl.h with its static data. Some more information with regard to the linker options: The use of the storage model in the runtime system is also reflected in the libraries. When using the fixed storage model store the library data in a free memory area, for example at the end of the memory reserved for the data of the PLC program. When using the dynamic storage model, store the library data at the address 0. The data will then be relocated by the development system. Always store the beginning of the code segment at the address 0. The code region will similarly be relocated by the development system. To construct the library proceed as follows: For each library the following files ANCHORL.C the files with the library functions and the file LAST.C are compiled and linked in this order and a file in Motorola hex record format is constructed. In the file anchorl.c there is a field LibDesc with the library functions, consisting of the function names and addresses. The field should be concluded with a zero entry for end-recognition. The field is only required for the compilation and is not loaded with the other elements onto the controller. In the following example 2 functions are exported from the library: const LibDesc ld[3] = { {"FUNC1", {"FUNC2", {NULL, NULL} };

(unsigned long)func1}, (unsigned long)func2},

Important: The order of the functions should be alphabetical, both in the table and also in the source code files. (Even if the functions are stored in several files, care must be taken with the linker order.) The reason for this is that when using Online Change the relative locations of the functions with respect to each other and to the 68k runtime library must remain unaltered (PC relative code). That is why the physical order must agree with the indexing, which is alphabetical. Ancillary functions should be placed after the exported functions. In anchorl.c there is a further field pCodeInit, consisting of 128-long values. The first entry is occupied with the function pointer pGetTime (so that the function GetTime can be called in the library); the second with the address of iLastData (so that the development system knows the size of the library data). If no GetTime is required in the library, -1 should be entered (normally only the IEC standard library requires this function for the timers). This field is loaded onto the controller. Example: unsigned long const pCodeInit[128] = { -1L, (unsigned long)&iLastData, -1L, -1L, -1L, -1L, -1L, -1L, ... Construction of the library with the Microtec C compiler

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 50 of 70

CoDeSys SP 32 Bit Embedded

In the sub-directory LIB of the runtime system are located all source and control files that are necessary for the construction of the standard library with the Microtec compiler. In addition to the H and C files these are the following files lap_code.cmd genlib.ld genlib.bat control file with the compiler options control file with the linker options DOS batch file for call of compiler and linker

If you wish to store the library data at a fixed address, adapt the control files as follows: lap_code.cmd: Store the start of the library data at the end of the memory reserved for the data of the application program. The standard library requires 104 (hex) bytes. Example: If the data region begins at 30000 (hex) and is 10000 (hex) long, 3FE00 is a sensible value for the start of the library data. In lap_code.cmd you therefore write: SECT zerovars = $0003FE00 genlib.ld: The access to the data must be absolute. To achieve this the compiler option -Mda is used. Ensure that this is used in genlib.ld, and not -Md5, for instance. If you are using the dynamic storage model, adapt the control files as follows: genlib.ld: Store the start of the library data at the address 0. In lap_code.cmd you therefore write: SECT zerovars = $00000000 The compiler may produce an error, but this should be ignored. A hex file is nevertheless produced. (It remarks that the code and data will be stored at the same address, but this is nonsense, since the code is PC-relative and the data are relative to A5.) lap_code.cmd: Access to the data must be relative to the A5 register. For this purpose the compiler option Md5 is used. CoDeSys recognises the method used on the basis of the address set for the data. The library data are stored at the start of the data region. When a library function is called code is produced that fills A5 with the base address of the data.

4.10.2 Linking in the runtime system


For each function whose call could not be resolved the development environment produces an entry in a list of not found functions. The entry consists of the name of the function and its index in the function table of the runtime system. This list is transferred with the download of the code. In the module main.c of the runtime system there is a function CstLinkFunction: void *CstLinkFunction(char *pszExtRef) Here, the additional manufacturer-specific functions can be added to the function pointer table. Just return the function pointer of the function with the name given in the parameter pszExtRef. Define the functions in accordance with the declaration in the IEC library in the runtime system (*.h-file generated by the programming system with Save as external library). Important only for Motorola 68k targets: The parameter transfer takes place on the stack. For compilers that transfer the first two parameters in registers, the Define PARA must be set accordingly. #define PARA unsigned long dummy1, unsigned long dummy2, In this way two dummy parameters are introduced that are occupied by the (not supplied) registers. If the define for the Microware compiler for 68k (#define FASTRACK) is set, it is also so defined. Dynamic linking has the advantage over the procedure described in the previous section that no C Lib has to be made available as a hex file on the PC. The extent of the data that must be transferred to the controller is smaller. However in the event of an update of a library function the whole runtime system must be renewed, and there may be more functions present on the controller than are actually required (with possible space problems).

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 51 of 70

CoDeSys SP 32 Bit Embedded

4.11 Retain Data


In the programming system, you can define variables to be retain by adding the keyword RETAIN to a variable block definition. For example: VAR RETAIN Retainvar: INT; END_VAR These variables are meant to keep their value also during a power off / power on sequence of the controller. This feature has to be implemented in the runtime system depending on the hardware environment. In the programming system, there are several options to define the location of these retain variables. This chapter cares about how to save retain data at power off. The code is stored with the bootproject mechanism, using the CstFile functions (see chapter File system functions). CoDeSys saved additional 12 bytes to the retain data segment to store retain identity tags. When a bootproject is loaded, the project id is checked against these tags. To support older versions of the runtime, where these tags were not saved, a retain segment without these tags is treated as valid. On newer systems, the retains have to be treated as invalid in this case. To activate the more strict checking, set the member bRetainInvalidIfIdentityMissing of the CustomSettings-structure to 1 in CstInit. In base, there are 3 scenarios:

4.11.1 All data memory (RAM) is buffered


In this case, the complete memory for application data is buffered through a power off / power on sequence of the controller. All data are automatically retentive, assuming the data location is the same after reboot. On bootup of the runtime and loading the bootproject, normal data is initialized, while variables declared as retain are not initialized. In the target settings of the programming system, use the following options: Retain in own segment: Off Area of retain segment: 1 (same as the other segments) This causes the retain variables to be mixed among the other variables in area 1. In the runtime: In the function CstInit(), set pCstMetrics->ulSizeRetain = <Size of data area>;

pCstMetrics->sRetainSaveType = CST_RETAIN_DIRECT; pCstMetrics->pbyMemoryRetain = 0;

The function CstRetainRestore must be empty: char CstRetainRestore(unsigned short sSegment, unsigned char *pbyData, unsigned long ulSize) { return 0; }
tech_doc_e.doc / V1.2

4.11.2 Only a part of the data memory (RAM ) is buffered


In this case, only a limited area of RAM is buffered through a power off / power on sequence of the controller. It is possible to allocate the retain data in this area, while normal data is in RAM. On bootup of the runtime and loading the bootproject, normal data is initialized, while variables declared as retain are not initialized. In the target settings of the programming system, use the following options:
Page 52 of 70

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

Retain in own segment: On Area of retain segment: 2 (other as the other segments) This causes the retain variables to be located to a own segment in a own memory area. All other segments are located to area 1. In the runtime: In the function CstInit(), set pCstMetrics->ulSizeRetain = <Size of the buffered memory area>;

pCstMetrics->sRetainSaveType = CST_RETAIN_DIRECT; pCstMetrics->pbyMemoryRetain = <Address of the buffered memory area>;

The function CstRetainRestore must be empty (see above). All accesses to retain data will be relocated to the buffered area.

4.11.3 RAM is not buffered, Flash or Hard Disc available


In this case, RAM is not buffered through a power off / power on sequence of the controller, but a flash or hard disc is available. During operation, the retain variables are, like the other variables, in normal RAM. On power down, the retain data has to be copied to the save area (flash or hard disc). If a power down signal is not available, the data has to be copied cyclically. On restart, the retain data has to be copied back to the application data area. Therefore, the function CstRetainRestore has to be implemented. The saving of the retain data has to be performed by the adaptation part of the runtime system. The functions CtrlGetSegmentAddress(DATAID_RETAIN) and CtrlGetSegmentSize(DATAID_RETAIN) give you the address and size of the retain segment. SrvGetRetainSize() gives you the size of memory that is really used by retain variables, (which may be smaller than the retain segment size retrieved by CtrlGetSegmentSize). Use these values to save the retain data. On bootup of the runtime and loading the bootproject, normal data is initialized, and retain data has to be copied back to its location. In the target settings of the programming system, use the following options: Retain in own segment: On Area of retain segment: 1 (same as the other segments) This causes the retain variables to be located to a own segment among the other segments in memory area 1. In the runtime: In the function CstInit(), set pCstMetrics->ulSizeRetain = <Maximum allowed size for the retains>;

pCstMetrics->sRetainSaveType = CST_RETAIN_ONPOWERFAIL; or pCstMetrics->sRetainSaveType = CST_RETAIN_CYCLIC; pCstMetrics->pbyMemoryRetain = 0;

The function CstRetainRestore must be implemented. Copy the data from flash or the hard disc to the memory location specified by pbyData, size specified by ulSize.
tech_doc_e.doc / V1.2

For example: char CstRetainRestore(unsigned short sSegment, unsigned char *pbyData, unsigned long ulSize) { memcpy(pbyData, pToMyFlash, ulSize); return 1; }
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 53 of 70

CoDeSys SP 32 Bit Embedded

4.12 File system functions


Features like Create Bootproject and source code download are realized with file system functions. The following file system functions have to be supported. They are defined in main.c. These functions also allow the application programmer to access the file system if the IEC library file.lib is included in the project. The core system opens only one file at a time. There are mainly 2 files used: DEFAULT.PRG for the boot project and SOURCE.DAT for download source code. If you have a file system, you can easily call your operating systems file system functions. If you have a flash, you have to adapt the functions to access the flash memory. void CstFileInit(short sFileSystem) Init your file system if necessary. void CstFileExit(short sFileSystem) De-init your file system if necessary. void* CstFileOpen(char *szFileName, char *szMode) Open a file with the given name. Mode can be r for read and w for write access. Return a file number for idenification. This number will be used in subsequent calls to CstFileWrite() etc. short CstFileClose(void* pFile) Close the given file. unsigned long CstFileRead(void *pFile, unsigned char *pbyBuffer, unsigned long ulSize) Read max. ulSize bytes from the given file into the buffer pbyBuffer and increase the read position. unsigned long CstFileWrite(void* pFile, unsigned char* pbyBuffer, unsigned long ulSize) Write ulSize bytes from the buffer pbyBuffer to the given file and increase the write position. short CstFileDelete(char *szFileName) Remove the file with the given name from disc or flash. void *SysDirOpen(char *szDir); Opens given directory int SysDirRead(void *pvDir, char *szDirEntry); Reads next directory entry. Fills text buffer szDirEntry. Buffer length is LZS_MAX_TEXT_SIZE = 80 Returns 1 if entry exists, 0 if end of directory reached. The file main.c contains an example implementation of file functions with the operating system OS9. The runtime system is notified that a file download is complete with a separate message. The message is LZS_FILE_TRANSFER_DONE. The command byte is followed by the file name. The following file names are defined and used by the programming system: #define PLC_PROGRAM_FILE "DEFAULT.PRG"

Name of the bootproject. #define CONFIG_DOWNLOAD_FILENAME "config.dat"

Name of the PLC configuration data. The PLC configuration is sent as a file if the option Download as file is selected in the target settings dialog box of the progamming system. Normally, the PLC configuration data is sent with the service RTS_DEFINE_CONFIG.
tech_doc_e.doc / V1.2

Normally, you will return RTS_OK after processing the message. However, if an error occurs while processing the message, return RTS_FILE_ERROR. In this case, the programming system will display an error message containing the file name.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 54 of 70

CoDeSys SP 32 Bit Embedded

4.13 Introducing faster Tasks


CoDeSys offers two possibilities to realize faster tasks than the IEC tasks in a single tasking environment. One possibility is using the system library SysLibCallback.lib, the other possibility is to use the interrupt tasks feature.

4.13.1 The callback library


Using this library, you can dynamically register IEC functions to be called from a system event using the function . There are some predefined runtime system events, for example program goes to run state (EVENT_START), program goes to stop (EVENT_STOP) etc. The events are defined in the enumeration RTS_EVENT. In addition, there are some events reserved for system-specific or customer-specific purposes. These events can be handled in the custom part of the runtime system. They are defined as EVENT_INT_0, and so on. For more details about the SysLibCallback library, see the respecting documentation. In the runtime system, you can call the function EvtInterruptHandler if a interrupt or system event occurs. This function will call the registered IEC functions. void EvtInterruptHandler(int iInterrupt) In the parameter interrupt, the interrupt number is passed (0 for EVENT_INT_0, 1 for EVENT_INT_1, and so on). To enable this feature in the runtime library, set the compiler switch INCLUDE_EVENTS.

4.13.2 Interrupt Tasks


Interrupt tasks give you the possibility to define tasks that are not called by the slow IEC task handler, but by a OS interrupt. This allows the user to define high priority POUs with a short cycle time, or POUs that are triggered by a hardware input. The cycle time of normal tasks is limited by the scan time of the main loop of the runtime system. Also, tasks called by the IEC scheduler are not interrupted. So, if a low-priority task is executed, the execution of a high-priority task is delayed until the low-prority task is finished. This means for the programmer: 1. Task cycle times must be (much) bigger than the scan time of the runtimes main loop. 2. Low-priority background tasks must be short, too, to avoid the jitter of high-speed, high-priority tasks to increase. This is because the 32 bit embedded runtime is a single tasking runtime with a simple simulation of multitasking. If you have a operating system that supports multi tasking, you can also use our 32 bit full runtime system. The method of Interrupt tasks is a way to have real high-speed, high-priority tasks in a single tasking environment. The interrupt task management functions are defined in the file interupt.c. The following functions have to be adapted if you want to use this feature: 4.13.2.1 IntCycle This function is the main cycle for interrupt tasks. It is called by the interrupt service routines UsrIntISR<n>. The call to the IEC task function is made here. Optionally, you can do your I/O-update for the task in this function. We would not recommend to update the whole IO image, because this would increase the interrupt execution time. Better leave the /* Read Inputs */ - block empty, and define library function blocks to update IOs individually.
tech_doc_e.doc / V1.2

4.13.2.2 UsrIntISR<n> The function void UsrIntISR0(void) is an example of an interrupt routine that calls a IEC program (when its present), using the IntCycle function. The interrupt routine is, of course, called on every interrupt, even no IEC task function (user code) is present in the interrupt task table. Thats why the function should check if a interrupt task function is present (IntIsPOUAvailabe) before calling the task (IntCycle). For every interrupt, you normally need a separate function, for example UsrIntISR1, UsrIntISR2,
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 55 of 70

CoDeSys SP 32 Bit Embedded

At startup of the system, these functions have to be entered to the interrupt table of the operating system. 4.13.2.3 UsrIntInsert This function is called when the interrupt task definition is downloaded from the programming system. The function char UsrIntInsert(char *szName...) adds the interrupt POU numbers to the interrupt task table. The UsrIntISR<n> interrupt routine then uses these POU numbers to call the IEC task function (user code). If no POU number is entered, no application program will be called. 4.13.2.4 IntIsTraceTask The function BOOL IntIsTraceTask(int iTask) checks whether trace should be performed with the given task. For the main program, iTask is 1. Return TRUE in this case.

4.14 Exception handling


The function DbgErrorTrap() has to be called if a exception occurs. void DbgErrorTrap(unsigned long ulException, unsigned long ulProgramCounter, unsigned long eaxRegister, unsigned long *pulEbp) The parameter ulException is a exception number as defined in RstExcpt.h. The other parameters are the same as for DbgDebugTrap(). The function calculates the callstack and stays in the debug loop to continue communication.

4.15 The PLC Browser


The plc browser functionality is implemented in the runtime system core file rtsbrows.c. If you want to user the plc browser, include this file into your project and set the compiler switch PLCBROWSE. You can extend the commands of the plc browser in the runtime system. If a browser command is not processed by the core system, it is passed to the user part of the runtime system. In this case, the function unsigned int CstSrvBrowserCmds(char* pszCommand , char* pszAnswer , unsigned int iSubCommand , unsigned int iBlockNr , char* pcActiveBrowserCommand) is called. With the function char CstAddBrowserhelp(char* pszAnswer, unsigned short usCurNr) you can add your commands to the help list of the plc browser. Add your zero terminated command strings to pszAnwer. short SysIsValidPointer(void* ptr) is called when the plc browser processes the memory dump functions. The function is called before a certain memory address is accessed. Return TRUE if the address is a valid address, else FALSE.
tech_doc_e.doc / V1.2

4.16 Misc adaption functions


void CstCodeChanged(void) This function is called when the user code has been changed due to a download or a online change. Flush your processors code cache, if used. void CstDebugOut(char *szDebug)
Page 56 of 70

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

CoDeSys SP 32 Bit Embedded

Print the debug string to the console. unsigned long SysCallWith3Param(char (*pf)(unsigned long, unsigned long, unsigned long), unsigned long ulParam1, unsigned long ulParam2, unsigned long ulParam3)

This functions is called in connection with the SysLibCallback.lib library. When a IEC function has to be called after the specified event has occurred, this function is called by the runtime core. The function should call the given function and pass the parameters. Due to different calling conventions, different mechanisms may have to be used for different targets. For example, functions compiled by the CoDeSys 68k and ColdFire code generator expect a pointer to a structure containing the input and result variables on the stack. Please note that Callback functions may not have local variables, because this would change the stack layout. Please note for 68k and ColdFire targets, that the names of Callback functions must start with Callback. The library can be used with CoDeSys version 2.2.0.2 or newer.

4.17 Extended 32 bit debug services


If you want to use the extended debug and variable monitoring services, set the #define EXT_SERVICES. Include the core file serverex.c to the project and remove the core file trace.c. The extended debug and variable monitoring services include 32 bit offset for variable monitoring and extended trace functionality (analogue trigger, setting the number of samples, ).

4.18 Error messages from the controller


The programming system polls the runtime system state cyclically. The status includes the program state (run/stop), information about breakpoints and also a customer specific information. The customer specific information consists of a message number and an additional text. Using the file errors.ini, the programming system displays the message on the screen. Messages can be displayed in the status line or in a error dialog box. In the runtime system, you can set the error number and text by calling the function void CtrlSetPlcState(unsigned long dwState, char* pszText) In the parameter dwState you pass the error message number. In pszText, the additional text can be passed, for example a file name. It can also be NULL. The error message itself is taken from errors.ini. Example for a message definition: [Error5] Type=Status German=Division durch Null in Modul '%s' English=Division by zero in module '%s' For Type, you can use Status, Message and MessageFatal. Status messages are displayed in the status window at the bottom of the screen. Message and MessageFatal messages are displayed in a dialog box, with warning or error icon. If no Type is given, messages with error number less than 1000 are taken as Message, and with error number greater than 1000 they are taken as Status. Refer to the manual of the CoDeSys for Automation Alliance extension for more details about the format of the errors.ini file.
tech_doc_e.doc / V1.2

4.19 Network variables and object dictionary


To enable the network variables and object dictionary functionality, you need to implement the socket library (SysLibSockets.lib) according your operating system environment. Examples for OS9 can be found in syslib.c.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 57 of 70

CoDeSys SP 32 Bit Embedded

4.20 Some useful runtime core functions


4.20.1 Getting address and size of data segments
The user data area is divided into several segments. There is a segment for the memory, input and output variables, for the global data, retain data and for the data of the single POUs. The function char* GetInputAddress(void) returns the memory address of the input data area. The function char* GetOutputAddress(void) returns the memory address of the output data area. With the function char* CtrlGetSegmentAddress(short sSegment) you can retrieve the memory address of any data segment. The segments are defined as follows: #define DATAID_MEMORY #define DATAID_INPUT #define DATAID_OUTPUT #define DATAID_RETAIN #define DATAID_GLOBVARS 4 0 1 2 3 /* Memory data area */ /* Input data area */ /* Output data area */ /* Retain data area */

/* Global variables data area */

Note: If you did NOT select the retain in own segment option the the target settings dialog of the programming system, there is no own retain segment. Retain variables are stored with the other variables in the global and POU segments. In this case, use #define DATAID_GLOBVARS 3 /* Global variables data area */ The function unsigned long SrvGetRetainSize(void) returns the number of bytes used by retain variables. Note: If you did select the retain in own segment option the the target settings dialog of the programming system, you can get the memory address and size of the retain data with the functions decribed above, and you can store the retain data on power fail, and restore them on power up. You need this if your retain variables are located in non-buffered RAM. The function unsigned long SrvGetGlobalDataSize(void) returns the number of bytes used in the global data segment. This value is sent by the programming system CoDeSys V 2.2 SP 4 or newer. For older programming systems, or for targets other than 68k and PPC single tasking, the value is 0.

4.20.2 Setting the maximum number of POUs


In the file custom.h, you can define the maximum number of POUs supported by the runtime system by setting the define #define MAXPOUS 512 /* Maximum numbers of POUs */ The corresponding number has to be set in the programming system by using an entry in the codesys.ini-file: MAXNUMOFPOUS=512 It is checked at download if the numbers are equal.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 58 of 70

CoDeSys SP 32 Bit Embedded

4.20.3 Reducing the memory requirements of the runtime


The runtime system is designed for a minimum data space consumption. Normally it should not be necessary to reduce the memory space needed by the runtime. If it is necessary due to a very low memory equipment of the target, here are some hints:
-

Reduce the size of the code buffers. These settings should be the same as in the memory layout of the target description. CoDeSys displays the actual code size in the message window after a rebuild all. If the code size exceeds the size given in the target settings, an error message is displayed at compile. Reduce the size of the data buffer. These settings should be the same as in the memory layout of the target description. CoDeSys displays the total amount of memory reserved for user data in the message window after a rebuild all. The actual data size of a project may be smaller. If the actual size exceeds the reserved size, an error message is displayed at compile.

The online change feature requires two code buffers of the same size. If you switch off this feature, only one buffer is needed. To do so, set the variable bNoOnlineChange = TRUE; in the function main() in main.c, and do not allocate memory for pcCodeArea1. In the programming system, switch off the online change feature in the General settings of the target settings. - The size of the communication buffers (send- and receive buffer and trace buffer) are defined in the file custom.h by default to 5000 bytes each: #define LZS_BUFFER_SIZE #define LZS_TRACE_BUFFER_SIZE 5000 4990

If you change the values, adapt BufferSize = 5000 tn the file CoDeSys.ini accordingly. To reduce the code buffer size, see also chapter 4.2.3, Customer specific user program data management.

4.20.4 Monitoring of system variables


System variables are variables that have a fixed address in the target system memory. They can be used for data exchange with other programs on the target system or to realise a kind of retain data (if they are mapped to retentive memory). System variables are defined in a file called sysvars.iec. See also chapter 5.1 System variables in this manual how to define system variables. For monitoring (reading, writing and forcing) of system variables, the standard CoDeSys monitoring services are used. The memory address of the system variables is passed in the online service in 2 WORDs (normally used for POURef and Offset): unsigned short wPOURef: unsigned short wOffset: Example: In the sysvars.iec file, we assume a system variable declaration like this: Otto: DWORD 16#00401704 In the above example, the values would be like this: unsigned short wPOURef: 16#8040
tech_doc_e.doc / V1.2

Hi-Word of the address with highest bit set. Lo-Word of the address.

unsigned short wOffset: 16#1704 The highest bit of the Hi-word is set to distinguish system addresses from normal IEC variables. For system addresses, the adaptation function CstMaskSysvar is called to resolve the address: BYTE *CstMaskSysvar(unsigned short wPOURef) This function has to convert the POURef to the Hi-Word of the system address in memory.

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 59 of 70

CoDeSys SP 32 Bit Embedded

1. The unsigned short input parameter wPOURef is shifted to the hiword of the unsigned long containing the memory address: unsigned long dwAddress = ((unsigned long)wPOURef) << 16; 2. By using the highest bit, either the lower memory area 16#0 to 16#7FFFFFF, or the upper memory area 16#80000000 to 16#FFFFFFFF can be accessed by system variables. The function CstMaskSysvar determines whether the lower or the higher memory are is used.
-

If your system variables are located in the lower memory area: To correct the address, the highest bit has to be reset to 0: dwAddress &= 0x7FFFFFFF; If your system variables are located in the upper memory area: The address is already correct and no adaptation has to be done.

The runtime system kernel then adds the offset to the result of the function.

4.20.5 Symbol management


This feature is optional and can be activated by the preprocessor switch INCLUDE_SYMBOLS. It allows external devices to connect to the runtime via the serial or tcpip communication protocol, and read variable addresses. The addresses can then be used to read the values of the variables. Therefore, the symbol file has to be downloaded to the runtime system (Enable the option in the CoDeSys target settings). The files rtssym.c and rtssym.h have have to be included to the runtime system workspace. To realize this feature, the service LZS_SYMBOL_READ was introduced to server.c. The service RTS_READ_VAR_DIRECT has been extended. This is the format of the services that can be used by the external device: a. A new service was defined: #define LZS_SYMBOL_READ Service: BYTE Service id (83) BYTE Count followed by a list of zero-terminated strings Answer: WORD: LZS_OK or error SRV_NO_SERVICE if the service is not defined (old systems) DWORD: current id of the IEC user programs. Can be used in the next READ_VARS_DIRCT services (see below). followed by a list of Structures of type LDATAREF. if a variable is not defined, the fields are set to 0xFFFF. DATAREF is defined as follows: typedef struct { WORD POURef; unsigned long unsigned long } LDATAREF_TYPE; 83

tech_doc_e.doc / V1.2

ulOffset; ulSize;

b. The service RTS_READ_VAR_DIRECT is extended. If the address-list is followed by the 4 byte program-id, the runtime checks this id against the current program id. If they are not equal, the answer is the 2 bytes error code SRV_NO_VARLIST.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 60 of 70

CoDeSys SP 32 Bit Embedded

If the ids are equal, the answer is as usual.

4.21 Access variables


4.21.1 Overview
Access variables give you the possibility to connect application variables to other tasks in the embedded environment. In some sense, they are something like network global variables, but the runtime system environment (or adaptation part) is responsible for exchanging the values. A access variable definition in CoDeSys consists of a local name, a remote name, data type and access flags. It must be in a VAR_ACCESS block in a global variable list. The local name can be used like a global variable name in any POU. Access variables are created like other global variables. The remote name is a string, used by the runtime environment to recognise the remote connection. Therefore, the access definitions are sent to the runtime. Example of a access variable definition: VAR_ACCESS Hugo: Remote1: BOOL READ_WRITE; END_VAR

4.21.2 Enabling the feature in the programming system


To use the access variables feature, enable the feature in the target description file: Features=FI_VARACCESS=1 If you supply a konfig.ini-file, the user can use a selection list to select the remote name of a variable. The konfig.ini file has to be located in the configuration directory. The format of the konfig.ini-File: The file is a text file in ascii format. It consists of one column definition line, followed by one or more variable definition lines. The column definition line defines the columns Label, T, GlobOffs, and Dim. Columns are separated by a |. Besides, more columns may be defined, but they are not used by the programming system. A ; indicates a line comment. The Label column contains the remote name of the access variables. GlobOffs is displayed in the selection list, but not used further. T is the type definition column. It contains a integer number with the following meanings: 9: 4: 5: 1: 1: 1: 1: 1: 3: 2:
tech_doc_e.doc / V1.2

TYPE_BOOL TYPE_INT TYPE_WORD TYPE_DINT TYPE_UDINT TYPE_TIME TYPE_DATE TYPE_TOD TYPE_DWORD TYPE_REAL TYPE_STRING TYPE_BYTE

6: 0: Example:
|

The Dim column is used for array definitions.

Label

|GlobOffs|MK |T|Dim |C|Grp|Info

; This is a Comment 3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 61 of 70

CoDeSys SP 32 Bit Embedded

|AC_TEST1 |AC_TEST2

| |

1 2

|R |R

|1| |1|

|1| |1|

|Testnumber |Testsequence

| |

4.21.3 Download format


The access definitions are downloaded with the only services LZS_DLACCESSLIST and LZS_DLTASKACCESSLIST. LZS_DLACCESSLIST contains the list of access variables. LZS_DLTASKACCESSLIST contains a access variable list for each IEC task. The services are sent directly before a LZS_DOWNLOAD command. You can catch these commands in the CstPreComputeService functions. The commands are not handled in the core part of the runtime system. The format of LZS_DLACCESSLIST: Query:
Structure of a service Offset Size Description [bytes]

LZS_DLACCESSLIST (200) Dummy byte Count Remote Name Type

0 1 2 6 38

1 1 4 32 1

Service for access list download Dummy byte (0x77) to let the rest be even aligned Number of access variable definitions Remote name of access variable #1 (string, zero-terminated) Data type of access variable #1: 9: 4: 5: 1: 1: 1: 1: 1: 3: 2: 6: 0: TYPE_BOOL TYPE_INT TYPE_WORD TYPE_DINT TYPE_UDINT TYPE_TIME TYPE_DATE TYPE_TOD TYPE_DWORD TYPE_REAL TYPE_STRING TYPE_BYTE ACCESS_READ ACCESS_WRITE ACCESS_READ_WRITE

Direction

39

Access direction of variable #1: 0: 1: 2:

Ref Id
tech_doc_e.doc / V1.2

40 42 44

2 2

Reference id (Segment number) of access variable #1 Offset inside segment of access variable #1 Definitions of following access variables

Offset

Answer:

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 62 of 70

CoDeSys SP 32 Bit Embedded

Structure of a service

Offset

Size Description [bytes]

RTS_OK (0x0000) Count Ref Id Offset Error Code

0 2 6 8 10

2 4 2 2 4

OK acknowledgement Number of errors in access definition (0 indicates success) Reference id (Segment number) of error access variable #1 (if Cound > 0) Offset inside segment of error access variable #1 Error code for error access variable #1: IDS_ERR_ACCESSNAME IDS_ERR_ACCESSTYPE IDS_ERR_ACCESSLIST IDS_ERR_NODOWNLOAD 1 2 4 5

IDS_ERR_ACCESSIGNORED 3

14

Error results of following erroneous access variables

The format of LZS_DLTASKACCESSLIST: Query:


Structure of a service Offset Size [bytes] Description

LZS_DLTASKACCES 0 SLIST (203) Dummy byte Size Task Index Count Ref Id Offset Direction 1 2 6 10 14 16 18 20 14+Count*6 Answer:
Structure of a service Offset

1 1 4 4 4 2 2 2

Service for task access list download Dummy byte (0x77) to let the rest be even aligned Size of definitions (including Size, without command and dummy byte) Index of first task using access variables Number of task access definitions for this task Reference id (Segment number) of access variable #1 Offset inside segment of access variable #1 Access direction of access variable #1 Definitions of following task access variables Definitions of following tasks

Size [bytes]

Description

RTS_OK (0x0000)
tech_doc_e.doc / V1.2

0 2

2 4

OK acknowledgement Number of errors in access definition (0 indicates success)

Count

4.22 Enabling SoftMotion


To enable the runtime to be used with the CoDeSys SoftMotion feature, set the #define SM in your compiler environment.
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 63 of 70

CoDeSys SP 32 Bit Embedded

4.23 Enabling the password functionality


To enable the runtime to support the feature password on the controller, set the #define INCLUDE_PASSWORD in your compiler environment. The password can be set with the plc-browser command setpwd, and it can be deleted with the plcbrowser command delpwd. If a password is defined, the first Login-Service is denied by the runtime (answer SRV_PASSWORD_NEEDED). CoDeSys then opens a dialog box to enter the password and re-sends the login-service. If the password is correct, the login service is performed. All services are now handled as normal. The password is stored in the file PASSWORD.TXT on the controller.

4.24 Support different target ids in one controller


Runtime systems and CoDeSys Version 2.3 newer than March 1, 2003, support the usage of different target ids on one controller. To use this, a target setting in the CoDeSys target description file has to be defined, and adaptations in the runtime system in the function CstGetTargetIds() have to be made. The target setting is: TargetMagic=<Magic Number> Use different magic numbers in your different target files. Example: Target file 1: Id=100 TargetMagic= 16#12345 Target file 2: Id=101 TargetMagic= 16#22114 If defined in the target file, the magic number is sent to the controller with the service CHECKTARGETID. It is copied to the global variable g_ulMagic, which is defined in server.c. You can use this variable in the adaptation function CstGetTargetIds() to determine which target id to return. Example: void CstGetTargetIds(unsigned long* ulTargetId, unsigned long* ulHookId) { If (g_ulMagic == 0x12345) *ulTargetId = 100; else /* if (g_ulMagic == 0x22114) */ *ulTargetId = 101; } This method allows to login to one controller using different target files.

4.25 Supporting SysLibDirect.lib and #-Addresses


tech_doc_e.doc / V1.2

The so-called #-addresses allow to map variable accesses in the IEC program to function calls. By that the user can perform system access with the aid of easy understandable variable accesses. The CoDeSys programming interface supports the usage of #-addresses in the format #MW<hi>.<lo> . For example declarations like the following one are possible: Otto AT #MW17.4: INT; If a variable declared in that way is used in the program, a function call will be generated automatically. This call is not visible for the user. Depending on whether a Read or a Write access to the variable will
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 64 of 70

CoDeSys SP 32 Bit Embedded

be done, a Read or Write function will be called. For the different generic data types there exist corresponding functions. The required functions are defined in the library SysLibDirect.lib. For Read accesses there are functions of type DirectReadBool, for Write accesses of type DirectWriteBool. The functions must be implemented in the runtime system as external C-library functions. When the function is called, the IEC-address is passed to the function coded in a 32-bit value. The address part before the dot can take values from 0 to 65535, The address part after the dot can take values from 0 to 65535. For the supported IEC datatypes and functions the following assignments are valid: BOOL: BYTE: SINT: USINT: WORD: INT: UINT: DWORD: DINT: UDINT: REAL: LREAL: STRING: DirectReadBool resp. DirectWriteBool DirectReadByte resp. DirectWriteByte

DirectReadWord resp. DirectWriteWord

DirectReadDWord resp. DirectWriteDWord

DirectReadLReal resp. DirectWriteLReal DirectReadString resp. DirectWriteString

Further datatypes like structures or arrays are not supported. The components have to be accessed individually. The functions have the following syntax, the examples are shown for the BOOL functions:

4.25.1 Syntax of the Read function


Read function in IEC syntax: FUNCTION DirectReadBool : BOOL VAR_INPUT dwOffset: DWORD; END_VAR Read function in C syntax: BOOL DirectReadBool(unsigned long dwOffset); The function should return the requested value as return value. The offset is used as an identifier. DwOffset is calculated from the #-address like shown in the following: dwOffset = (hi << 16) + lo + 1; For our example from chapter 2.3.11: #17.4 -> hi is 17 and lo is 4. The offset is calculated like follows: dwOffset = (0x11 = = = << 16) + 0x4 + 0x1 0x00110000 + 0x04 + 0x01 0x0011005 (hex) 69637 (decimal)

tech_doc_e.doc / V1.2

For the other datatypes just replace datatype BOOL by that which is actually used. The offset is always given in a DWORD.

4.25.2 Syntax of the Write function


Write function in IEC syntax:
3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 65 of 70

CoDeSys SP 32 Bit Embedded

FUNCTION DirectwriteBool : BOOL VAR_INPUT dwOffset: DWORD; Value: BOOL; END_VAR Write function in C-Syntax: BOOL DirectWriteBool(unsigned long dwOffset, BOOL Value); The function gets the offset and the value which should be written. The offset is used as an identifier and is calculated like described for the Read function. For the other datatypes just replace datatype BOOL by that which is actually used. The offset is always given in a DWORD.

4.26 Parameter Manager


CoDeSys 2.3 SP 2 and newer contain the new parameter manager, which is an extension of the further object dictionary editor. CoDeSys sends the parameter definitions to the controller, and also monitors parameter values. The runtime system contains interface functions, where the downloaded description is passed to the adaptation part, and where the address of the parameter is retrieved for monitoring. To enable the parameter download services in the runtime system, set the compiler flag INCLUDE_OD. The following interface functions have to be defined in the custom part. Main.c contains a sample implementation of them. int CstPMDownload(char *pucData, unsigned long ulDataSize) /* Data contains ItemHeader | ColumnDescription | Lines | ValueTable */

int CstPMDownloadInitiate(char *pucData, unsigned long ulDataSize) /* Indicates the start of a PM download */

int CstPMGetAddress(MonDescIndexSubIndex *pmdisi , unsigned char** ppbyAddress , unsigned int* pnSize, int* piBitOffset) /* Uded for monitoring of PM values */

int CstPMServiceEnd(unsigned long ulService) /* Indicates the end of a PM download */

4.26.1 Download of parameter description


After program download, CoDeSys also downloads the parameter description. The runtime contains a rudimentary object dictionary as a example, but it is assumed that the parameters are stored in the adaptation part of the runtime. The parameter description is downloaded in several blocks, if necessary. For each block, a function in the adaptation part is called. If you want to process the downloaded data, implement the function according your needs. This is the function: int CstPMDownload(char *pucData, unsigned long ulDataSize);

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 66 of 70

CoDeSys SP 32 Bit Embedded

pucData contains the downloaded data. ulDataSize contains the size of the block. Return 1 if the data was processes successful, else return 0. The downloaded data contains of: The structure OD_ItemHeader The structure OD_ColumnDescription The value table (one 4-byte-entry for every field in the parameter manager table) The value buffer (for data in the parameter manager table that exceeds the size of 4 bytes) For further details, see the document TSP_Creating_E.pdf.

4.26.2 Monitoring of parameter values


CoDeSys monitors the values of variable entries of the OD. To realize this, the runtime calls the following function: int CstPMGetAddress(MonDescIndexSubIndex *pmdisi, unsigned char** ppbyAddress, unsigned int* pnSize, int* piBitOffset) pmdisi is a Pointer to a structure of type MonDescIndexSubIndex. It contains the Index and Subindex of the parameter values to monitor. pbyAddress is a pointer to a pointer to the value buffer. Set *ppbyAddress to the byte address of the parameter value. pSize is a pointer to a integer value that contains the size of the parameter. If *pnSize is 0, the size is one bit. In this case, set *ppbyAddress to the byte address of the value, and *pBitOffset to the bit offset inside the byte. In the other cases, the size in bytes is given. pBitOffset is a pointer to a integer, where you can store the bit offset of the values address, if *pnSize is 0. Return 1 if the address of the parameter value could be retrieved, else return 0.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 67 of 70

CoDeSys SP 32 Bit Embedded

CoDeSys programming system

5.1

System variables

System variables are variables that have a fixed address in the target system memory. They can be used for data exchange with other programs on the target system or to realise a kind of retain data (if they are mapped to retentive memory). System variables are defined in a file called sysvars.iec. You can change this name with the entry SysVarsFile=<filename> in the target file. The directories where the file is looked for are (in this order):
-

Target specific library directory (from target file) Project specific library directory (set in options dialog box) Common library directory (from ini-File) Target specific configuration directory (from target file) Project specific configuration directory (set in options dialog box) Common configuration directory (from ini-File)

Only the first file found is taken. The file contains declarations of system variables. The format is as follows: <Var1>: <Type1> <Address1> <Var2>: <Type2> <Address2> <Var3>: <Type3> <Address3> with: Var: Variable name Type: IEC Data type Address: Address in target hardware, given in IEC 61131-3 hex constant format Example: Otto: DWORD 16#00401704 You can define such a file for every different target hardware with a different memory layout. In the input help dialog box, these variables appear as system variables. They can be used in the program as any other variable. They are directly accessed at the given memory location. For example, the ST-expression Otto := 9; Would result in the following 68000 or ColdFire assembler-code: move.l #$9,$401704 For system addresses, the memory address given in the sysvars.iec-file is passed to the runtime system in 2 WORDs like this: unsigned short wPOURef: Hi-Word of the address with highest bit set. unsigned short wOffset: Lo-Word of the address.
tech_doc_e.doc / V1.2

The highest bit is set to determine it is a system address. In this case, the function CstMaskSysvar is called. In the above example, the values would be like this: unsigned short wPOURef: 16#9234 unsigned short wOffset: 16#5678

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 68 of 70

CoDeSys SP 32 Bit Embedded

With this method, either the lower memory area 16#0 to 16#7FFFFFF, or the upper memory area 16#80000000 to 16#FFFFFFFF can be accessed by system variables. In the function CstMaskSysvar it is determined whether the lower or the higher memory are is used. If the lower memory area is used: To correct the address, the highest bit has to be set to 0 again. If the higher memory area is used: The address is already correct and no adaptation has to be done. In both cases, the unsigned short is shifted to the hiword of the unsigned long containing the memory address. The runtime system kernel then adds the offset. In main.c you find a example for the CstMaskSysvar function.

5.2

Defining interrupt Tasks

If you want to use the interrupt task feature (see chapter 4.13 Interrupt Tasks in this manual) of the runtime system, you have to do the following: Define the interrupt names In the target description file, define the names of the interrupt as follows: SystemEvent1=Timer_Interupt10ms SystemEvent2=Input_Interupt7 ... For compatibility with older version, you can also define the interrupt names in the file CoDesys.ini, but the definitions in the target file have higher priority. The target file allows you to define target-specific interrupts, while the ini-File is common to all targets. Up to 100 Interrupts can be defined. Note: The index is 1-based. Use the interrupt names in the task configuration In the task configuration, you can use the interrupt names in the single event input field of the task attributes dialog box. (Normally, only Boolean IEC variables can be used here). Tasks that have such an interrupt name as event are not called by the standard CoDeSys non-preemptive task mechanism. For these tasks, a data structure is sent to the target system, so it can call these functions out of an interrupt.

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 69 of 70

CoDeSys SP 32 Bit Embedded

Change History
Version Description Editor Date

Issued Various modifications, change states see version history in data base

TZ

14.10.2002

1.0 1.0 1.1 1.1 1.2 1.3 1.3 1.4 1.5 1.6 1.7 2.0 2.1 3.0

Added INCLUDE_EVENTS, ok for Release Formal rework, new doc template, start of versioning, Release Support for ARM Philips LPC2294 and Tricore (Chap. 1, 3.3, 4) ReceiveBufferLen (Chap. 4.8.1(#5846) Formal Review, Release Infineon Tricore support bRetainInvalidIfIdentityMissing, Chapt.4.11 (#6571) Formal Review, Release Added system architecture graphics Added chapter for CAN communication Added virtual commands for CstPreComputeService Added Security Warning Formal Review, Release Added security warning conc. PLCBrowser command (#11004) Formal Review, Release

TZ MN TZ MN FL TZ MN TZ TZ TZ TZ MN MN MN

18.08.2005 16.08.2005 08.03.2006 04.05.2006 14.07.2006 20.07.2006 14.09.2006 14.07.2007 03.12.2008 23.23.2009 30.10.2012 31.10.2012 20.02.2013 21.02.2013

tech_doc_e.doc / V1.2

3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc

Page 70 of 70

You might also like