MxNetLabviewRT.lvproj and MxNet.lvlib group all of the VIs and files used by the LabVIEW RT system. MxNetLabviewRT.dll (DLL) contains the API to interface LabVIEW and MxNet.
msvcp80.dll and msvcr80.dll are DLLs associated with Microsoft Visual Studio C++ Runtime Library and are used by MxNetLabviewRT.dll because it is written with Microsoft Visual Studio.
MxNet protocol is controlled by a set of VIs and DLL function calls. Initialization calls ensure that data structures are properly initialized. 1ms tick calls ensure that data is periodically processed.
MxInit.vi – calls MxLV_Init(), initializes all of the internal structures and buffers.
MxClose.vi – calls MxLV_Close(), finalizes and clears resource usage inside DLL.
MxConnected.vi – calls MxLV_MxNetConnected() to check connection status, returns 0 if not connected, returns 1 if connected, returns 2 if connected and the test has started.
MxTestStarted.vi – calls MxLV_MxNetStarted() to check if a test has started, which returns 0 if not started, returns 1 if started. If a test has started, this VI sets the start time. For every iteration, this VI returns current time used everywhere else inside main loop.
MxTickRx.vi – calls MxLV_MxNetRxTask1ms() with the current timestamp to execute MxNet tasks to process received data.
MxTickTx.vi – calls MxLV_MxNetTxTask1ms() to execute MxNet tasks to transmit data.
MxNetTask.vi – this is the main loop for the MxNet Protocol. At the very least, it should contain VIs for Rx and Tx MxNet tick which are expected to be ticked every 1 ms. Within global sequence of events, this VI should be executed after initialization and enumeration, and after hardware channels are opened. UDP and CAN tasks are expected to be running in parallel.
Example.vi – is the top level VI that is executed to run the test. It shows the sequence at which the system is set up and provides and example implementation of RT test system using the available MxNet API to set up and run the test.
The UDP communication layer is controlled by a set of functions that act as intermediate data transfer between the MxNet API and LabVIEW which controls UDP socket connection.
MxUDP.vi – opens a UDP socket on a given port, and launches UDP receive and UDP transmit threads.
MxUdpOpen.vi – calls MxLV_UDP_Open() after LabVIEW UDP open creates a UDP socket.
MxUdpRead.vi – calls MxLV_UDP_Read(uint32 connect ID, uint 32 address, uint 16 port, uint 8* data, uint 32* size) when LabVIEW UDP receives data, to pass it into DLL for processing.
MxUdpReceive.vi – UDP receive thread, calls MxUdpRead.vi when data is received.
MxUdpTransmit.vi – UDP transmit thread, calls MxUdpWrite.vi to check if there is any data to be transmitted over UDP.
MxUdpWrite.vi – calls MxLV_UDP_Write(uint 32* connectID, uint 32* address, uint 16* port, uint8* data, uint32* size) function which returns 0 if there is no data to write, and returns 1 if parameters now contain data to transmit over UDP.
Enumeration is done to identify all connected devices and their ports. After a call to enumerate each device is done, the function returns deviceID, which is used as a reference to this device from now on. Each device with a unique deviceID will have a corresponding transform in MxTransIt graph when Enumeration is performed using MxTransIt.
MxAddCCP.vi - calls MxLV_EnumAddCCP(char* name, uint32 bused, uint32 txId, uint32 rid, uint8 bigEndian, uint8 extended, uint16 stationId) to enumerate CCP device and returns deviceId.
MxAddCustom.vi – calls MxLV_EnumAddCustomDevice(char* name) to enumerate a custom/user Device (such as FPGA), and returns deviceID.
MxAddMIO.vi – calls MxLV_EnumMIOAddCard(uint8 id, char* name, char* productType, uint32 serialNumber, uint8 devClass) to enumerate NI digital or analog MIO card. Returns deviceID.
MxAddTP.vi – calls MxLV_EnumAddTP(char* name ) to enumerate CAN Transport Protocol device. Returns device ID.
MxEnumAddAnalog.vi – calls MxLV_EnumAddAnalog(uint32 deviceId, char* name, char* physicalPath, uint16 channelNumber, uint16 direction) to enumerate physical analog channels. This VI should be called once a deviceID from MxAddMIO.vi is obtained, and it should be called once for every input and output channel that is found in the system for the current device.
MxEnumAddCan.vi - calls MxLV_EnumAddCANPort(char* cardSeries, uint16 port, char* busName, uint32 serialNumber) to enumerate CAN ports found on the system.
MxEnumAddDigital.vi – calls MxLV_EnumAddDigital(uint32 deviceId, char* name, char* physicalPath, uint16 port, uint16 line, uint16 direction) to enumerate physical digital channels. This VI should be called once a deviceID from MxAddMIO.vi is obtained, and it should be called once for every input and output channel that is found in the system for the current device.
MxEnumAnalogChannels.vi - calls MxEnumAddAnalog.vi for every analog physical channel. The input into this VI is the array of AI or AO physical channels returned by the DAQmx Device Property.
MxEnumClear.vi - calls MxLV_EnumClear() to clear previously enumerated devices.
MxEnumDigitalLines.vi - calls MxEnumAddDigital.vi for every digital line. The input into this VI is the array of DI or DO lines returned by the DAQmx Device Property.
MxEnumerateIO.vi – top level enumeration VI that enumerates the whole LabVIEW system. Required inputs are CCP and TP configuration arrays.
Custom_Enum_FPGA_Channels.vi – example VI that shows how to enumerate input and output signals/channels for a custom/user device such as FPGA.
All of the input and output data is transferred from and to MxNet by a set of commands specific for the type of data (CAN message, discrete/digital, or continuous/analog).
MxProcessCommands.vi – is the VI that requests new data from DLL. The main input to this VI is the current time. First call is made to MxNextCommand.vi to check whether there is a command to execute, if there is it returns the type of the command. Based on the type, MxGetCANMessage, MxGetContinuous, or MxGetDiscrete is called. This VI is executed until there are no more commands for the current time.
MxNextCommand.vi – calls DLL function MxLV_GetNextTransition(mxI64 now_ns, mxI64* cmd_ns, uint16* deviceClass, uint8* dataType), returns 0 if there is no more transitions for the current time, returns 1 if there is a transition and returns DeviceClass and DataType to identify which VI to call next.
MxGetCANMessage.vi – calls MxLV_GetNextCanMessage(uint16* bus, uint32* arbId, uint8* extended, uint8* wakeup, uint8* dlc, uint8* payload) to obtain next CAN message that has been queued for transmission.
MxGetContinuous.vi – calls MxLV_GetNextContinuous(uint16* device, uint16* channel, mxF64* data) to obtain a value to be written to analog channel.
MxGetDiscrete.vi – calls MxLV_GetNextDiscrete(uint16* device, uint16* channel, mxI64* data) to obtain a value to be written to digital line.
MxSendCanMessage.vi – calls MxLV_SendCanMessage(mxI64 time_ns, uint8 bus, uint32 arbId, uint8 extended, uint8 wakeup, uint8 dlc, uint8* payload) to transmit a received message from the CAN bus back to MxNet.
MxSendContinuous.vi – calls MxLV_SendContinuous(mxI64 time_ns, uint16 deviceClass, uint16 device, uint16 channel, double data) to transmit continuous data type back to MxNet.
MxSendDiscrete.vi - calls MxLV_SendDiscrete(mxI64 time_ns, uint16 deviceClass, uint16 device, uint16 channel, mxI64 data) to transmit discrete/digital data type back to MxNet
MxReadIO.vi – this VI goes through all data sources and calls the appropriate VI to handle new data. Digital/Analog is read from the hardware. CAN is received using RT FIFO, user/custom device data is received from a custom interface.
MxWriteIO.vi – this VI is called after digital and analog data is received using MxProcessCommands, and is written to the hardware cards.
MxWriteCan.vi – this VI is called when a CAN message is received inside MxProcessCommands, it is transmitted to the CAN thread using RT FIFO queue.
FPGA_Interface.vi – this is a customizable VI that references sink or data source for custom/user data. In the Example.vi implementation, MxReadIO.vi reads from this VI, and MxProcessCommands sends data to it if the data type is marked as user device. Before using this for custom device interface, the device and its inputs and outputs need to be enumerated.
CAN communication is done on the separate threads for CAN receive and transmit. The data is passed from the main I/O thread to CAN threads using RT FIFO queues. CAN hardware is ‘started’ when the global flag indicates that the test was started.
MxCanTask.vi – VI that launches CAN Rx and CAN Tx tasks.
MxCanTaskRx.vi – VI that reads CAN data from a CAN bus and transmits the data to RT FIFO queue when any messages are received on the current bus. Bus handles are initialized during set up sequence.
MxCanTaskTx.vi – VI that writes data on CAN bus when a message is received on RT FIFO queue from the main IO thread.
MxConvertCanFrame.vi - A utility VI that converts the CAN data frame from the format that is used by CAN VIs to the one that RT FIFO expects. (RT FIFO does not handle arrays, so the message is translated from an array of 8 bytes to fixed struct of 8 bytes)
MxConvertRtFrame.vi – A utility VI that converts the CAN data frame from RT FIFO format to LabVIEW CAN VI format.
Set up happens after the enumeration, when hardware resources are being requested and handles obtained.
Activate Channels.vi – this VI is called for every digital device that needs to be configured. Since some devices allow digital lines to be either input or output, this is necessary to distinguish how they will be set up. DeviceID specifies the digital card (this id is returned from calling AddMIO.vi ) An array of Boolean values identifies how the digital lines are used. Setting the value to True marks the channel Input, and False marks it as Output. The index of the array specifies the digital channel.
MxMarkActive.vi – calls MxLV_EnumMarkActive(uint32 deviceId, uint8 direction, uint32 channel, uint8 active) to identify which lines (channels) are being used and how (input/output). By default, all digital channels are marked as inactive, and all analog and CAN channels are marked active.
MxGetTasksStrings.vi - calls MxLV_GetTaskStrings(char* aiTask, char* aoTask, char* diTask, char* doTask, char* canTask, char* extTask, int maxLength) to obtain the LabVIEW Task Strings. These strings are the names of physical channels used by LabVIEW. For Analog Input, Analog Output, Digital Input, and Digital Output the string uses a comma to separate each task, and a vertical bar character (“|”) to split devices. For example, a Digital Input string may look like this: “Dev1/port0/line0, Dev1/port0/line1 | Dev2/port0/line0”.
MxConfigureAnalogInputs.vi – Sets up DAQmx Tasks for Analog inputs and creates an array of dimensions that correspond to the number of analog devices and channels. This array is filled with data received from MxNet and written to hardware.
MxConfigureAnalogOutputs.vi - Sets up DAQmx Tasks for Analog outputs and creates an array of dimensions that correspond to the number of analog devices and channels. This array is filled with data read from hardware and is transmitted to MxNet.
MxConfigureCAN.vi – this VI sets up a CAN Network Interface object from LabVIEW, obtains object handles, and creates RT FIFO queues that are used to exchange CAN messages between I/O threads and CAN threads.
MxConfigureDigitalInputs.vi - Sets up DAQmx Tasks for Digital inputs and creates an array of dimensions that correspond to the number of digital devices and lines. This array is filled with data received from MxNet and written to hardware.
MxConfigureDigitalOutputs.vi - Sets up DAQmx Tasks for Digital outputs and create an array of dimensions that correspond to the number of digital devices and channels. This array is filled with data read from hardware and is transmitted to MxNet.
MxCanTpConfig.vi – calls function MxLV_CanTp_Config(uint16 busId, uint32 rxId, uint32 txId, uint32 brdId) to configure a CAN Transport Protocol stack.
MxOpenHardware.vi – this VI contains all of the code that initializes hardware. It requests the LabVIEW Task Strings and based on them DAQmx Tasks are created and CAN is initialized.
MxCloseHardware.vi – this VI contains code that is needed to successfully close hardware. More specifically CAN object handles need to be released before they can be opened again.
MxClock.vi – gets the 1 microsecond time stamp from the RT counter, does the check to make sure the counter did not roll-over.
Globals.vi – contains global variables used by VIs throughout the system.
MxStartLogging.vi – calls MxLV_StartLogging() and begins debugging trace log, by logging each entrance into DLL and writes it to a file.
MxStopButton.vi - stops execution of the test. Stops all VIs running in parallel.
MxStopLogging.vi – calls MxLV_StopLogging() and stops debugging trace and writes a file to C:/MxDebugLog.txt
MxSplitString.vi – utility VI used to split a string based on the input delimiter.
The following TypeDefs and Enums are used throughout the code to simplify comparison and flow of data.
CanTP Config.ctl – CAN Transport Protocol configuration parameters:
Bus ID: can port which is used to send CAN messages on
RxID: receive message ID
TxID: transmit message ID
brbID: broadcast message ID
Name: name given to the current TP stack, used to create transform in MxTransIt.
CCP Config.ctl - CCP configuration sent to MxNet.
Name: name given to the current CCP stack, used to create transform in MxTransIt.
busId: CAN port which is used to send CAN messages on
BusId: specifies which CAN bus (port) to send CAN messages on associated with this CCP ‘stack’
TxId: is CRO - Command Receive Object : message sent from the master device to the slave device.
RxId: is DTO - Data Transmission Object : message sent from the slave device to the master device (Command Return Message or Event Message or Data Acquisition Message).
big-Endian and Extended: are Boolean flags to specify device endianness and extended addressing.
StationId: station address of slave device.
ContinuousCommand.ctl – TypeDef to specify continuous/analog transition, which contains deviceID, channel and value
DataDirection.ctl – enum to distinguish data direction. Output = 0, Input = 1
DataType.ctl – enum to distinguish data types: Discrete/digital = 0, Continuous = 1, Message = 2
Device Class.ctl – enum corresponding to MxNet device classes, User/Custom = 0, Digital = 1, analog = 2, Enum = 3, CAN = 4, CANTP = 5, CCP = 6
Device Id.ctl – numeric type.
Device Index.ctl – array of Driver Info.ctl
DiscreteCommand.ctl - TypeDef to specify digital transition, which contains deviceID, channel and value.
Driver Info.ctl – device driver info, contains Name, Device ID, Driver Class
RT CAN Frame.ctl – TypeDef for a CAN frame which is almost identical to LabVIEW CAN frame except the data is not an array but a cluster of 8 bytes.
Tasks.ctl – array of all tasks used throughout the test environment. AI/AO/DI/DO DAQmx tasks, CAN object handles and RT FIFO queues, custom/fpga device id
TransitionCommand.ctl – specifies the next transition device class and data type along with timestamp.