emModbus CPU independent Modbus stack for embedded applications User & Reference Guide Document: UM14001 Software version: 1.00 Revision: 2 Date: July 1, 2014 A product of SEGGER Microcontroller GmbH & Co. KG www.segger.com 2 Disclaimer Specifications written in this document are believed to be accurate, but are not guaranteed to be entirely free of error. The information in this manual is subject to change for functional or performance improvements without notice. Please make sure your manual is the latest edition. While the information herein is assumed to be accurate, SEGGER Microcontroller GmbH & Co. KG (SEGGER) assumes no responsibility for any errors or omissions. SEGGER makes and you receive no warranties or conditions, express, implied, statutory or in any communication with you. SEGGER specifically disclaims any implied warranty of merchantability or fitness for a particular purpose. Copyright notice You may not extract portions of this manual or modify the PDF file in any way without the prior written permission of SEGGER. The software described in this document is furnished under a license and may only be used or copied in accordance with the terms of such a license. (c) 2014 SEGGER Microcontroller GmbH & Co. KG, Hilden / Germany Trademarks Names mentioned in this manual may be trademarks of their respective companies. Brand and product names are trademarks or registered trademarks of their respective holders. Contact address SEGGER Microcontroller GmbH & Co. KG In den Weiden 11 D-40721 Hilden Germany Tel.+49 2103-2878-0 Fax.+49 2103-2878-28 E-mail: support@segger.com Internet: http://www.segger.com UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 3 Manual versions This manual describes the current software version. If any error occurs, inform us and we will try to assist you as soon as possible. Contact us for further information on topics or routines not yet specified. Print date: July 1, 2014 Software Revision Date 1.00 2 140601 MC Updated file information. 1.00 1 140314 MC "Getting Started", "Tasks and Interrupt usage". Spelling. 1.00 0 140224 MC Initial version. UM14001 User & Reference Guide for emModbus By Description (c) 2014 SEGGER Microcontroller GmbH & Co. KG 4 UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 5 About this document Assumptions This document assumes that you already have a solid knowledge of the following: * * * * The software tools used for building your application (assembler, linker, C compiler) The C programming language The target processor DOS command line If you feel that your knowledge of C is not sufficient, we recommend The C Programming Language by Kernighan and Richie (ISBN 0-13-1103628), which describes the standard in C-programming and, in newer editions, also covers the ANSI C standard. How to use this manual This manual explains all the functions and macros that the product offers. It assumes you have a working knowledge of the C language. Knowledge of assembly programming is not required. Typographic conventions for syntax This manual uses the following typographic conventions: Style Used for Body Body text. Keyword Text that you enter at the command-prompt or that appears on the display (that is system functions, file- or pathnames). Parameter Parameters in API functions. Sample Sample code in program examples. Sample comment Comments in programm examples. Reference Reference to chapters, sections, tables and figures or other documents. GUIElement Buttons, dialog boxes, menu names, menu commands. Emphasis Very important sections. Table 1.1: Typographic conventions UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER SEGGER Microcontroller GmbH & Co. KG 6 SEGGER Microcontroller GmbH & Co. KG develops and distributes software development tools and ANSI C software components (middleware) for embedded systems in several industries such as telecom, medical technology, consumer electronics, automotive industry and industrial automation. SEGGER's intention is to cut software development time for embedded applications by offering compact flexible and easy to use middleware, allowing developers to concentrate on their application. Our most popular products are emWin, a universal graphic software package for embedded applications, and embOS, a small yet efficient real-time kernel. emWin, written entirely in ANSI C, can easily be used on any CPU and most any display. It is complemented by the available PC tools: Bitmap Converter, Font Converter, Simulator and Viewer. embOS supports most 8/16/32-bit CPUs. Its small memory footprint makes it suitable for single-chip applications. Apart from its main focus on software tools, SEGGER develops and produces programming tools for flash micro controllers, as well as J-Link, a JTAG emulator to assist in development, debugging and production, which has rapidly become the industry standard for debug access to ARM cores. Corporate Office: http://www.segger.com EMBEDDED SOFTWARE (Middleware) emWin Graphics software and GUI emWin is designed to provide an efficient, processor- and display controller-independent graphical user interface (GUI) for any application that operates with a graphical display. embOS Real Time Operating System embOS is an RTOS designed to offer the benefits of a complete multitasking system for hard real time applications with minimal resources. embOS/IP TCP/IP stack embOS/IP a high-performance TCP/IP stack that has been optimized for speed, versatility and a small memory footprint. United States Office: http://www.segger-us.com SEGGER TOOLS Flasher Flash programmer Flash Programming tool primarily for micro controllers. J-Link JTAG emulator for ARM cores USB driven JTAG interface for ARM cores. J-Trace JTAG emulator with trace USB driven JTAG interface for ARM cores with Trace memory. supporting the ARM ETM (Embedded Trace Macrocell). J-Link / J-Trace Related Software Add-on software to be used with SEGGER's industry standard JTAG emulator, this includes flash programming software and flash breakpoints. emFile File system emFile is an embedded file system with FAT12, FAT16 and FAT32 support. Various Device drivers, e.g. for NAND and NOR flashes, SD/MMC and CompactFlash cards, are available. USB-Stack USB device/host stack A USB stack designed to work on any embedded system with a USB controller. Bulk communication and most standard device classes are supported. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 7 Table of Contents 1 Introduction to emModbus ...............................................................................................9 1.1 1.2 1.3 The Modbus standard ............................................................................... 10 emModbus.............................................................................................. 14 Tasks and interrupt usage......................................................................... 16 2 Getting Started...............................................................................................................21 2.1 2.2 2.3 2.4 Installation ............................................................................................. 22 Upgrade a trial version ............................................................................. 23 Upgrade an embOS start project................................................................ 24 Create a project from scratch .................................................................... 29 3 Example applications .....................................................................................................31 3.1 Overview ................................................................................................ 32 4 Core functions................................................................................................................35 4.1 4.2 4.3 API functions .......................................................................................... 36 emModbus data structures ........................................................................ 64 Error codes ............................................................................................. 69 5 Configuring emModbus..................................................................................................71 5.1 Compile-time configuration ....................................................................... 72 6 Debugging......................................................................................................................75 6.1 6.2 6.3 Message output ....................................................................................... 76 Using a network sniffer to analyse ethernet communication problems ............. 81 Testing emModbus applications ................................................................. 82 7 OS Integration................................................................................................................83 7.1 7.2 General information ................................................................................. 84 OS layer API functions.............................................................................. 85 8 Resource usage.............................................................................................................97 8.1 Memory footprint..................................................................................... 98 UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 8 UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 9 Chapter 1 Introduction to emModbus This chapter provides an introduction to using emModbus. It explains the basic concepts behind emModbus. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 10 CHAPTER 1 1.1 Introduction to emModbus The Modbus standard The Modbus protocol was originally published in 1979 by Modicon (which later became Schneider Electric) and has since evolved into a standard communications protocol for industrial electronic devices. In 2004, Schneider transfered rights to the protocol to the Modbus Organization, which since is in charge of the open standard's further development. 1.1.1 Modbus message basics The modbus protocol is an application layer messaging protocol used for communications between devices that are connected to different types of buses or networks. It uses a master-slave-technique in which one device, the master, initiates transactions (called "queries"). Other devices, the slaves, respond by performing the action requested in the query or by supplying the requested data to the master. The protocol determines how each device will know its address, how it will recognize a message addressed to it, how it will determine the kind of action to be taken and how it will extract data or any other information contained in the message. It also determines how slaves construct and send reply messages. 1.1.1.1 Message frames Several Modbus messaging formats ("frames") exist and are used for different purposes and environments, though many of them are not compliant to the Modbus standard. The standard-compliant frame variants are listed in the following table: Protocol RTU ASCII Modbus/TCP Description Original Modbus standard. Binary data is sent via serial connections such as RS-232 or similar. Similar to RTU. Instead of raw binary, data is encoded in ASCII. Binary data is encapsulated in a TCP frame and sent via network connections such as Ethernet. This variant can also be used with UDP instead of TCP and is then called Modbus/UDP. Table 1.1: Standard-compliant variants of Modbus message frames When using ASCII frames or RTU frames via serial connection, parameters such as baud rate and parity bits must be set correctly for all connected devices. When using Modbus/TCP, setting these parameters is not required, but correct IP address and port number are required instead. The standard port number for Modbus/TCP is port 502. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 11 1.1.1.2 Message fields Although the different message frames are each handled differently by the protocol, RTU frames and ACSCII frames each include the same four fields. Field 2 and 3 constitute the Protocol Data Unit (PDU), which is part of Modbus/TCP message frames as well, while all 4 fields together constitute the Application Data Unit (ADU): Field 1 includes the address of a slave device, either indicating the slave that is designated to receive the message from its master, or indicating the slave that sent the message towards its master. This address, which is refered to as "unit ID" or "slave address", is a number from 1 to 247 and is uniquely assigned to a single slave device, allowing these devices to listen for messages containing their specific ID. Additionaly, ID 0 is used to send broadcasts and ID 255 usually is reserved for communications with a Modbus gateway. Field 2 includes a function code, which, when sent by a master, indicates the instruction a slave is asked to carry out. When sent by a slave, on the other hand, the function code indicates the instruction the slave is responding to. Field 3 contains variable amounts of data, e.g. certain data addresses a master wants a slave to read, or the data a slave is reporting towards its master. In field 4 Modbus messages carry a checksum to allow their respective recipients to determine wether a message has arrived completely. RTU message frames When using RTU frames, each byte contained in a message is sent as binary data. The main advantage of this mode is its greater density, allowing better data throughput for the same baud rate when compared to ASCII frames. To indicate the start of an RTU frame, the ADU is preceded by a silent interval of at least 3.5 Byte times, hence the length of that interval depends on the configuration of the devices in use. To indicate the end of a frame, another silent interval of 3.5 Byte times succeeds the ADU. Note that one single interval of silence can, at the same time, indicate the end of one frame and the beginning of another frame. RTU frames use Cyclic Redundancy Checks (CRC). A complete RTU frame can be depicted as shown below: UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 12 CHAPTER 1 Introduction to emModbus ASCII message frames When using ASCII frames, each byte contained in a message is encoded and sent as two ASCII characters. This allows time intervals of up to one second to occur between characters without causing an error. To indicate the start of a frame, the ADU is preceded by a single character, which always is a colon (0x3A). To indicate the end of a frame, another two trailing characters succeed the ADU, which always are "Carriage Return" and "Line Feed" (0x0D and 0x0A, respectively). ASCII frames use Longitudinal Redundancy Checks (LRC). A complete ASCII frame can be depicted as shown below: Modbus/TCP message frames When using Modbus/TCP frames, an additional header called "Modbus Application Header" precedes the PDU. Its four fields contain the transaction ID, the protocol ID, the length of the following frame and the slave address. The transaction ID is a number from 0 to 65,535 encoded into two bytes. A master device will increment this number for every request it sends to a slave, while slaves simply echoe the number back to their master. By doing so, the master is able to decide wether messages got lost or delayed in transmission. The protocol ID is a two-byte value, too, but is always 00 00. The length field consists of two more bytes indicating the length of the remaining message. Finally the address field contains a unit ID, similar to that included in ASCII frames or RTU frames. But with Modbus/TCP, it does not necessarily serve a purpose, as the IP address is used instead to indicate the message's recipient. However, the unit ID is still part of the message and might be used to decide whether a device forwards a message onto a serial connection, thereby allowing devices without networking capabilities to be used in these environments, too. A complete Modbus/TCP frame can be depicted as shown below: UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 13 1.1.2 Modbus data basics Modbus was specifically designed for usage in supervisory control and data acquisition systems, connecting a supervisory computer with one or several remote terminal units (RTU). Therefore, data types used in Modbus communications have been named according to that implementation. When the Modbus protocol was extended in 1999 to include TCP frames via Ethernet, the data types' names were left unchanged. Four primary data types are used by Modbus: Data type Description Coil Discrete Input Holding Register Input Register single bit, alterable single bit, provided 16-bit, alterable by 16-bit, provided by by by an an an application program, read-write an I/O system, read-only application program, read-write I/O system, read-only Table 1.2: Primary Modbus data types For referencing data, Modbus uses a concept of data tables, which are arrays or blocks of memory used to store data. This data can then be referenced by using data table addresses, represented by simple integer values between 0 and 65,535. While it is fully standard-compliant to implement up to 65,536 addresses for each data type, the number of addresses implemented in a particular device usually is much lower. Therefore, Modbus implementations might even assign specific address ranges of a single table to each type of data. While the Modbus standard itself does not specify distinct address ranges, typical Modbus implementations utilize the following assignments: * * * * 0xxxx-ranged 1xxxx-ranged 3xxxx-ranged 4xxxx-ranged addresses addresses addresses addresses store store store store coils. discrete inputs. input registers. holding registers. Modbus uses a big-endian representation for data table addresses as well as for the actual data itself. Therefore, the most significant byte is sent first when a numerical quantity larger than a single byte is transmitted. For example * * (16-bits) 0x1234 gets send as 0x12 0x34 and (32-bits) 0x12345678 gets send as 0x12 0x34 0x56 0x78. In addition to single bit data types (e.g. representing boolean values) and 16-bit data types (e.g. representing integers), it is also possible to use large data types such as long integers, floating point numbers and strings by splitting them over several addresses. However, the Modbus standard does not stipulate this, hence it is up to the individual user to split and store data accordingly. 1.1.3 Further reading This guide explains the usage of the emModbus stack. It describes all functions which are required to build a Modbus application. For a deeper understanding of the official Modbus protocol, please refer to the following references. * Modbus Organization official website: http://www.modbus.org/ UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 14 CHAPTER 1 1.2 Introduction to emModbus emModbus emModbus is written in ANSI C and can be used on virtually any CPU. It combines a maximum of performance with a small memory footprint and comes with all features typically required by embedded systems. RAM usage has been kept to a minimum by smart buffer handling. 1.2.1 Features of emModbus Features of emModbus include: * * * * Easy to integrate. Low memory footprint. ANSI-C code is completely portable and runs on any target. Follows the SEGGER coding standards: Efficient and compact, yet easy to read, understand & debug. Supports ASCII, RTU and Modbus/TCP (and UDP) protocol. Sample applications for all protocols included. Kernel abstraction layer: can be used with or without any RTOS. Works out-of-the-box with embOS. Modbus/TCP can be used with standard socket interface and any TCP/IP stack. Works out-of-the-box with embOS/IP. Project for executable on PC for Microsoft Visual Studio available. * * * * * * * The following table shows the contents of the emModbus root directory: Directory Content Application\*.c Contains example applications to run emModbus with UART or embOS/IP. Config\*.* Contains the emModbus configuration files. Refer to Configuring emModbus on page 71 for further information. MB\*.* Contains the emModbus sources such as MB_Core.c, MB_CHANNEL.c, MB_MASTER.c and MB_SLAVE.c Util\*.c Contains optimized memcpy routines to speed up the stack. Windows\*.* Contains the source(s), project file(s) and a executable(s) to run emModbus on a Microsoft Windows host. Table 1.3: Supplied directory structure of emModbus shippings 1.2.2 emModbus requirements TCP/IP stack For usage of Modbus/TCP, emModbus requires a TCP/IP capable stack. emModbus can be used with any TCP/IP stack that supports BSD Standard Sockets. The shipment includes an implementation which uses the socket API of embOS/IP. Multi tasking Although emModbus can be used completely without an RTOS, it is recommended to use emModbus in a multi tasking system, at least when implementing a Modbus master. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 15 1.2.3 Development environment (compiler) The CPU used is of no importance; only an ANSI-compliant compiler complying with at least one of the following international standard is required: * * * ISO/IEC/ANSI 9899:1990 (C90) with support for C++ style comments (//) ISO/IEC 9899:1999 (C99) ISO/IEC 14882:1998 (C++) If your compiler has some limitations, let us know and we will inform you if these will be a problem when compiling the software. Any compiler for 16/32/64-bit CPUs or DSPs that we know of can be used; most 8-bit compilers can be used as well. * A C++ compiler is not required, but can be used. The application program can therefore also be programmed in C++ if desired. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 16 CHAPTER 1 1.3 Introduction to emModbus Tasks and interrupt usage emModbus can be used in an application in two different ways. * * With tasks dedicated to the stack. Without tasks dedicated to the stack. The following chapters provide information on these ways for both ASCII and RTU frames as well as for Modbus/TCP (or UDP) frames. 1.3.1 ASCII / RTU slave with tasks dedicated to the stack To use tasks dedicated to the stack is the simplest way to use emModbus with ASCII and/or RTU frames. The MB_SLAVE_Task handles housekeeping operations and evaluation of incoming frames. The "Store byte" operation is called and performed from within the Interrupt Service Routine, hence no additional task is required. Interrupt (ISR) emModbus slave (ASCII / RTU) Task Routine / Action MB_SLAVE_ Task Application tasks Rx MB stack Driver App. task 1 ... MB_SLAVE_ Exec() MB_OnRx() Evaluat e fram e Store byt e App. task n UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 17 1.3.2 ASCII / RTU slave without tasks dedicated to the stack emModbus ASCII and/or RTU frames can also be used without any task dedicated to the stack, if an application task calls MB_SLAVE_Exec() periodically. The "Store byte" operation is called and performed from within the Interrupt Service Routine. Interrupt (ISR) emModbus slave (ASCII / RTU) Task Routine / Action Rx Application tasks MB stack Driver App. task 1 ... MB_SLAVE_ Exec() MB_OnRx() Evaluat e fram e Store byt e App. task n UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 18 CHAPTER 1 1.3.3 Introduction to emModbus TCP / UDP slave with tasks dedicated to the stack To use tasks dedicated to the stack is the simplest way to use emModbus/TCP. The MB_SLAVE_Task handles housekeeping operations and evaluation of incoming frames. The "Read frame" operation is called and performed by another task, MB_SLAVE_PollChannel, which periodically polls for incoming frames. Interrupt (ISR) emModbus slave (TCP / UDP) Task Routine / Action MB_SLAVE_ Task Application tasks MB_SLAVE_ PollChannel MB stack Driver MB_SLAVE_ Exec() App. task 1 ... App. task n Evaluat e fram e UM14001 User & Reference Guide for emModbus Read frame (c) 2014 SEGGER Microcontroller GmbH & Co. KG 19 1.3.4 TCP / UDP slave without tasks dedicated to the stack emModbus/TCP can also be used without any task dedicated to the stack, if an application task consecutively calls MB_SLAVE_PollChannel() and MB_SLAVE_Exec() periodically. Interrupt (ISR) emModbus slave (TCP / UDP) Task Routine / Action MB_SLAVE_ PollChannel() Application tasks MB stack Driver 1.) App. task 1 ... App. task n MB_SLAVE_ Exec() 2.) Evaluat e fram e UM14001 User & Reference Guide for emModbus Read frame (c) 2014 SEGGER Microcontroller GmbH & Co. KG 20 CHAPTER 1 1.3.5 Introduction to emModbus emModbus master The emModbus master API is independent of the usage of any Real-time operating system. However, by utilizing an RTOS the emModbus interface becomes more easy and comfortable to integrate into any desired application. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 21 Chapter 2 Getting Started The first step in getting started with emModbus is to compile it for and run it on the target system. This chapter explains how to do this. In this document the IAR Embedded Workbench(R) IDE is used for all examples and screenshots, but every other ANSI C toolchain can be used as well. It is also possible to use makefiles; in this case, "add to the project" translates into "add to the makefile". UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 22 CHAPTER 2 2.1 Getting Started Installation emModbus is typically shipped as a .zip file in electronic form. In order to install emModbus, extract it to any folder of your choice, preserving the directory structure of the .zip file. To create a running emModbus project, there are 3 different ways available: * * * Upgrade a trial version by adding source code. Upgrade an embOS start project. Create a project from scratch. The following example procedures describe each of these ways. They focus on integrating an emModbus slave device using Modbus/TCP frames, but any other emModbus project can be created as well by following the same steps. emModbus via TCP is optimized to be used with embOS/IP, SEGGER's TCP/IP stack. However, emModbus can be used with any other TCP/IP stack as well. Note that when using ASCII frames or RTU frames, the integration of a TCP/IP stack is not required and should be omitted for smaller code size. Similarly, if no real-time operating system is required, the integration of an RTOS should be omitted as well. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 23 2.2 Upgrade a trial version Various trial packages for different target hardware are available at SEGGER's website. Note that not all trial packages currently available contain a trial of emModbus. If you are interested in a specific package that does not contain emModbus yet, feel free to contact us. Including emModbus in a trial package can be done in short time. Additionally, trial packages that do not contain embOS/IP do lack an appropiate TCP/IP stack, which is required for Modbus/TCP frames. However, ASCII frames and RTU frames might be used regardless of a TCP/IP stack. Replace libraries with sources After downloading the trial package, extract the project contained in the .zip file to any folder of your choice and open the workpace/project file. Copy the source files from the folder MB of your emModbus shipment into the folder MB of your downloaded package, add the files to the project and exclude the trial libraries from build. Build the project Build the project; it should compile without errors and warnings. If any problem is encoutered during the build process, checking the include paths and project configurations is advisable as first step. When done building, download the output into the designated target and start the application. Test the project We recommend testing emModbus devices by using their respective counterparts, e.g. using a emModbus/TCP master to test a emModbus/TCP slave and vice versa. Alternatively, devices can also be tested with a desktop computer running an appropiate Modbus application. Refer to Testing emModbus applications on page 82 for additional information. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 24 CHAPTER 2 2.3 Getting Started Upgrade an embOS start project Begin with a sample project for embOS, SEGGER's real-time operating system, then include embOS/IP and emModbus into the project. The emModbus default configuration is preconfigured with valid values, which match the requirements of most applications. Procedure to follow Integration of emModbus is a relatively simple process, which consists of the following steps: * * * * Step Step Step Step 1: 2: 3: 4: Open an embOS start project. Add embOS/IP to the start project. Add emModbus to the start project. Build the project. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 25 2.3.1 Step 1: Open an embOS start project We recommend that you use one of the supplied embOS start projects for your target system. Compile the project and run it on your target hardware. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 26 CHAPTER 2 2.3.2 Getting Started Step 2: Adding embOS/IP to the start project Add all source files in the following directories to your project: * * * Config IP UTIL (optional) The Config folder includes all configuration files of embOS/IP. The configuration files are preconfigured with valid values that match the requirements of most applications. Add the hardware configuration IP_Config_.c supplied with the driver shipment. If your hardware is currently not supported, use the example configuration file and the driver template to write your own driver. The example configuration file and the driver template is located in the Sample\Driver\Template folder. The Util folder is an optional component of the embOS/IP shipment. It contains optimized MCU and/or compiler specific files, for example an optimized memcopy function. Replace BSP.c and BSP.h of your embOS start project Replace the BSP.c source file and the BSP.h header file used in your embOS start project with the one which is supplied with the embOS/IP shipment. Some drivers require a special functions which initializes the network interface of the driver. This function is called BSP_ETH_Init(). It is used to enable the ports which are connected to the network hardware. All network interface driver packages include the BSP.c and BSP.h files irrespective if the BSP_ETH_Init() function is implemented. Configuring the include path The include path is the path in which the compiler looks for include files. In cases where the included files (typically header files, .h) do not reside in the same directory as the C file to compile, an include path needs to be set. In order to build the project with all added files, you will need to add the following directories to your include path: * * * Config Inc IP UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 27 2.3.3 Step 3: Adding emModbus to the start project Add all source files in the following directories to your project: * * * Config MB UTIL (optional) The Config folder includes all configuration files of emModbus. The configuration files are preconfigured with valid values, which match the requirements of most applications. Configuring the include path The include path is the path in which the compiler looks for include files. In cases where the included files (typically header files, .h) do not reside in the same directory as the C file to compile, an include path needs to be set. In order to build the project with all added files, you will need to add the following directories to your include path: * * Config MB Select the start application For quick and easy testing of your emModbus integration, start with the code found in the folder Application. Add one of the applications to your project (for example OS_IP_MB_SlaveTCP.c). UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 28 CHAPTER 2 2.3.4 Getting Started Step 4: Build the project Build the project Build the project; it should compile without errors and warnings. If any problem is encoutered during the build process, checking the include paths and project configurations is advisable as first step. When done building, download the output into the designated target and start the application. Test the project We recommend testing emModbus devices by using their respective counterparts, e.g. using a emModbus/TCP master to test a emModbus/TCP slave and vice versa. Alternatively, devices can also be tested with a desktop computer running an appropiate Modbus application. Refer to Testing emModbus applications on page 82 for additional information. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 29 2.4 Create a project from scratch To create a project from scratch, some steps have to be taken: * * * * A project or make file has to be created for the specific toolchain. The project configurations may need adjustments. The hardware routines have to be implemented. The path of any required header files has to be set as include path. To get the target up and running is a lot easier if taget hardware drivers are already available. In that case, these drivers can be used. Creating the project or make file The screenshot below gives an idea about a possible project setup: Build the project Build the project; it should compile without errors and warnings. If any problem is encoutered during the build process, checking the include paths and project configurations is advisable as first step. When done building, download the output into the designated target and start the application. Test the project We recommend testing emModbus devices by using their respective counterparts, e.g. using a emModbus/TCP master to test a emModbus/TCP slave and vice versa. Alternatively, devices can also be tested with a desktop computer running an appropiate Modbus application. Refer to Testing emModbus applications on page 82 for additional information. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 30 UM14001 User & Reference Guide for emModbus CHAPTER 2 Getting Started (c) 2014 SEGGER Microcontroller GmbH & Co. KG 31 Chapter 3 Example applications In this chapter, you will find a description of the emModbus example applications that are delivered together with the emModbus shipment. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 32 3.1 CHAPTER 3 Example applications Overview Example applications for emModbus are supplied in source code in the Application folder. These can be used for testing the correct installation and proper function of the device running emModbus. The following start application files are provided: File Description OS_IP_MB_MasterTCP.c Demonstrates the functionality of a Modbus Master device using TCP frames via network. OS_IP_MB_SlaveTCP.c Demonstrates the functionality of a Modbus Slave device using TCP frames via network. OS_MB_MasterASCII.c Demonstrates the functionality of a Modbus Master device using ASCII frames via serial connection. OS_MB_MasterRTU.c Demonstrates the functionality of a Modbus Master device using RTU frames via serial connection. OS_MB_SlaveASCII.c Demonstrates the functionality of a Modbus Slave device using ASCII frames via serial connection. OS_MB_SlaveRTU.c Demonstrates the functionality of a Modbus Slave device using RTU frames via serial connection. Table 3.1: emModbus example applications UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 33 3.1.1 OS_IP_MB_MasterTCP.c This sample demonstrates emModbus master functionalities using the Modbus/TCP protocol. It opens a channel and tries to establish a TCP connection to a Modbus slave device, which is known to the master by the slave's IP address as defined at the beginning of the file. The master also uses a given port for this connection, which is defined at the beginning of the file, too (e.g. port 502, the standard port for Modbus communications). When a connection is established, the master repeatedly sends queries to the slave, asking it to perform the function "write coil", and waits for appropiate responses. 3.1.2 OS_IP_MB_SlaveTCP.c This sample demonstrates emModbus slave functionalities using the Modbus/TCP protocol. It opens a channel and waits for incoming TCP connections on a given port, which is known to the slave as defined at the beginning of the file. When an incoming connection from a Modbus master device has been established, the slave reacts to queries it receives from the master. When ordered to write a coil (like the associated Modbus master sample does), the slave will toggle LEDs to signal its new status. 3.1.3 OS_MB_MasterASCII.c This emModbus sample demonstrates emModbus master functionalities using ASCII frames. It opens a channel and repeatedly sends queries to a Modbus slave device (specified by its slave ID as defined at the beginning of the file), asking it to perform the function "write coil", and waits for appropiate responses. 3.1.4 OS_MB_MasterRTU.c This emModbus sample demonstrates emModbus master functionalities using RTU frames. It opens a channel and repeatedly sends queries to a Modbus slave device (specified by its slave ID as defined at the beginning of the file), asking it to perform the function "write coil", and waits for appropiate responses. 3.1.5 OS_MB_SlaveASCII.c This sample demonstrates emModbus slave functionalities using ASCII frames. It opens a channel and waits for incoming queries from a Modbus master device. When ordered to write a coil (like the associated Modbus master sample does), the slave will toggle LEDs to signal its new status. 3.1.6 OS_MB_SlaveRTU.c This sample demonstrates emModbus slave functionalities using RTU frames. It opens a channel and waits for incoming queries from a Modbus master device. When ordered to write a coil (like the associated Modbus master sample does), the slave will toggle LEDs to signal its new status. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 34 UM14001 User & Reference Guide for emModbus CHAPTER 3 Example applications (c) 2014 SEGGER Microcontroller GmbH & Co. KG 35 Chapter 4 Core functions In this chapter, you will find a description of each emModbus core function. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 36 4.1 CHAPTER 4 Core functions API functions The table below lists the available API functions within their respective categories. Function Description Channel specific core functions MB_CHANNEL_Disconnect() Disconnects a connected channel. Master specific core functions Adds a master channel that uses ASCII MB_MASTER_AddASCIIChannel() frames via serial connection. Adds a master channel that uses TCP MB_MASTER_AddIPChannel() frames via network. Adds a master channel that uses RTU MB_MASTER_AddRTUChannel() frames via serial connection. De-Initializes master resources and MB_MASTER_DeInit() channels and removes the master endpoint from the global endpoint list. Initializes master resources and adds MB_MASTER_Init() master endpoint to global endpoint list. Master instruction set MB_MASTER_ReadCoils() Reads Coils from a slave. MB_MASTER_ReadDI() Reads Discrete Inputs from a slave. MB_MASTER_ReadHR() Reads Holding Registers from a slave. MB_MASTER_ReadIR() Reads Input Registers from a slave. MB_MASTER_WriteCoil() Writes a single coil to a slave. MB_MASTER_WriteCoils() Writes multiple coils to a slave. MB_MASTER_WriteReg() Writes a single register to a slave. MB_MASTER_WriteRegs() Writes multiple registers to a slave. Slave specific core functions Adds a slave channel that uses ASCII MB_SLAVE_AddASCIIChannel() frames via serial connection. Adds a slave channel that uses TCP MB_SLAVE_AddIPChannel() frames via network. Adds a slave channel that uses RTU MB_SLAVE_AddRTUChannel() frames via serial connection. De-Initializes the slave resources and MB_SLAVE_DeInit() channels and removes the slave endpoint from the global endpoint list. Loops over all slave channels once and MB_SLAVE_Exec() processes data when channel has been signalled ready. Initializes slave resources and adds slave MB_SLAVE_Init() endpoint to global endpoint list. Polled periodically for each slave channel MB_SLAVE_PollChannel() that requires requesting data instead of getting it via interrupt. Wrapper function that runs MB_SLAVE_Task() MB_SLAVE_Exec() in a task. Other core functions Function allowing to set a user defined MB_ConfigTimerFreq() timer frequency instead of the default frequency of 1kHz. Table 4.1: emModbus API function overview UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 37 Function MB_OnRx() MB_OnTx() MB_TimerTick() Description Function called by byte oriented transmission channels that receive an interrupt for new data received. Function called by byte oriented transmission channels once a Tx complete interrupt has been received. Function called on each timer interrupt to manage internal RTU timeout with serial channels using the RTU protocol. Table 4.1: emModbus API function overview (Continued) UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 38 CHAPTER 4 4.1.1 Core functions Channel specific core functions 4.1.1.1 MB_CHANNEL_Disconnect() Description Disconnects a previously connected channel, if the channel did any connect at all and is currently connected. Prototype void MB_CHANNEL_Disconnect ( MB_CHANNEL *pChannel ); Parameter Parameter pChannel Description [IN] Pointer to element of MB_CHANNEL. Table 4.2: MB_CHANNEL_Disconnect() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 39 4.1.2 Master specific core functions 4.1.2.1 MB_MASTER_AddASCIIChannel() Description Adds a master channel that uses ASCII frames via serial connection. Prototype void MB_MASTER_AddASCIIChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_UART *pConfig, const MB_IFACE_UART_API *pIFaceAPI, U32 Timeout, U8 SlaveAddr, U32 Baudrate, U8 DataBits, U8 Parity, U8 StopBits, U8 Port ); Parameter Parameter pChannel pConfig pIFaceAPI Timeout SlaveAddr Baudrate DataBits Parity StopBits Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_UART. [IN] Pointer to element of MB_IFACE_UART_API used to read/write from/to interface. [IN] Timeout [in ms] to wait for answer. [IN] Slave address to access. [IN] Desired baudrate in UART protocol. [IN] Number of data bits used in UART protocol. [IN] Parity used in UART protocol. [IN] Number of stop bits used in UART protocol. [IN] UART port number used by this channel. Table 4.3: MB_MASTER_AddASCIIChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_UART_API _IFaceAPI = { _SendByte, _Init, _DeInit, NULL, NULL, NULL, NULL, NULL, NULL }; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel(&_MBChannel, &_MBConfig, &_IFaceAPI, 3000, 1, 38400, 8, 0, 1, 0); // Add master channel do { ... } // e.g. master/slave communications } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 40 CHAPTER 4 Core functions 4.1.2.2 MB_MASTER_AddIPChannel() Description Adds a master channel that uses TCP frames via network. Prototype void MB_MASTER_AddIPChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_IP *pConfig, const MB_IFACE_IP_API *pIFaceAPI, U32 Timeout, U8 SlaveAddr, U32 IPAddr, U8 Port ); Parameter Parameter pChannel pConfig pIFaceAPI Timeout SlaveAddr IPAddr Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_IP. [IN] Pointer to element of MB_IFACE_IP_API used to read/write from/to interface. [IN] Timeout [in ms] to wait for answer. [IN] Slave address to access. [IN] IP address of slave. [IN] Slave port to connect to. Table 4.4: MB_MASTER_AddIPChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_IP_API _IFaceAPI = { NULL, NULL, NULL, _Send, _Recv, _Connect, _Disconnect, NULL, NULL }; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddIPChannel(&_MBChannel, &_MBConfig, &_IFaceAPI, 3000, 1, IP_BYTES2ADDR(192,168,1,80), 502); // Add master channel do { ... } // e.g. master/slave communications } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 41 4.1.2.3 MB_MASTER_AddRTUChannel() Description Adds a master channel that uses RTU frames via serial connection. Prototype void MB_MASTER_AddRTUChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_UART *pConfig, const MB_IFACE_UART_API *pIFaceAPI, U32 Timeout, U8 SlaveAddr, U32 Baudrate, U8 DataBits, U8 Parity, U8 StopBits, U8 Port ); Parameter Parameter pChannel pConfig pIFaceAPI Timeout SlaveAddr Baudrate DataBits Parity StopBits Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_UART. [IN] Pointer to element of MB_IFACE_IP_API used to read/write from/to interface. [IN] Timeout [in ms] to wait for answer. [IN] Slave address to access. [IN] Desired baudrate in UART protocol. [IN] Number of data bits used in UART protocol. [IN] Parity used in UART protocol. [IN] Number of stop bits used in UART protocol. [IN] UART port number used by this channel. Table 4.5: MB_MASTER_AddRTUChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_UART_API _IFaceAPI = { _SendByte, _Init, _DeInit, NULL, NULL, NULL, NULL, _InitTimer, _DeInitTimer }; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddRTUChannel(&_MBChannel, &_MBConfig, &_IFaceAPI, 3000, 1, 38400, 8, 0, 1, 0); // Add master channel do { ... } // e.g. master/slave communications } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 42 CHAPTER 4 Core functions 4.1.2.4 MB_MASTER_DeInit() Description De-Initializes the master resources and channels and removes the master endpoint from the global endpoint list. Prototype void MB_MASTER_DeInit ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 43 4.1.2.5 MB_MASTER_Init() Description Initializes the master resources and adds the master endpoint to the global endpoint list. Prototype void MB_MASTER_Init ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 44 CHAPTER 4 4.1.3 Core functions Master instruction set 4.1.3.1 MB_MASTER_ReadCoils() Description Reads coils from a slave. Prototype int MB_MASTER_ReadCoils ( MB_CHANNEL *pChannel, U8 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [OUT] Pointer to application buffer where to store the read data. [IN] Address in slave where to find the coils to access. [IN] Number of items to read. Table 4.6: MB_MASTER_ReadCoils() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U8 *_pData; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_ReadCoils(&_MBChannel, &_pData, 1000, 2);// Read Coils } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 45 4.1.3.2 MB_MASTER_ReadDI() Description Reads Discrete Inputs from a slave. Prototype int MB_MASTER_ReadDI ( MB_CHANNEL *pChannel, U8 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [OUT] Pointer to application buffer where to store the read data. [IN] Address in slave where to find the inputs to access. [IN] Number of items to read. Table 4.7: MB_MASTER_ReadDI() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U8 *_pData; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_ReadDI(&_MBChannel, &_pData, 1000, 2); // Read Discrete Input } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 46 CHAPTER 4 Core functions 4.1.3.3 MB_MASTER_ReadHR() Description Reads Holding Registers from a slave. Prototype int MB_MASTER_ReadHR ( MB_CHANNEL *pChannel, U8 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [OUT] Pointer to application buffer where to store the read data. [IN] Address in slave where to find the registers to access. [IN] Number of items to read. Table 4.8: MB_MASTER_ReadHR() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U8 *_pData; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_ReadHR(&_MBChannel, &_pData, 1000, 2);// Read Holding Register } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 47 4.1.3.4 MB_MASTER_ReadIR() Description Reads Input Registers from a slave. Prototype int MB_MASTER_ReadIR ( MB_CHANNEL *pChannel, U8 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [OUT] Pointer to application buffer where to store the read data. [IN] Address in slave where to find the registers to access. [IN] Number of items to read. Table 4.9: MB_MASTER_ReadIR() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U8 *_pData; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_ReadIR(&_MBChannel, &_pData, 1000, 2);// Read Input Register } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 48 CHAPTER 4 Core functions 4.1.3.5 MB_MASTER_WriteCoil() Description Writes a single coil to a slave. Prototype int MB_MASTER_WriteCoil ( MB_CHANNEL *pChannel, U16 Addr, U8 OnOff ); Parameter Parameter pChannel Addr OnOff Description [IN] Pointer to channel configured to interface a slave. [IN] Address in slave where to find the coil to access. [IN] Write Coil to 0: Off or 1: On. Table 4.10: MB_MASTER_WriteCoil() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_WriteCoil(&_MBChannel, 1000, 1); // Write Coil } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 49 4.1.3.6 MB_MASTER_WriteCoils() Description Writes multiple coils to a slave Prototype int MB_MASTER_WriteCoils ( MB_CHANNEL *pChannel, U8 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [IN] Pointer to application buffer where the values to write are stored. [IN] Address in slave where to find the coils to access. [IN] Number of items to write. Table 4.11: MB_MASTER_WriteCoils() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U8 _data; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_WriteCoils(&_MBChannel, &_data, 1000, 2);// Write Coils } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 50 CHAPTER 4 Core functions 4.1.3.7 MB_MASTER_WriteReg() Description Writes a single register to a slave. Prototype int MB_MASTER_WriteReg ( MB_CHANNEL *pChannel, U16 Data, U16 Addr ); Parameter Parameter pChannel Data Addr Description [IN] Pointer to channel configured to interface a slave. [IN] 16-bit data to write to register. [IN] Address in slave where to find the register to access. Table 4.12: MB_MASTER_WriteReg() parameter list Return value <0: Error 0: OK Example // // Static declarations // static int _result; static MB_CHANNEL _MBChannel; static U16 _data; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_WriteReg(&_MBChannel, _data, 1000); // Write Register } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 51 4.1.3.8 MB_MASTER_WriteRegs() Description Writes multiple registers to a slave. Prototype int MB_MASTER_WriteRegs ( MB_CHANNEL *pChannel, U16 *pData, U16 Addr, U16 NumItems ); Parameter Parameter pChannel pData Addr NumItems Description [IN] Pointer to channel configured to interface a slave. [IN] Pointer to application buffer where the values to write are stored. [IN] Address in slave where to find the registers to access. [IN] Number of items to write. Table 4.13: MB_MASTER_WriteRegs() parameter list Return value <0: Error 0: OK Example // // Static declarations // static volatile int _result; static MB_CHANNEL _MBChannel; static U16 _data; // // Code running in its own task // static void _MasterTask(void) { MB_MASTER_Init(); // Init master MB_MASTER_AddASCIIChannel( ... ); // Add master channel _result = MB_MASTER_WriteRegs(&_MBChannel, &_data, 1000, 2);// Write Registers } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 52 CHAPTER 4 4.1.4 Core functions Slave specific core functions 4.1.4.1 MB_SLAVE_AddASCIIChannel() Description Adds a slave channel that uses ASCII frames via serial connection. Prototype void MB_SLAVE_AddASCIIChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_UART *pConfig, const MB_SLAVE_API *pSlaveAPI, const MB_IFACE_UART_API *pIFaceAPI, U8 SlaveAddr, U8 DisableWrite, U32 Baudrate, U8 DataBits, U8 Parity, U8 StopBits, U8 Port ); Parameter Parameter pChannel pConfig pSlaveAPI pIFaceAPI SlaveAddr DisableWrite Baudrate DataBits Parity StopBits Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_UART. [IN] Pointer to elemtent of MB_SLAVE_API used to read/write from/to target. [IN] Pointer to element of MB_IFACE_UART_API used to read/write from/to interface. [IN] Slave address to listen on. [IN] Disable write access on this channel. [IN] Desired baudrate in UART protocol. [IN] Number of data bits used in UART protocol. [IN] Parity used in UART protocol. [IN] Number of stop bits used in UART protocol. [IN] UART port number used by this channel. Table 4.14: MB_SLAVE_AddASCIIChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_UART_API _IFaceAPI = { _SendByte, _Init, _DeInit, NULL, NULL, NULL, NULL, NULL, NULL }; static const MB_SLAVE_API _SlaveAPI = { _WriteCoil, _ReadCoil, _ReadDI, _WriteReg, _ReadHR, _ReadIR }; // // Code running in main task // void MainTask(void) { MB_SLAVE_Init(); // Init slave MB_SLAVE_AddASCIIChannel(&_MBChannel, &_MBConfig, &_SlaveAPI, &_IFaceAPI, 1, 0, 38400, 8, 0, 1, 0); // Add slave channel OS_CREATETASK( ... ); // Start slave task } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 53 4.1.4.2 MB_SLAVE_AddIPChannel() Description Adds a slave channel that uses TCP frames via network. Prototype void MB_SLAVE_AddIPChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_IP *pConfig, const MB_IFACE_IP_API *pIFaceAPI, U8 SlaveAddr, U32 DisableWrite, U32 IPAddr, U8 Port ); Parameter Parameter pChannel pConfig pSlaveAPI pIFaceAPI SlaveAddr DisableWrite IPAddr Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_IP. [IN] Pointer to elemtent of MB_SLAVE_API used to read/write from/to target. [IN] Pointer to element of MB_IFACE_IP_API used to read/write from/to interface. [IN] Slave address to access. [IN] Disable write access on this channel. [IN] Filter address. If set, only connections on this address should be accepted. [IN] Port that accepts connections for this channel. Table 4.15: MB_SLAVE_AddIPChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_IP_API _IFaceAPI = { NULL, _Init, _DeInit, _Send, _Recv, _Connect, _Disconnect, NULL, NULL }; static const MB_SLAVE_API _SlaveAPI = { _WriteCoil, _ReadCoil, _ReadDI, _WriteReg, _ReadHR, _ReadIR }; // // Code running in main task // void MainTask(void) { MB_SLAVE_Init(); // Init slave OS_CREATETASK( ... ); // Start slave task MB_SLAVE_AddIPChannel(&_MBChannel, &_MBConfig, &_SlaveAPI, &_IFaceAPI, 1, 0, 0, 502); // Add slave channel OS_CREATETASK( ... ); // Start polling task for this channel } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 54 CHAPTER 4 Core functions 4.1.4.3 MB_SLAVE_AddRTUChannel() Description Adds a slave channel that uses RTU frames via serial connection. Prototype void MB_SLAVE_AddASCIIChannel ( MB_CHANNEL *pChannel, MB_IFACE_CONFIG_UART *pConfig, const MB_SLAVE_API *pSlaveAPI, const MB_IFACE_UART_API *pIFaceAPI, U8 SlaveAddr, U8 DisableWrite, U32 Baudrate, U8 DataBits, U8 Parity, U8 StopBits, U8 Port ); Parameter Parameter pChannel pConfig pSlaveAPI pIFaceAPI SlaveAddr DisableWrite Baudrate DataBits Parity StopBits Port Description [IN] Pointer to element of MB_CHANNEL that is added to linked list. [IN] Pointer to element of MB_IFACE_CONFIG_UART. [IN] Pointer to elemtent of MB_SLAVE_API used to read/write from/to target. [IN] Pointer to element of MB_IFACE_UART_API used to read/write from/to interface. [IN] Slave address to listen on. [IN] Disable write access on this channel. [IN] Desired baudrate in UART protocol. [IN] Number of data bits used in UART protocol. [IN] Parity used in UART protocol. [IN] Number of stop bits used in UART protocol. [IN] UART port number used by this channel. Table 4.16: MB_SLAVE_AddRTUChannel() parameter list Example // // Static declarations // static MB_CHANNEL _MBChannel; static MB_IFACE_CONFIG_UART _MBConfig; static const MB_IFACE_UART_API _IFaceAPI = { _SendByte, _Init, _DeInit, NULL, NULL, NULL, NULL, _InitTimer, _DeInitTimer }; static const MB_SLAVE_API _SlaveAPI = { _WriteCoil, _ReadCoil, _ReadDI, _WriteReg, _ReadHR, _ReadIR }; // // Code running in main task // void MainTask(void) { MB_SLAVE_Init(); // Init slave MB_SLAVE_AddRTUChannel(&_MBChannel, &_MBConfig, &_SlaveAPI, &_IFaceAPI, 1, 0, 38400, 8, 0, 1, 0); // Add slave channel OS_CREATETASK( ... ); // Start slave task} } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 55 4.1.4.4 MB_SLAVE_DeInit() Description De-Initializes the slave resources and channels and removes the slave endpoint from the global endpoint list. Prototype void MB_SLAVE_DeInit ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 56 CHAPTER 4 Core functions 4.1.4.5 MB_SLAVE_Exec() Description Loops once over all slave channels, processes data when the channel has been signalled ready. Prototype void MB_SLAVE_Exec ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 57 4.1.4.6 MB_SLAVE_Init() Description Initializes the slave resources and adds the slave endpoint to the global endpoint list. Prototype void MB_SLAVE_Init ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 58 CHAPTER 4 Core functions 4.1.4.7 MB_SLAVE_PollChannel() Description Function that has to be periodically polled for each slave channel that requires requesting data instead of getting it via interrupt. Prototype void MB_SLAVE_PollChannel ( MB_Channel *pChannel ); Parameter Parameter pChannel Description [IN] Pointer to element of MB_CHANNEL. Table 4.17: MB_SLAVE_PollChannel() parameter list Return value <0: Error 0: No complete Modbus message signaled. 1: Complete Modbus message signaled. Example // // Polling a slave channel in a task, allowing it to sleep when possible. // static void _PollSlaveChannelTask(void *pChannel) { while (1) { MB_SLAVE_PollChannel((MB_CHANNEL*)pChannel); } } UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 59 4.1.4.8 MB_SLAVE_Task() Description Wrapper function that runs MB_SLAVE_Exec() in a task. Prototype void MB_SLAVE_Task ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 60 CHAPTER 4 4.1.5 Core functions Other core functions 4.1.5.1 MB_ConfigTimerFreq() Description This function allows setting a user defined timer frequency instead of the default frequency of 1kHz. Prototype void MB_ConfigTimerFreq ( U32 Freq ); Parameter Parameter Freq Description [IN] Timer frequency that shall be used for all all channels to calculate the RTU timeout. Table 4.18: MB_ConfigTimerFreq() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 61 4.1.5.2 MB_OnRx() Description Function called by byte oriented transmission channels that receive an interrupt for new data received. Prototype void MB_OnRx ( MB_CHANNEL *pChannel, U8 Data ); Parameter Parameter pChannel Data Description [IN] Pointer to element of MB_CHANNEL. [IN] Received character. Table 4.19: MB_OnRx() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 62 CHAPTER 4 Core functions 4.1.5.3 MB_OnTx() Description Function called by byte oriented transmission channels once a Tx complete interrupt has been received to send the next byte or report back that there is no more to send. Prototype int MB_OnTx ( MB_CHANNEL *pChannel ); Parameter Parameter pChannel Description [IN] Pointer to element of MB_CHANNEL. Table 4.20: MB_OnTx() parameter list Return value <0: Error 0: More data sent 1: No more data to send UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 63 4.1.5.4 MB_TimerTick() Description Function called on each timer interrupt to manage internal RTU timeout with serial channels using the RTU protocol. Prototype void MB_TimerTick ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 64 CHAPTER 4 4.2 Core functions emModbus data structures 4.2.1 Interface configuration structures 4.2.1.1 Structure MB_IFACE_CONFIG_IP Description This structure holds configurations for IP communications. Prototype struct { MB_SOCKET Sock; MB_SOCKET ListenSock; U32 IPAddr; U16 Port; U16 xID; } MB_IFACE_CONFIG_API; Member Sock ListenSock IPAddr Port xID Description Socket used for send and receive. Socket used by TCP for listen() and accept(). Not needed for UDP. Master: Addr. to connect to. Slave: Filter address. If set only connections on this address should be accepted. Master: Port to connect to. Slave: Port that accepts connections for this channel. Master: Transaction ID that is incremented for each send. Slave: Ignored. Table 4.21: Structure MB_IFACE_CONFIG_IP member list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 65 4.2.1.2 Structure MB_IFACE_CONFIG_UART Description This structure holds configurations for UART communications. Prototype struct { U32 Cnt; U32 CntReload; U32 Baudrate; U8 DataBits; U8 Parity; U8 StopBits; U8 Port; } MB_IFACE_CONFIG_UART; Member Cnt CntReload Baudrate DataBits Parity StopBits Port Description RTU timeout countdown. RTU countdown reload value. Baudrate to use. Number of data bits. Parity as interpreted by application. Number of stop bits. Interface index. Table 4.22: Structure MB_IFACE_CONFIG_UART member list Additional information MB_IFACE_CONFIG is of type MB_IFACE_CONFIG_UART. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 66 CHAPTER 4 4.2.2 Core functions Interface function structures 4.2.2.1 Structure MB_IFACE_IP_API Description This structure holds function pointers for IP communications. Prototype struct { void ( *pfSendByte ) ( MB_IFACE_CONFIG_UART *pConfig, U8 Data ); int ( *pfInit ) ( MB_IFACE_CONFIG_UART *pConfig ); void ( *pfDeInit ) ( MB_IFACE_CONFIG_UART *pConfig ); int ( *pfSend ) ( MB_IFACE_CONFIG_UART *pConfig, const U8 *pData, U32 NumBytes ); int ( *pfRecv ) ( MB_IFACE_CONFIG_UART *pConfig, U8 *pData, U32 NumBytes, U32 Timeout ); int ( *pfConnect ) ( MB_IFACE_CONFIG_UART *pConfig, U32 Timeout ); void ( *pfDisconnect ) ( MB_IFACE_CONFIG_UART *pConfig ); void ( *pfInitTimer ) ( U32 MaxFreq ); void ( *pfDeInitTimer ) ( void ); } MB_IFACE_IP_API; Member Description Send first byte. Every next byte will be sent via MB_OnTx() from interrupt. NULL if stream oriented interface, as pfSendByte gets used instead. Init IP and get listen socket and bring it in listen state if needed. pfInit NULL if not needed. Close listen socket and de-init IP. pfDeInit NULL if not needed. Send data for stream oriented interface. pfSend NULL if byte oriented interface is used, as pfSend gets used instead. pfRecv Request more data. Master: Connect to slave. Slave: Accept connection if needed. pfConnect NULL if not needed. Master: Disconnect from slave. pfDisconnect Slave: Close connection if needed. NULL if not needed. pfInitTimer NULL. pfDeInitTimer NULL. pfSendByte Table 4.23: Structure MB_IFACE_IP_API member list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 67 4.2.2.2 Structure MB_IFACE_UART_API Description This structure holds function pointers for UART communications. Prototype struct { void ( *pfSendByte ) ( MB_IFACE_CONFIG_UART *pConfig, U8 Data ); int ( *pfInit ) ( MB_IFACE_CONFIG_UART *pConfig ); void ( *pfDeInit ) ( MB_IFACE_CONFIG_UART *pConfig ); int ( *pfSend ) ( MB_IFACE_CONFIG_UART *pConfig, const U8 *pData, U32 NumBytes ); int ( *pfRecv ) ( MB_IFACE_CONFIG_UART *pConfig, U8 *pData, U32 NumBytes, U32 Timeout ); int ( *pfConnect ) ( MB_IFACE_CONFIG_UART *pConfig, U32 Timeout ); void ( *pfDisconnect ) ( MB_IFACE_CONFIG_UART *pConfig ); void ( *pfInitTimer ) ( U32 MaxFreq ); void ( *pfDeInitTimer ) ( void ); } MB_IFACE_UART_API; Member Description Send first byte. Every next byte will be sent via MB_OnTx() from interrupt. NULL if stream oriented interface, as pfSend gets used instead. Init hardware. pfInit NULL if not needed. De-Init hardware. pfDeInit NULL if not needed. Send data for stream oriented interface. pfSend NULL if byte oriented interface, as pfSendByte gets used instead. Typically data is received via MB_OnRx() from interrupt. pfRecv NULL if not using polling mode. pfConnect NULL. pfDisconnect NULL. Typically needed for RTU interfaces only. Initializes a timer needed for RTU timeout. pfInitTimer NULL if not needed. De-initialize RTU timer. pfDeInitTimer NULL if not needed. pfSendByte Table 4.24: Structure MB_IFACE_UART_API member list Additional information MB_IFACE_API is of type MB_IFACE_UART_API. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 68 CHAPTER 4 4.2.3 Core functions Slave structures 4.2.3.1 Structure MB_SLAVE_API Description This structure holds function pointers used by slaves. Prototype struct { int ( *pfWriteCoil ) ( U16 Addr, char OnOff ); int ( *pfReadCoil ) ( U16 Addr ); int ( *pfReadDI ) ( U16 Addr ); int ( *pfWriteReg ) ( U16 Addr, U16 Val ); int ( *pfReadHR ) ( U16 Addr, U16 *pVal ); int ( *pfReadIR ) ( U16 Addr, U16 *pVal ); } MB_SLAVE_API; Member pfReadCoil pfReadDI pfReadHR pfReadIR pfWriteCoil pfWriteReg Description Read coil status. Read discrete input registers. Read holding register. Read input register. Write coil. Write register. Table 4.25: Structure MB_SLAVE_API member list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 69 4.3 Error codes The following table contains a list of emModbus error codes. Generally, success is indicated by 0 and definite errors are indicated by negative numbers. Symbolic name MB_ERR_ILLEGAL_FUNC MB_ERR_ILLEGAL_DATA_ADDR MB_ERR_ILLEGAL_DATA_VAL MB_ERR_SLAVE_FAIL MB_ERR_ACK MB_ERR_SLAVE_BUSY MB_ERR_NACK MB_ERR_MEM_PARITY_ERR MB_ERR_MISC MB_ERR_CONNECT MB_ERR_CONNECT_TIMEOUT MB_ERR_DISCONNECT MB_ERR_TIMEOUT MB_ERR_CHECKSUM MB_ERR_PARAM MB_ERR_SLAVE_ADDR Value Description Slave errors The function code received in the query is an illegal function code for the slave. This may be because the function code was not implemented in the selected -1 device. It could also indicate that the slave is in the wrong state to process a request of this type. The data address received in the query is an invalid address for the slave. More -2 specifically, the combination of reference number and transfer length is invalid. A value contained in the query data field is an invalid value for the slave. This indi-3 cates a fault in the structure of a request, such as an incorrect implied length. An unrecoverable error occurred while -4 the slave was attempting to perform the requested action. The slave has accepted the request and is processing it, but a long duration of time will be required to do so. This -5 response is returned to prevent a timeout error from occurring in the master, which can then poll for process completion. The slave is engaged in processing a -6 long-duration command. The master should retransmit the message later. The requested function cannot be per-7 formed. Issue poll to obtain detailed device dependent error information. The slave attempted to perform the query, but detected a parity error in the memory. The master can retry the -8 request, but service may be required on the slave device. Stack internal errors -20 Unspecified error. -21 Error while connecting. -22 Timeout while connecting. -23 Interface signaled disconnect. -24 No answer received on request. Received message did not pass LRC/CRC -25 check. -26 Parameter error in API call. Received valid response with wrong slave -27 address. Table 4.26: emModbus error codes UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 70 CHAPTER 4 Symbolic name Value MB_ERR_FUNC_CODE -28 MB_ERR_REF_NO -29 MB_ERR_NUM_ITEMS -30 MB_ERR_DATA -31 MB_ERR_TRIAL_LIMIT -32 Core functions Description Received valid response with wrong function code. Received valid response with wrong reference number. Received valid response with more or less items than requested. Received valid response for a single write with different data than written. Trial limit exceeded. When using trial libraries, this error occurs after 12 hours of run time. Except from this, the trial library is fully functional and includes all features of emModbus. Table 4.26: emModbus error codes UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 71 Chapter 5 Configuring emModbus emModbus can be used without changing any of the compile-time flags. All compiletime configuration flags are preconfigured with valid values, which match the requirements of most applications. The default configuration of emModbus can be changed via compile-time flags which can be added to MB_Conf.h. MB_Conf.h is the main configuration file for the emModbus stack. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 72 CHAPTER 5 5.1 Configuring emModbus Compile-time configuration The following types of configuration macros exist: Binary switches "B" Switches can have a value of either 0 or 1, for deactivated and activated respectively. Actually, anything other than 0 works, but 1 makes it easier to read a configuration file. These switches can enable or disable a certain functionality or behavior. Switches are the simplest form of configuration macros. Numerical values "N" Numerical values are used somewhere in the code in place of a numerical constant. A typical example is the configuration of the sector size of a storage medium. Function replacements "F" Macros can basically be treated like regular functions although certain limitations apply, as a macro is still put into the code as simple text replacement. Function replacements are mainly used to add specific functionality to a module which is highly hardware-dependent. This type of macro is always declared using brackets (and optional parameters). 5.1.1 Compile-time configuration switches Type Symbolic name B MB_IS_BIGENDIAN N MB_DEBUG F MB_MEMCMP F MB_MEMCPY F MB_MEMMOVE F MB_MEMSET Default Description System configuration macros Macro to define if a big endian tar0 get is used. Debug macros Macro to define the debug level of the emModbus build. Refer to 0 Debug level on page 73 for a description of the different debug level. Optimization macros Macro to define an optimized memcmp memcmp routine to speed up the (C-routine in stack. An optimized memcmp roustandard Ctine is typically implemented in library) assembly language. Macro to define an optimized memcpy routine to speed up the memcpy stack. An optimized memcpy rou(C-routine in tine is typically implemented in standard Cassembly language. library) Optimized versions for IAR and GCC compilers are supplied. Macro to define an optimized memmove memmove routine to speed up the (C-routine in stack. An optimized memmove standard Croutine is typically implemented in library) assembly language. Macro to define an optimized memset memset routine to speed up the (C-routine in stack. An optimized memset roustandard Ctine is typically implemented in library) assembly language. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 73 5.1.2 Debug level emModbus can be configured to display debug information at higher debug levels to locate a problem (Error) or potential problem. To display information, emModbus uses the logging routines (see chapter Debugging on page 75). These routines can be blank, they are not required for the functionality of emModbus. In a target system, they are typically not required in a release (production) build, since a production build typically uses a lower debug level. If (IP_DEBUG == 0): used for release builds. Includes no debug options. If (IP_DEBUG == 1): MP_PANIC() is mapped to MP_Panic(). If (IP_DEBUG >= 2): MP_PANIC() is mapped to MP_Panic() and logging support is activated. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 74 UM14001 User & Reference Guide for emModbus CHAPTER 5 Configuring emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 75 Chapter 6 Debugging emModbus comes with debugging options including optional warning and log outputs. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 76 6.1 CHAPTER 6 Debugging Message output The debug builds of emModbus include a debug system which helps to analyze the correct implementation of the stack in your application. All modules can output logging and warning messages via terminal I/O. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 77 6.1.1 Debug API functions Function MB_Log() MB_Panic() MB_Warn() Description I/O functions This function is called by the stack in debug builds with log output. This function is called if the stack encounters a critical situation. This function is called by the stack in debug builds with warning output. Table 6.1: emModbus debug API functions overview UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 78 CHAPTER 6 Debugging 6.1.1.1 MB_Log() Description This function is called by the stack in debug builds with log output. In a release build, this function may not be linked in. Prototype void MB_Log ( const char *s ); Parameter Parameter s Description [IN] String to output. Table 6.2: MB_Log() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 79 6.1.1.2 MB_Panic() Description This function is called if the stack encounters a critical situation. In a release build, this function may not be linked in. Prototype void MB_Panic ( const char *s ); Parameter Parameter s Description [IN] String to output before running into endless loop. Table 6.3: MB_Panic() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 80 CHAPTER 6 Debugging 6.1.1.3 MB_Warn() Description This function is called by the stack in debug builds with warning output. In a release build, this function may not be linked in. Prototype void MB_Warn ( const char *s ); Parameter Parameter s Description [IN] String to output. Table 6.4: MB_Warn() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 81 6.2 Using a network sniffer to analyse ethernet communication problems Using a network sniffer to analyze your local Ethernet traffic may give you a deeper understanding of the data that is being sent in your network. For this purpose you can use several network sniffers. Some of them are available for free such as Wireshark. An example of a network sniff using Wireshark is shown in the screenshot below: UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 82 6.3 CHAPTER 6 Debugging Testing emModbus applications We recommend testing emModbus devices by using their respective counterparts, e.g. using a emModbus/TCP master to test a emModbus/TCP slave and vice versa. Alternatively, devices can also be tested with a desktop computer running an appropiate Modbus application. To solely test emModbus on target hardware, we recommend building a corresponding project for the specific application. For example, the application contained in OS_IP_MB_SlaveTCP.c, can be tested using a project for the application contained in OS_IP_MB_MasterTCP.c. Configuration of some parameters (e.g. IP address) is required before compiling the project and downloading the output into a second target. When connected to the same network, both devices should then start communication with each other. To test emModbus using a desktop computer, an appropiate software package is required. The shipment contains Windows applications for Modbus master and slave devices using Modbus/TCP, which can be used to test both devices via that connection. In addition, several vendors offer Modbus testing applications for Microsoft Windows and other operating systems, many of which are free or at least free to evaluate for a limited time. We recommend "Modbus Poll" for testing emModbus slave functionalities and "Modbus Slave" for testing emModbus master functionalities. Both applications can be downloaded from http://www.modbustools.com. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 83 Chapter 7 OS Integration emModbus is designed to be used in a multitasking environment. The interface to the operating system is encapsulated in a single file, the MB/OS interface. For embOS, all functions required for this MB/OS interface are implemented in a single file which comes with emModbus. This chapter provides descriptions of the functions required to fully support emModbus in multitasking environments. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 84 7.1 CHAPTER 7 OS Integration General information All OS interface functions for embOS are implemented in MB_OS_embOS.c, which is located in the root folder of the emModbus stack. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 85 7.2 OS layer API functions Function Description General functions De-Initializes (removes) all objects required for task MB_X_OS_DeInitMaster() syncronisation of the master. De-Initializes (removes) all objects required for task MB_X_OS_DeInitSlave() synchronisation of the slave. MB_X_OS_DisableInterrupt() Disables interrupts before critical operations. MB_X_OS_EnableInterrupt() Enables interrupts after critical operations. MB_X_OS_GetTime() Returns the current system time in ms. Initializes (creates) all objects required for task synMB_X_OS_InitMaster() chronisation of the master. Initializes (creates) all objects required for task synMB_X_OS_InitSlave() chronisation and signalling of the slave. Synchronization functions Sets an object to signaled state, or resumes tasks MB_X_OS_SignalItem() which are waiting at the event object. Wakes tasks waiting for a NET-event or timeout in the MB_X_OS_SignalNetEvent() function MB_OS_WaitNetEvent(). MB_X_OS_WaitItemTimed() Suspends a task which needs to wait for an object. Blocks until a NET-event occurs, meaning MB_X_OS_WaitNetEvent() MB_OS_SignalNetEvent() is called from another task or ISR. Table 7.1: OS layer API functions list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 86 CHAPTER 7 7.2.1 OS Integration General functions 7.2.1.1 MB_X_OS_DeInitMaster() Description De-Initializes (removes) all objects required for task syncronisation of the master. Prototype void MB_X_OS_DeInitMaster ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 87 7.2.1.2 MB_X_OS_DeInitSlave() Description De-Initializes (removes) all objects required for task syncronisation of the slave. Prototype void MB_X_OS_DeInitSlave ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 88 CHAPTER 7 OS Integration 7.2.1.3 MB_X_OS_DisableInterrupt() Description Disables interrupts before critical operations. Prototype void MB_X_OS_DisableInterrupt ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 89 7.2.1.4 MB_X_OS_EnableInterrupt() Description Enables interrupts after critical operations. Prototype void MB_X_OS_EnableInterrupt ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 90 CHAPTER 7 OS Integration 7.2.1.5 MB_X_OS_GetTime() Description Returns the current system time in ms. The value will wrap around after approximately 49.7 days. This is taken into account by the stack. Prototype U32 MB_X_OS_GetTime32 ( void ); Return value System time in ms. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 91 7.2.1.6 MB_X_OS_InitMaster() Description Initializes (creates) all objects required for task syncronisation of the master. This is one semaphore for protection of critical code, which may not be executed from multiple tasks at the same time, and a hook in case a task currently executing Modbus master API is terminated. Prototype void MB_X_OS_InitMaster ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 92 CHAPTER 7 OS Integration 7.2.1.7 MB_X_OS_InitSlave() Description Initializes (creates) all objects required for task synchronisation and signalling of the slave. Prototype void MB_X_OS_InitSlave ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 93 7.2.2 Synchronization functions 7.2.2.1 MB_X_OS_SignalItem() Description Sets an object to signaled state, or resumes tasks which are waiting at the event object. Prototype void MB_X_OS_SignalItem (void *pWaitItem ); Parameter Parameter pWaitItem Description [IN] Pointer to item a task is waiting for. Table 7.2: MB_X_OS_SignalItem() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 94 CHAPTER 7 OS Integration 7.2.2.2 MB_X_OS_SignalNetEvent() Description Wakes tasks waiting MB_OS_WaitNetEvent(). for a NET-event or timeout in the function Prototype void MB_X_OS_SignalNetEvent ( void ); UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 95 7.2.2.3 MB_X_OS_WaitItemTimed() Description Suspends a task which needs to wait for an object. This object is identified by a pointer to it and can be of any type, e.g. channel. Prototype void MB_X_OS_WaitItemTimed ( void unsigned Timeout ); *pWaitItem, Parameter Parameter pWaitItem Timeout Description [IN] Pointer to item a task shall wait for until signalled or timeout occurs. [IN] Timeout [in ms] to wait for item to be signalled. Table 7.3: MB_X_OS_WaitItemTimed() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 96 CHAPTER 7 OS Integration 7.2.2.4 MB_X_OS_WaitNetEvent() Description Called from MB_Task() only. Blocks until a NET-event MB_OS_SignalNetEvent() is called from another task or ISR. occurs, meaning Prototype void MB_X_OS_WaitNetEvent ( unsigned ms ); Parameter Parameter ms Description [IN] Time to wait for a NET-event to occur [in ms]. 0 for infinite. Table 7.4: MB_X_OS_WaitNetEvent() parameter list UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 97 Chapter 8 Resource usage This chapter covers the resource usage of emModbus. It contains information about the memory requirements in typical systems, which can be used to obtain sufficient estimates for most target systems. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 98 CHAPTER 8 8.1 Resource usage Memory footprint emModbus is designed to fit many kinds of embedded design requirements. Some features might be excluded from a build to get a minimal system. Note that the values are only valid for the given configurations. 8.1.1 ARM7 system The following table shows the hardware and the toolchain details of the project: Detail CPU Tool chain Model Compiler options Description ARM7 IAR Embedded Workbench for ARM V6.30.6 ARM7, Thumb instructions; interwork; Highest size optimization; Table 8.1: ARM7 sample configuration 8.1.1.1 ROM usage The following table shows the ROM requirement of emModbus: Description master using ASCII master using TCP master using RTU slave using ASCII slave using TCP slave using RTU ROM approx. approx. approx. approx. approx. approx. 1.5 0.9 2.1 2.0 1.6 2.6 Kbytes Kbytes Kbytes Kbytes Kbytes Kbytes 8.1.1.2 RAM usage emModus requires approximately 30 Bytes of RAM for the stack itself and approximately 300 Bytes of RAM for each channel added. UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG Index Index 99 P Port number (Modbus/TCP) .................. 10 Protocol Data Unit (PDU) ...................... 11 Protocol ID (Modbus/TCP) .................... 12 Q Query ................................................ 10 A Application Data Unit (ADU) ..................11 C Coil ....................................................13 Compiler, required compliance ...............15 Compile-time flags ...............................71 Configuration ......................................71 Contact address ................................... 2 Core functions .....................................36 Cyclic Redundancy Check ......................11 S Schneider Electric SA ........................... 10 SEGGER Microcontroller GmbH & Co. KG .. 6 Slave (device) .................................... 10 Syntax, conventions used ....................... 5 T TCP/IP stack ....................................... 14 Transaction ID (Modbus/TCP) ................ 12 U Unit ID .............................................. 11 D Data table ..........................................13 Data types, primary .............................13 Debug functions ..................................77 Discrete Input .....................................13 E Endianess ...........................................13 F Frames, Modbus-compliant variants .......10 Function code ......................................11 Function replacements .........................72 H Holding Register ..................................13 I Input Register .....................................13 L Log output ..........................................78 Longitudinal Redundancy Check .............12 M Master (device) ...................................10 Memory requirement ............................97 Modbus Application Header (Modbus/TCP) 12 Modbus Organization ............................10 Modbus, standard protocol ....................10 Modicon .............................................10 Multi tasking .......................................14 N Network sniffer ....................................81 O OS integration functions .......................85 UM14001 User & Reference Guide for emModbus (c) 2014 SEGGER Microcontroller GmbH & Co. KG 100 UM14001 User & Reference Guide for emModbus Index (c) 2014 SEGGER Microcontroller GmbH & Co. KG