Accessing Environment Variables from CANlib (2 of 3)

  • September 10, 2015
  • Magnus Carlsson

This is the second post in a 3-part series about Environment Variables in t programs:

  1. Introduction to Environment Variables
  2. Accessing Environment Variables from CANlib
  3. Kvaser TRX and Environment Variables

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 hnd points to.
  • kvScriptEnvvarClose :: (kvEnvHandle eHnd) closes an environment variable (that has been opened with kvScriptEnvvarOpen()).

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 int.
  • kvScriptEnvvarGetInt :: (kvEnvHandle eHnd, int *val) retrieves the value of an environment variable defined as an int.
  • kvScriptEnvvarSetFloat :: (kvEnvHandle eHnd, float val) sets the value of an environment variable defined as a float.
  • kvScriptEnvvarGetFloat :: (kvEnvHandle eHnd, float *val) retrieves the value of an environment variable defined as an float.

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 start_index and 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 char.
  • 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 char.

Let’s try and talk to our t program from Python now.

Using Python and environment variables

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.

Author Image

Magnus Carlsson

Magnus Carlsson is a Software Developer for Kvaser AB and has developed firmware and software for Kvaser products since 2007. He has also written a number of articles for Kvaser’s Developer Blog dealing with the popular Python language.