You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 9 Next »

Requirements

The I/O capability of an RCE system provided by its protocol plugins is made available to application code using abstractions called ports. Some of those ports are predefined, i.e., are set up by the RCE core code before application code is started.

  1. Data container zero in the configuration flash contains tables providing all the information needed to make ready the predefined ports. This includes pointers to device driver code but not the code itself; other containers will hold driver code. In addition the tables provide some extra information not actually needed for setup but required to print a summary, meaningful to human beings, of the characteristics of the predefined ports.
  2. The RCE core code uses the information in the tables to define the ports they describe, except for loading and running device drivers (see below).
  3. Each channel (PPI) has exactly one device driver whose object code fits into a single container in the configuration flash. The tables described above contain references to these containers. A device driver is just a module as defined by the RCE dynamic linker; its rce_appmain() function initializes the driver. The RCE core code loads the device driver modules into system RAM along with the application module(s) and links them all together in the default instance of the linker. It then calls the rce_appmain() of each driver (no order guaranteed) before calling that of the application. Technically this allows a driver to depend on other drivers or even on the application code but DON'T DO IT. A driver should depend only on the RCE core.
  4. The core provides an API by which the application code can discover which ports are defined and their characteristics. When the application starts the API can return information about any predefined port.

Table format in configuration flash

The tables are called Ports, Channels, Channel Classes, Bandwidths, Drivers and Strings. Except for Strings each table is an array of plain-old-data structs with the first field being a key or ID field normally equal to the array index. An ID equal to 0xffffffff signifies the end of the table in which case none of the other fields in the struct have any guaranteed values and should never be read. Thus you'll generate end-of-table sentinels automatically if you erase a flash block before writing tables into it, provided you leave at least one 32-bit word of unsed space at the end of each table.

The Strings table is like an ELF string table; NUL-terminated ASCII strings laid end to end. Certain standard strings such as the short-names of channels are at the front of the table with only one instance of each string present. The other tables refer to a string by giving the offset of its first character in the Strings table.

General layout of the container contents

The first words of the container are the offsets in the container to the starts of the tables in the following order:

  1. Ports.
  2. Channels.
  3. Channel Classes.
  4. Bandwidths.
  5. Drivers.
  6. Strings.

Each of the offsets should be divisible by four.

After that come the tables themselves. No particular order is required, though since all the tables except Strings can be allocated a fixed chunk of flash it's most convenient to have Strings come last.

The Ports table

struct Port {
    uint32_t  id;             // Unique port number.
    uint32_t  channelId;      // Ref. to Channels table.
    uint32_t  channelPortNum; // Port's number within the channel.
    StringOff description;    // A short description of the port.
};

The Channels table

struct Channel {
    uint32_t id;              // Unique channel number.
    unit32_t idWithinClass;   // Class-unique 0, 1, ... .
    unit32_t classId;         // Ref. to Channel Classes table.
    StringOff description;
};

The Channel Classes table

struct ChannelClass {
    uint32_t  id;
    uint32_t  driverId;
    unit32_t  bandwidthId;
    StringOff shortName;
    StringOff description;
};

The Drivers table

Struct Driver {
    uint32_t  id;
    uint32_t  containerName;
    StringOff description;
};
  • No labels