ecu-tests/vendor/BLCInterfaceExample.py

327 lines
17 KiB
Python

#!/usr/bin/python3
####
# This is a sample program, which introduces the functions and applications of the Baby-LIN-DLL. To run this program you need the current LINWorks software and
# a Baby-LIN device from Lipowsky Industrie-Elektronik GmbH. Make sure that there is a USB connection between your PC and the Baby-LIN-Device and
# that a voltage of 8-26 VDC is applied to the LIN-Bus.
#
# Table of Contents:
# 1. Display Version of Baby-LIN-DLL und Wrapper
# 2. Connection with the Baby-LIN-Device
# 3. Connection to the LIN-Channel
# 4. Write SerialNumber to signal
# 5. Excecute macro and processing MacroResultString
# 6. Use of getsig/setsig for signal handling
# 7. Frame registration and display of the framecallbacks
# 8. Error handling
####
from __future__ import unicode_literals
from asyncio.windows_events import NULL
from ctypes import *
from hashlib import new
import os, sys, argparse, six
try:
# import the BabyLIN Python wrapper
import BabyLIN_library
except ImportError as e:
six.print_(e)
def parse_arguments():
""" """
# get sdf file from the path where the executable is
parser = argparse.ArgumentParser(description="run `main.py` on sdf file")
parser.add_argument("-s", "--sdf", help="sdf file to load",
default="Example.sdf")
parser.add_argument("-v", "--verbose", action="count", default=0)
args = parser.parse_args()
return args.sdf, args.verbose
def main(sdf_name, verbose):
""" Standard example. """
def framecallback(handle, frame):
""" frame callback to be used later."""
six.print_(frame)
return 0
if verbose == 1:
six.print_("Using dynamic library " + BabyLIN.BABYLIN_DLL_PATH_NAME)
# create the BabyLIN class contained in BabyLIN_DLL.py
BabyLIN = BabyLIN_library.create_BabyLIN()
# inject BabyLIN names into local namespace, so you can, e.g. write
# BLC_getVersion instead of BabyLIN.BLC_getVersion
for k, v in BabyLIN.__dict__['_libNames'].items():
globals()[k] = getattr(BabyLIN, k)
if verbose == 1:
six.print_("Using sdf file " + sdf_name)
try:
six.print_("Test programm started")
six.print_("#####################################")
six.print_("")
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 1. Display Version of Baby-LIN-DLL und Wrapper
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Display the version of the BabyLIN DLL and the .net Wrapper
six.print_("DLL and wrapper version are read out")
six.print_("")
dllVersion = BLC_getVersionString()
wrapperVersion = BLC_getWrapperVersion()
six.print_("BabyLIN version: ", dllVersion)
six.print_("BabyLIN python Wrapper version: ", wrapperVersion)
six.print_("")
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 2. Connection with the Baby-LIN-Device
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Search for Baby-LIN devices
# The BLC_getBabyLinPortsTimeout() function is also searching for network devices
# If you are using only Baby-LIN devices with USB port, you can use BLC_getBabyLinPorts()
portCount = 100 # Find up to 100 devices
six.print_("Search for Baby-LIN-Devices for connection...")
portList = BLC_getBabyLinPorts(portCount)
if portList == 0:
six.print_("Could not find any Baby-LIN devices.")
sys.exit(-1)
six.print_(str(len(portList)) + " devices were found for the connection")
six.print_("")
portList = BLC_getBabyLinPortsTimout(portCount, 3000)
if portList == 0:
six.print_("Could not find any Baby-LIN devices.")
sys.exit(-1)
# In this example, we will be using the first found Baby-LIN device
if len(portList) < 1:
six.print_("Could not find any Baby-LIN devices.")
sys.exit(-1)
port = portList[0]
# Open a connection to the first found BabyLIN
six.print_("The connection to the first Baby-LIN-Device of the portlist is established.")
handle = BLC_openPort(port)
if handle == NULL:
six.print_("The connection to the BabyLIN could not be opened. Please check, that the COM Port is correct.")
sys.exit(-1)
# Download the SDF file into the BabyLIN device
six.print_("SDF download...")
six.print_("")
rc = BLC_loadSDF(handle, sdf_name, 1)
if rc != 0:
six.print_("The SDF file could not be loaded into the BabyLIN. Please check, that the filename is correct.")
sys.exit(-1)
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 3. Connection to the LIN-Channel
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Get the number of available channels
six.print_("Output of the channel info")
channelCount = BLC_getChannelCount(handle)
six.print_("available channels: " + str(channelCount))
# the example will open the first device with an included
# LIN channel, download the sdf to it, start the LIN bus,
# register a frame-callback and watch the incoming LIN-frames
# in the callback.
# open the device(s)
conHandle = (handle for port in portList)
# get the device's number of channels
channelCount = ((BLC_getChannelCount(h), h) for h in conHandle)
# among these, look for the first LIN channel:
channelRange = ((range(chNr), h) for chNr, h in channelCount)
# first, get the corresponding channel handles
channelHandle = ((BLC_getChannelHandle(h, channelIndex), h)
for r, h in channelRange for channelIndex in r)
# for each channel (handle), get the channel info
chInfo = ((BLC_getChannelInfo(ch), h, ch) for ch, h in channelHandle)
# using the channel info, filter the LIN channels
# using 'info.type == 0'
conH_chH = ((h, ch) for info, h, ch in chInfo if info.type == 0)
for conHandle, channelHandle in conH_chH:
# for debugging, print ChannelInfo
channelInfos = BLC_getChannelInfo(channelHandle)
six.print_("Channel info: Name=" + str(channelInfos.name) + " , Type=" + str(channelInfos.type) + " , MaxBaudrate=" + str(channelInfos.maxbaudrate))
# start the LIN bus
six.print_("Connect to channel number 1 and start the schedule number 0")
six.print_("")
scheduleNr = 0
rc = BLC_sendCommand(channelHandle, "start schedule " + str(scheduleNr) + ";")
if rc != 0:
six.print_("Could not start the LIN bus.")
sys.exit(-1)
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 4. Write SerialNumber to signal
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Write Signal Serial_Number
# The SDF provides the following signals: SN_Byte_0, SN_Byte_1, SN_Byte_2 ,SN_Byte_3, SN_Byte_4, SN_Byte_5, SN_Byte_6, SN_Byte_7
# With the BLCvarWrite() command the signals can all be written with one operation. The varible data_len determines the number of signals to be set.
# Exactly one byte is assigned to each signal
six.print_("Precessing the serial number")
signal_nr = 0
data_len = 8
data = bytes([83, 78, 48, 49, 50, 51, 52, 53]) # ASCII-Code: "SN012345"
rc = BLC_varWrite(channelHandle, signal_nr, data, data_len)
if rc != 0:
six.print_("Could not write into signal Serial_Number.")
sys.exit(-1)
# Read signal Serial_number for control
# The BLC_varRead() command reads a certain number of signals and stores them in a byte buffer, which is passed to the function when it is called.
# The number of signals to be read is determined by the variable lenght.
lenght = 8
SignalValue = BLC_varRead(channelHandle, signal_nr, lenght)
if SignalValue == 0:
six.print_("Could not read the signal Serial_Number.")
sys.exit(-1)
six.print_("Serial number set via BLC_varWrite command")
six.print_("")
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 5. Excecute macro and processing MacroResultString
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Execute 01_process_SerialNumber
# In this macro the data from the SN_Byte signals are read out and combined to a result string.
# The Baby_LIN_DLL provides a set of Baby_LIN commands which can be executed with the BLC_sendCommand().
#
# The macro_exec command executes the macro with the passed macro number. The BLC command does not wait until the macro is fully executed.
# This must be implemented by the user with the function BLC_macro_result. As long as the macro is still executed, the BLC function returns the value 150.
six.print_("Create MacroResultString out of serial number bytes")
macro_nr = 0
return_value = 0
timeout_ms = 250
rc = BLC_sendCommand(channelHandle, "macro_exec " + str(macro_nr) + ";")
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
rc = BLC_macro_result(channelHandle, macro_nr, timeout_ms)
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
# Get MacroResultString
# When executing a macro it returns a result string after successful completion.This can be set additionally by MAcro command print.
# With parameter passing the values from the signals can be put together to a result string easily. The encoding of the output can also be set,
# which is shown by the two outputs in ASCII code and HEXByte code.
MacroResultStringASCII = BLC_getMacroResultString(channelHandle, macro_nr)
six.print_("Serial number: " + MacroResultStringASCII + "(ASCII Code)")
six.print_("")
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 6. Use of getsig/setsig for signal handling
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Use of getsig and setsig with BLC_sendCommand()
# The BabyLIN commands getsig and setsig are responsible for reading and setting individual signals.
# The signal used is determined by the signal number. This can be found in the bus description of the SDF.
# The signal_flag can be used to determine at which time or event the signal is to be read out:
# signal_flag = 0x00, returns the last value written to the bus signal.
# signal_flag = 0x01, reset fresh flag and wait for fresh signal value appearing on bus.
# signal_flag = 0x02, return signal value as result, if fresh value is availble, otherwise returns RETCODE_OPERATION_PENDING
six.print_("Set the bus signals of brightness by setsig and getsig command")
signal_nr = 8
signal_flag = 0
index = 0
luminanceValue = 100
BLC_sendCommand(channelHandle, "getsig " + str(signal_nr) + " " + str(signal_flag) + ";")
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
rc = BLC_lastAnswerHasData(channelHandle)
if rc == 0:
ByteValue = BLC_getAnswerByIndex(channelHandle, index)
six.print_("Current luminance configuration: " + str(ord(ByteValue)))
# Signal value luminance is set to 100 with BLC_sendCommand "setsig"
rc = BLC_sendCommand(channelHandle, "setsig " + str(signal_nr) + " " + str(luminanceValue) + ";")
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
# Control setsig Command with readout the Signal value again via getsig
rc = BLC_sendCommand(channelHandle, "getsig " + str(signal_nr) + " " + str(signal_flag) + ";")
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
rc = BLC_lastAnswerHasData(channelHandle)
if rc == 0:
ByteValue = BLC_getAnswerByIndex(channelHandle, index)
six.print_("Luminance increased to 100")
six.print_("Current luminance configuration: " + str(ord(ByteValue)))
six.print_("")
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 7. Frame registration and display of the framecallbacks
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Here we will subscribe to get frames and write their data
# The disframe command can be used to subscribe to specific frames. These are determined by the frame ID.
# If you pass 0xff as parameter, a special case is executed and all frames defined in the SDf are subscribed.
# The frames are defined as a structure in the DLL and thus offer the possibility to display all information, such as the FrameID or the timestamp.
six.print_("Subscribe to Frames")
# Subscribe to frames
FrameIDForAllFrames = 0xff
rc = BLC_sendCommand(channelHandle, "disframe " + str(FrameIDForAllFrames) + " 1;")
if rc != 0:
six.print_("BLC command could not be executed.")
sys.exit(-1)
# the output of the callback will fill up the screen quickly
# press <ENTER> to see the incoming frames, and <ENTER> again
# to stop the output
try:
p = "Starting frame callback now...\n"
p += "Press <Enter> to start and stop"
input(p)
except Exception as e:
pass
# register the frame-callback
BLC_registerFrameCallback(channelHandle, framecallback)
try:
input("") # waiting for the next <enter>
except Exception as e:
pass
# de-register the frame-callback
BLC_registerFrameCallback(channelHandle, None)
# stop the LIN-bus
BLC_sendCommand(channelHandle, "stop;")
# close all devices. end of example.
BLC_closeAll()
break
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# 8. Error handling
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
except BabyLIN.BabyLINException as e:
six.print_(e)
if __name__ == '__main__':
sdf, verbose = parse_arguments()
try:
main(sdf, verbose)
except KeyboardInterrupt:
pass