Wednesday 23 July 2008

Support of hardware variants with one BSP

Sometimes you have one BSP that has to support slightly different hardware due to adaptions for end customers. Usually, there is a globlal compiler define which is set in sources.cmn (or somewhere in sources files) and if you later add a new variant, you have to go through all those files and add the support for the new variant.

A really simple solution which only requires re-linking of executables followed by makeimg is to build variants of a library where each variant follows a defined naming scheme. And even better, for a new variant you just add the catalog feature, add the sources/makefile for the component variant and that's it.


Let's see how that could work with a concrete example:

In my case, the BSP had to support different PCI configurations because the PCI arbiter had a bug and during data transfer to a S-ATA harddisk, the USB controller on the same bus starved. Fortunately, the use cases of the device required either S-ATA or USB and not both of them at the same time (and if USB was required, too, we did not include the EHCI driver, USB1.0 still worked fine in that configuration). So, I have two variants:

  • conservative: The PCI setup is performed carefully - slow transfer rates to S-ATA HD, but reliable USB 2.0
  • optimized: In case the S-ATA transfer rate is very important and the PCI setup is tuned for that use case

The kernel has to link either the optimized or the conservative variant of the pci library. And therefore the catalog file offers the features "PCI optimized" and "PCI conservative". The features either set the environment variable PCI_CTRL_CONSERVATIVE (or don't).

Now, sources.cmn sets a makefile variable depending on that user-selected catalog feature:

!IF "$(PCI_CTRL_CONSERVATIVE)"=="1"
PCI_KERNEL_LIBRARY_SUFFIX=conservative
!ELSE
PCI_KERNEL_LIBRARY_SUFFIX=optimised
!ENDIF

The two libraries (one compiled with defines for optimised and one for conservative behaviour) are built by two source/makefile projects:

TARGETNAME=oal_pcidevicecfg_conservative
CDEFINES=$(CDEFINES) -DPCI_CTRL_CONSERVATIVE=1
SOURCES= \ ..\pcidevicecfg.c

and

TARGETNAME=oal_pcidevicecfg_optimised
SOURCES= \ ..\pcidevicecfg.c

As you can see, the file name of the library variants has an extension which is used by sources.cmn.

Now, the executable which calls functions in that library (here the kernel itself, because it configures the PCI bus during boot time) just links the library using a makefile variable:

TARGETNAME=kern
TARGETTYPE=PROGRAM
... snip ...
TARGETLIBS= $(TARGETLIBS)\
$(TARGETPATH)\oal_pcidevicecfg_$(PCI_KERNEL_LIBRARY_SUFFIX).lib


The other advantage of this mechanism is that there's not need to re-compile the whole project. Just link and run makeimg. That's all.

No comments: