CoDeSys SP 32 Bit Embedded - E
CoDeSys SP 32 Bit Embedded - E
tech_doc_e.doc / V1.2
Page 1 of 70
CONTENT
1 2
OVERVIEW INTRODUCTION
2.1 2.2 Components of the PLC program environment Functions of the components
6 7
7 8
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
Scaling the runtime system Format of the bootproject file (DEFAULT.PRG) Header Code Task configuration Hardware configuration IO description
3.7.6
Project Info
30
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
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
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
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
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
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
Access variables Overview Enabling the feature in the programming system Download format
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.26.1 4.26.2
68
Page 4 of 70
5.1 5.2
68 69
CHANGE HISTORY
70
tech_doc_e.doc / V1.2
Page 5 of 70
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
Page 6 of 70
Introduction
2.1
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
PLCprogram
Process map
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
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
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
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.
Page 9 of 70
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
READ_VAR_DIRECT (stateless monitoring service for reading variable values) WRITE_VAR_DIRECT (stateless monitoring service for writing variable values)
3.2
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
The CoDeSys 32 bit embedded runtime consists of the following code modules:
tech_doc_e.doc / V1.2
syslibxxx.c Interuptxxx.c
rtsbrows.c serverex.c
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
Page 12 of 70
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:
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.
rtscopyna.c rtsenctarget.c
Page 13 of 70
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:
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).
Main.c:
5. I/O-Configuration
RtsCfg.c:
Processes the downloaded data of the PLC configuration of loads them to a data structure.
Interupt.c:
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
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
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
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
Query sent by CoDeSys V 2.3 SP3 and newer: Structure LOGIN_TYPE in RtsSrv.h
Structure of the service Offset Size [Bytes] Description
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
Page 16 of 70
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
34 38 42 46 50
4 4 4 4 4
dwProcessor
54
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"
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
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
3.5.2.2
Logout
Disconnecting. Query:
Structure of a service Offset Size [Bytes] Description
Offset
Size [Bytes]
Description
RTS_OK (0x0000)
OK acknowledgement
3.5.2.3
Start
Offset
Size [Bytes]
Description
RTS_OK (0x0000)
OK Acknowledgement
3.5.2.4
Stop
RTS_STOP Answer:
Structure of a service
Stop PLC
Offset
Size [Bytes]
Description
RTS_OK (0x0000)
OK Acknowledgement
3.5.2.5
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
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
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
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).
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
3.5.2.7
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
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
Page 21 of 70
X+0 2 4 8
2 2 4 4
#define MON_CONSTANT Used for monitoring of constant values. MON_CONSTANT nDescSize nSize Constant Value X+0 2 4 8 2 2 4
0xFFFE
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
0xFFFB
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
Offset Size
14 18
4 4
#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
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
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
Page 23 of 70
3.5.2.9
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
0 1 3 5
1 2 2 n
Offset
Size [bytes]
Description
0 2
2 1
2 4
2 n
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
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
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
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
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
Page 25 of 70
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
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
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
Offset
Size [Bytes]
Description
wReply
RTS_OK 0x0000 If block could be read. SRV_FILE_ERROR 0x0050 If file could not be read.
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
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
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.
Page 27 of 70
3.5.4.2
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. */
Page 28 of 70
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
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
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
3.7
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
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
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
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
tech_doc_e.doc / V1.2
Page 31 of 70
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
Page 32 of 70
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
Page 33 of 70
4.1
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
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
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.
Page 35 of 70
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
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
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
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
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
- 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
4.2
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
#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
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
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
4.3
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
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
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 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
Page 42 of 70
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
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
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
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
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
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
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
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
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
(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
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
4.7
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
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
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
TRG_186_CPU
4.7.4
Infineon Tricore
4.8
4.8.1
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
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
#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
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
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.
Page 49 of 70
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
Page 50 of 70
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.
tech_doc_e.doc / V1.2
Page 51 of 70
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
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>;
The function CstRetainRestore must be empty (see above). All accesses to retain data will be relocated to the buffered area.
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
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.
Page 54 of 70
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
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.
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.
Page 57 of 70
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.
tech_doc_e.doc / V1.2
Page 58 of 70
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.
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.
Page 59 of 70
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.
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
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:
|
Label
; This is a Comment 3S-Smart Software Solutions GmbH CoDeSys SP 32 bit embedded_E1.doc Page 61 of 70
|AC_TEST1 |AC_TEST2
| |
1 2
|R |R
|1| |1|
|1| |1|
|Testnumber |Testsequence
| |
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
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:
Page 62 of 70
Structure of a service
Offset
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
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
Count
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
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
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:
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.
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.
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 */
tech_doc_e.doc / V1.2
Page 66 of 70
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.
tech_doc_e.doc / V1.2
Page 67 of 70
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
Page 68 of 70
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
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
Page 69 of 70
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
Page 70 of 70