Chapter 102. API Overview

The main client-application access to CCB functionality is via the common named device /dev/ccb. It is the responsibility of the client-application to open a handle onto this common device, and then to read and write messages as appropriate.

The common layer will automatically start the protocol control thread and use the standard eCos cyg_io interface connection to the specific CCB interface (hardware port) device drivers.

For CYGPKG_IO_FILEIO configurations the client-application can use the open(), write(), read() and select() functions. If CYGPKG_IO_FILEIO is not configured then the standard cyg_io_lookup(), cyg_io_read() and cyg_io_write() function interface is used.

[Note]Note

The client-application writes to the CCB are always blocking. The read operations can be configured as non-blocking if required, and if CYGPKG_FILEIO select() support is configured will default to non-blocking operation.

The common and driver-specific CCB packages also provide access to some GET/SET operations that can be accessed via the relevant cyg_fs_fgetinfo/cyg_fs_fsetinfo or cyg_io_get_config/cyg_io_set_config functions. The “key” values supported are:

CYG_IO_GET_CONFIG_PENDING_MESSAGES

This key allows a snapshot view of the number of pending client-application RX messages.

[Note]Note

As packet reception might occur during calls to this config operation, the information returned may already be stale. If the thread reading this count is the only thread reading messages then this value can be viewed as the minimum number of messages pending. i.e. the client-application should always be able to read the returned number of messages.

A client-application using select() to do a non-busy wait for a message should not normally need to worry about the number of pending messages. This config key support is provided to correspond with the functionality described by the CCB protocol documentation.

CYG_IO_GET_CONFIG_CCB_STATISTICS

This option allows, where provided by the underlying hardware interface port driver, sets of statistics to be monitored. The <cyg/io/ccb_port.h> header file defines the cyg_ccb_devio_stats_t structure used to hold RX and TX information for a specific device driver. This config key functionality uses the <cyg/io/ccb.h> header file defined cyg_ccb_io_stats_t structure to step through the available interface statistics.

The initial cyg_ccb_io_stats_t.priv_ctx field should be initialised to NULL, and then this key config call repeated until the common CCB support returns cyg_ccb_io_stats_t.priv_ctx == NULL (indicating no more data). As per the following pseudocode example:

cyg_ccb_io_stats_t stats;
cyg_bool moredata = true;

stats.priv_ctx = NULL; // start

do {
  int res = cyg_fs_fgetinfo(pcapp->fd,CYG_IO_GET_CONFIG_CCB_STATISTICS,&stats,sizeof(stats));
  if (res < 0) {
    diag_printf("FAIL:<Get statistics error %d \"%s\">\n",res,strerror(errno));
    moredata = false;
  }
  if (moredata) {
    moredata = (stats.priv_ctx != NULL);
    if (moredata) {
      diag_printf("Device \"%s\" : RX pkts=%u (bytes=%llu) dropped=%u : TX pkts=%u (bytes=%llu) retrans=%u failed=%u>n",
                  stats.dname,
                  stats.dstats.rx_pkts,
                  stats.dstats.rx_bytes,
                  stats.dstats.rx_pkts_dropped,
                  stats.dstats.tx_pkts,
                  stats.dstats.tx_bytes,
                  stats.dstats.tx_pkts_retrans,
                  stats.dstats.tx_pkts_failed);
    }
  }
} while (moredata);

When using a cyg_io_handle_t reference to the common CCB layer then the example above would use the corresponding cyg_io interface:

  Cyg_ErrNo res = cyg_io_get_config(pcapp->handle,CYG_IO_GET_CONFIG_CCB_STATISTICS,&stats,&slen);
CYG_IO_SET_CONFIG_CCB_BUS_RESET
Normally the client-application should not need to force a global bus reset. The common CCB layer performs a bus reset as part of the normal application startup. This config “key” may be useful during testing/development, or if an unrecoverable error is detected.

There is also a minimal function call API providing some “stateless“ message helper routines.

102.1. Application support API

cyg_ccb_build_message — Construct message
cyg_ccb_check_response — Check response

These functions are available for the client-application to aid in message processing.

See the Testing section's ccb_master test client-application for an example of access to the /dev/ccb and use of these functions.

102.2. I/O Device Driver Interface

The header file <cyg/io/ccb_devio.h> defines the interface between the common CCB support and the target specific device drivers. The device drivers provide the physical CCB packet communication support.

Physical connections are supplied to the common layer via the relevant target/platform defining a cyg_ccb_port_instance_t structure (via the CCB_PORT() macro), which provides the mapping to the relevant low-level hardware I/O driver via the supplied named device.

The cyg_ccb_devio_port_t structure defines a hardware port instance (i.e. a physical RS-485 hardware interface) driver in conjunction with a standard I/O driver device descriptor DEVTAB_ENTRY() definition. A driver normally instantiates itself via the CCB_DEVIO_PORT() macro to populate a cyg_ccb_devio_port_t structure.

The device drivers interface with the CCB common layer via the cyg_ccb_devio_funs_t and cyg_ccb_callbacks_t structures implemented by the src/ccb_devio.c support.

The device drivers fundamentally provide a per-port blocking transmit function, and asynchronous packet reception. The driver calls back into the common CCB layer via the (DSR context) cyg_ccb_callbacks_t functions tx_done() and rx_pkt().