The first post in this series introduced the environment variable and showed how the environment variable can be used in a t program. This second post shows how environment variables can be accessed using CANlib. Full program listings are available on http://github.com/Kvaser/developer-blog.
Environment variables are used to communicate between different t programs or with a PC using CANlib. An environment variable must be defined in an
envvar section in the t program.
In order to access an environment variable from CANlib you need a handle to the environment variable:
kvScriptEnvvarOpen (const int hnd, char *envvarName, int *envvarType, int *envvarSize)opens an existing environment variable and returns a handle as well as the type and size of the environment variable. In order for an environment variable to exist, the environment variable must have been defined in a t program that has been loaded in the device that the CAN channel handle
kvScriptEnvvarClose :: (kvEnvHandle eHnd)closes an environment variable (that has been opened with
You need to remeber the data type of the environment variable. If you try and access the environment variable using the wrong type, the access will fail. Depending on the data type there are different functions you can use to access the environment variable:
kvScriptEnvvarSetInt :: (kvEnvHandle eHnd, int val)sets the value of the environment variable pointed to by eHnd, which has been defined as
kvScriptEnvvarGetInt :: (kvEnvHandle eHnd, int *val)retrieves the value of an environment variable defined as an
kvScriptEnvvarSetFloat :: (kvEnvHandle eHnd, float val)sets the value of an environment variable defined as a
kvScriptEnvvarGetFloat :: (kvEnvHandle eHnd, float *val)retrieves the value of an environment variable defined as an
The environment variable may also be defined as an array of
char with a length of up to
ENVVAR_MAX_SIZE. In order to reduce the size of the data that is transferred, environment variables defined as array of
char are exchanged using a
data_len. This can be useful if you have divided the data and know what part of the data that you are interested in.
kvScriptEnvvarSetData :: (kvEnvHandle eHnd, void *buf, int start_index, int data_len)Sets a range of data bytes in an environment variable defined as an array of
kvScriptEnvvarGetData :: (kvEnvHandle eHnd, void *buf, int start_index, int data_len)Retrieves a range of data bytes from an environment variable defined as an array of
Let’s try and talk to our t program from Python now.
Now it is time to test if we can talk to a device running the t program outlined in our first post in this series. In order to run this we need the wrappers for environment variables which is included in v5.12 of the CANlib SDK. A pre-release version is available at https://github.com/Kvaser/canlib-samples.
import time import kvDevice # Define some values and messages to send to our device # In order to hide these secret messages, we write them encoded ;-) messages = [(1, "-Jung unccraf gb n sebt'f pne jura vg oernxf qbja?"), (2, "-Vg trgf gbnq njnl."), (3, "-Jul jnf fvk fpnerq bs frira?"), (4, "-Orpnhfr frira 'ngr' avar."), (5, "-Jung vf gur qvssrerapr orgjrra fabjzra naq fabjjbzra?"), (6, "-Fabjonyyf."), (7, "-Jurer qvq lbh svaq gurfr?"), (8, "-uggc://jjj.ynhtusnpgbel.pbz/wbxrf/jbeq-cynl-wbxrf")] # We will be using the first Eagle device found connected to the PC # For an introduction to the kvDevice object, see # http://www.kvaser.com/developer-blog/object-oriented-approach-accessing-kvaser-device-python-3-3/ eagle_ean = "73-30130-00567-9" dev = kvDevice.kvDevice(ean=eagle_ean) # Open a handle to the device dev.open() # Load the t program into slot 0 dev.channel.scriptLoadFile(0, "envvar.txe") # Start the program in slot 0 dev.channel.scriptStart(0) # Our protocol states that we should wait until HostIdConnected is zero before trying to connect print "Waiting for device to be free..." # All calls to the kvScriptEnvarOpen() and kvScriptEnvvarGetXXX() functions are hidden in the # envvar class inside canlib.py. Here we can access it directly with dev.channel.envvar.YYY while dev.channel.envvar.HostIdConnected != 0: time.sleep(0.2) # Now we try to connect by writing our unique id into the environment variable HostIdRequest. # We wait until our connection was accepted, i.e. HostIdConnected contains our id. print "Requesting connection..." myHostId = 42 print "Waiting for device to connect..." while dev.channel.envvar.HostIdConnected != myHostId: if dev.channel.envvar.HostIdConnected == 0: print "Requesting connection..." if dev.channel.envvar.HostIdRequest != myHostId: dev.channel.envvar.HostIdRequest = myHostId time.sleep(0.2) print "Connected!" # Start sending our messages to the device for (severity, message) in messages: print "Sending message %d" % severity dev.channel.envvar.Severity = severity dev.channel.envvar.Message = message.encode('rot13') time.sleep(4) print "Disconnect..." dev.channel.envvar.HostIdRequest = 0 # Stop the script in slot 0 dev.channel.scriptStop(0)
Executing the above Python code results in the following printout on standard out:
Waiting for device to be free... Requesting connection... Waiting for device to connect... Connected! Sending message 1 Sending message 2 Sending message 3 Sending message 4 Sending message 5 Sending message 6 Sending message 7 Sending message 8 Disconnect...
Not very exciting, I agree, so in the last part of this series we will look at how to interact with those environment variables using Kvaser TRX, a light weight IDE for developing t programs for Kvaser devices.