PBMaster:Communication with the device FDL API
From PBMasterWiki
This section introduces the Application Programming Interface (API) of the Profibus's FDL layer. It ties together with the device drivers and will explain the basic mechanisms to communicate with another station on the Profibus network.
Even thought the communication with another station on the bus could be provided by sending bytes in the raw form directly to the Profibus device, the fact that a developer needs to understand frame structures and even the Profibus specification, make it unsuitable and inconvenient for most application developers. Hence an API was developed to offer a unified and simple mechanism to access the Profibus network.
The API is provided in the form of a library. The library offers a unified system and architecture-independent programming interface handling the transfer between FDL applications and Profibus stations. At the beginning we will take a look at the API functions and their arguments. Later in this section an example using the FDL programming interface will be introduced.
[edit] Interface description
An application wanting to communicate first needs to open the device. Afterwards the communication can be carried out using the read/write operations. At the end the communication should be properly closed using the appropriate function. The library involves the following functions (please consult the manual pages for more details):
pbm_close - close a connection pbm_read - blocking read/receive data from the network pbm_read_poll - unblocking read/receive data from the network with pbm_write - write/send data to the network pbm_write_srd - set up a frame of SRD type and send it to the network pbm_errno - get number of the last error
The FDL API functions are intended to be similar to the POSIX's I/O functions:
/* Open a device. */ int pbm_open(char *dev); /* Close a device. */ int pbm_close(int fildes); /* Read from a device. All arguments are equivalent to the arguments * of the read(3) functions. */ int pbm_read(int fildes, void *buf, int nbyte); /* Write to a device. All arguments are equivalent to the arguments * of the write(3) functions. */ int pbm_write(int fildes, const void *buf, int nbyte); /* Read from the device with timeout. The first three arguments are the same * as arguments of the read() function. Argument timeout is used for the * poll() function. */ int pbm_read_poll(int fildes, void *buf, int nbyte, int timeout); /* Return number of the last error */ int pbm_errno(void); /* Write a SRD telegram to the device */ int pbm_write_srd(int fildes, void *buf, int nbyte, int addr, int dsap, int ssap, int priority);
[edit] FDL API compatibility
The project had a plan to fully support the FDL programming interface by Siemens. In the end, backwards support was not implemented due to the proprietary license of that programming interface. Nonetheless, the project's API partly supports backward compatibility with the Siemens's FDL programming interface. Everything related to Siemens's Request Block should be removed as the library does not work with that structure. Replace the Request Block with a buffer. This backward support is implemented as macros calling the proper API functions described previously. Mapping between the project's API and the API by Siemens is listed below:
SCP_open - pbm_open SCP_close - pbm_close SCP_send - pbm_write SCP_receive - pbm_read_poll SCP_get_errno - pbm_errno
[edit]
The following code shows a simple example using the FDL programming interface. The program sends parameterization and configuration to a slave station, an ET200B by Siemens, then it turns on the first digital output of this slave station.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pbmcore.h>
#include <pbm.h>
#define ET200B 18 /* slave address */
/* Set parameters of Siemens ET200B */
void et200b_set_conf(int fd)
{
/* parametrization */
unsigned char param[] = { 0xb0, 0x08, 0x09, 0x0b, 0x00, 0x0f,
0, 0, 0, 0, 0, 0 };
/* configuration */
unsigned char conf[] = { 0x20, 0x12 };
/* send parametrization */
pbm_write_srd(fd, param, sizeof(param),
ET200B, SAP_SET_PARAM, SAP_CHECK_CFG, PB_MSG_HIGH);
/* send configuration */
pbm_write_srd(fd, conf, sizeof(conf),
ET200B, SAP_CHECK_CFG, SAP_CHECK_CFG, PB_MSG_HIGH);
}
/* Turn on digital output */
void et200b_on(int fd, int output_num)
{
unsigned char q[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
/* set digital output */
pbm_write_srd(fd, &q[output_num], 1,
ET200B, SAP_DEFAULT, SAP_DEFAULT, PB_MSG_HIGH);
}
int main(int argc, char **argv)
{
int fd;
fd = pbm_open("/dev/pbmaster0");
if (fd < 0)
exit(1);
et200b_set_conf(fd);
et200b_on(fd, 0);
pbm_close(fd);
return 0;
}

