How to port the cifX Toolkit

Basics:

There are two different types of devices being handled:

  1. Flash-based devices (like a comX) which have their firmware running out of flash
  2. RAM-based devices (like a cifX) which get their firmware loaded by the driver / toolkit.

 

Here is a short step-by-step guide, what needs to be done:

  • Copy the Source Folder (which contains the whole Toolkit) to your project

  • Implement the OS Abstraction layer (according to the toolkit documentation) in a own / seperate C-file.
    You may take a look at "OSAbstraction\OS_Win32.c" to see how this is done under Windows. You don't need to implement all functions, depending on your use case:

    Options:
    1) When not using cifX PCI cards or any other RAM-based device with the netX directly connected to the PCI bus, you can stub out the functions OS_ReadPCIConfig / OS_WritePCIConfig

    2) When not using Interrupts you can stub out the OS_CreateEvent, OS_SetEvent, OS_ResetEvent, OS_DeleteEvent, OS_WaitEvent functions

    3) If you don't have a multitasking environment you can stub out the Mutex functions (OS_CreateMutex, OS_WaitMutex, OS_ReleaseMutex, OS_DeleteMutex), as the mutexes are only used to prevent reentrant function calls.
    Note:
    As the Mutexes are expected to work as the toolkit does not know about your O/S you will need to return a value != 0 out of OS_CreateMutex and OS_WaitMutex.
    Attention:
    Doing this in a multitasking environment will result in undefined behaviour as function reentrancy cannot be controlled.

    4) If you only have a comX or another netX with flashed firmware you may stub out the file functions (OS_FileOpen, OS_FileRead, OS_FileClose) too, if you don't want to use the automatic update feature of the toolkit, which checks and updates the Firmware during startup.
    Attention: When using RAM-based devices these functions must be implemented.

  • Implement the USER functions in an own / seperate C-file
    You may take a look at "User\TKitUser.c" to see how this is done under Windows.

    Options:
    1) If you only have a comX or another netX with flashed firmware you may stub out the firmware / bootloader functions (USER_GetFirmwareFileCount, USER_GetFirmwareFile, USER_GetConfigurationFileCount, USER_GetConfigurationFile, USER_GetOSFile, USER_GetBootloaderFile), if you don't want to use the automatic update feature of the toolkit, which checks and updates the Firmware during startup.
    Attention: When using RAM-based devices these functions must be implemented.

  • Only needed if any of your devices are using polling mode: Implement a cyclic timer (e.g. 500ms) which calls the function cifXTKitCyclicTimer()
  • Call the Toolkit initialization (cifXTKitInit()) from your driver framework
  • Add all your netX / cifX / comX devices under Toolkit control by:

    1. Allocating a DEVICE_INSTANCE structure
    2. Filling in all needed parameters into this structure.
        Note1: You can use the element pvOSDependent to store any non-toolkit parameters for this device.
        Note2: You can override the type of the device by adjusting the element "eDeviceType" if it is not correctly auto-detected by the toolkit.

    COMX Example:

    OS_Memset(ptDevInstance, 0, sizeof(*ptDevInstance));
    ptDevInstance->fPCICard      = 0;
    ptDevInstance->pbDPM         = <Insert pointer to DPM here>;
    ptDevInstance->ulDPMSize     = <Insert accessible size of DPM here>;
    OS_Strncpy(ptDevInstance->szName, "cifX0", sizeof(ptDevInstance->szName));
    ptDevInstance->pvOSDependent = MyDeviceData;

    CIFX Example:

    OS_Memset(ptDevInstance, 0, sizeof(*ptDevInstance));
    ptDevInstance->fPCICard      = 1;
    ptDevInstance->pbDPM         = <Insert pointer to DPM here>;
    ptDevInstance->ulDPMSize     = <Insert accessible size of DPM here>;
    OS_Strncpy(ptDevInstance->szName, "cifX0", sizeof(ptDevInstance->szName));
    ptDevInstance->pvOSDependent = MyDeviceData;

    3. Call cifXTKitAddDevice() to add them under Toolkit control

  • On big-endian CPUs:
    You will need to enable big endian support in the toolkit by setting the preprocessor definition "CIFX_TOOLKIT_BIGENDIAN", which instructs the toolkit to convert DPM access endianess.
    Attention: The toolkit will not swap Packet contents or I/O data as it does not know the structured data behind these data areas. So the user has to do the endianess conversion before calling xChannelPutPacket / xChannelIOWrite and after xChannelGetPacket / xChannelIORead calls. Same is valid for system device and some other block access functions (e.g. extended status block).

  • Optional: Use DMA on PCI devices
    Attention: This is only supported if the netX is directly connected to the PCI Bus (e.g. cifX). It does not work with NXPCA-PCI boards (or any other PCI<-->DPM Bridge)

    To use DMA you will need to do the following:
    1. Insert the preprocessor define "CIFX_TOOLKIT_DMA"
    2. Pass 8 DMA buffers which need to be aligned on a 256 byte boundary. These buffers must be a multiple of 256 Bytes in size with a maximum size of 63.75kB

    Example:

    ptDevInstance->ulDMABufferCount = 8;
    ptDevInstance->atDmaBuffers[0].ulSize             = 8192;
    ptDevInstance->atDmaBuffers[0].ulPhysicalAddress  = <Insert phys. address here>;
    ptDevInstance->atDmaBuffers[0].pvBuffer           = <Insert virtual / cpu accessible pointer here>;
    ptDevInstance->atDmaBuffers[0].pvUser             = MyDMAData;
    ...
    ptDevInstance->atDmaBuffers[7].ulSize             = 8192;
    ptDevInstance->atDmaBuffers[7].ulPhysicalAddress  = <Insert phys. address here>;
    ptDevInstance->atDmaBuffers[7].pvBuffer           = <Insert virtual / cpu accessible pointer here>;
    ptDevInstance->atDmaBuffers[7].pvUser             = MyDMAData;

     

  • Now you can use any of the cifX API functions to access your devices

Â