How to port the cifX Toolkit
Basics:
There are two different types of devices being handled:
- Flash-based devices (like a comX) which have their firmware running out of flash
- 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_WritePCIConfig2) 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.75kBExample:
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
Â