Multiple direct drivers

When support for multiple direct drivers is configured then a driver instance is contained within a cyg_lwip_eth_t structure:

typedef struct cyg_lwip_eth {
  const char *name; // NUL terminated ASCII human-readable name
  void (*init)(struct cyg_lwip_eth *drvdesc);
  void (*run_deliveries)(void *instance);
  err_t (*ll_output)(struct netif *netif,struct pbuf *p);
  int (*pbuf_free_hook)(void *instance,struct pbuf *p);
  void (*phy_event)(struct netif *netif);
  int (*ioctl)(struct netif *netif,unsigned long key,void *data,int data_length);
  void *instance;
  cyg_uint32 flags;
} CYG_HAL_TABLE_TYPE cyg_lwip_eth_t;

This CYGPKG_IO_ETH_DRIVERS package will implement the wrapper namespace to support lwIP, calling the relevant individual device driver registered functions as required.

You create an instance of cyg_lwip_eth_t using the CYG_LWIP_DRIVER macro, which sets up the structure. Using this macro ensures that if the internal design changes then existing source will fail to compile until updated to reflect the changed functionality. This is better than having definitions within the low-level drivers themselves, with the possibility of them building successfully but then failing at run-time.

The individual hardware drivers are initialised automatically via the wrapper provided cyg_lwip_eth_ecos_init() function, which iterates over the __LWIPDEVTAB__ vector containing the driver instance descriptors as required.

Note: When lwIP direct drivers are written to support CYGFUN_IO_ETH_DRIVERS_LWIP_DRIVER_DIRECT_MULTI configurations they MUST reference their cyg_lwip_eth_t descriptor via the state field of the struct netif describing the lwIP network interface. The instance field of the cyg_lwip_eth_t can be used to hold driver specific instance data.

The function pointers referenced from the cyg_lwip_eth_t descriptor closely match the raw namespace, with the exception that initialisation is passed the cyg_lwip_eth_t driver descriptor pointer, and the run_deliveries and pbuf_free_hook implementations are passed the private instance pointer. This ensures that the individual driver implementation can access the necessary state as would be the case for a single driver configuration.

Note: For the pbuf_free_hook support we should ideally pass the pbuf back to the original driver instance that allocated that specific pbuf. However, for the moment, the code just offers the pbuf to each configured driver in turn (the alternative would introduce complexity into the driver model for minimal gains).

This “do you want this pbuf” approach does not affect the behaviour, only the performance, of the driver when used in a multi-driver configuration. If the developer needs to ensure that a particular driver instance is “higher priority” than other lwIP Ethernet drivers for pbuf re-use then they should enforce a mechanism for ensuring the ordering of the __LWIPDEVTAB__device table.

Documentation license for this page: Open Publication License