Writing your own libtsctl direct access application in C

From embeddedTS Manuals

While other sections cover how to get started controlling our boards without needing to write any code (using the tsctl command line), you may wish to develop your own application to directly access the Technologic Systems hardware. This is the superior solution if you need high performance and do not need the ability to control the board functions remotely. Note that libtsctl is designed to work best when only a single application at a time is using it. If multiple applications are linked against libtsctl with the idea of being run simultaneously, special care is needed to be taken to prevent them from "stepping on each other's toes".

Direct access applications can be written in any language that has the capability to interface with C. We provide an (unsupported) SWIG example to demonstrate how it is possible to do this from Python. However in this section we will discuss writing directly in C.

To begin, first get the latest source code from GitHub: https://github.com/embeddedTS/libtsctl

The top-most directory of the project contains the Makefile and the source code to the sample apps. The ts directory contains the libtsctl source code. The dioctl.config directory contains the config files for all the architecture, and a script to create the compressed version of these for inclusion into libtsctl - note that this is already done so unless you want to modify an existing config you will not need to touch this directory.

Once you have the source code on your system there are two approaches to adding libtsctl to your application:

1. Adding your application to the libtsctl directory

This is probably the simplest approach, especially if your application consists of only a single source code file. All of the sample applications included with libtsctl use this approach. Your application will need to include "libtsctl.h", and you will need to add a couple of entries to the supplied Makefile, one to direct builds of your application to the proper sub-directory, and the other to list the dependencies for your project. The easiest way to do this is probably to copy/paste/modify an existing entry for one of the sample apps provided. For example:

MapDump: $(DIR)/MapDump
       @true

$(DIR)/MapDump: $(addprefix $(DIR)/,MapDump.o Arch.o NoThread.o $(ARCHLIBS) libtsctl.a) -lbz2 

In the above example, you would replace "MapDump" with the name of your application source file - if there are multiple source files you would replace MapDump.o with an object file for each source file. If you need pthreads you would change NoThread.o to PThread.o and add -lpthread to the end. You will need pthreads if you are running the CAN server in your application, even if your own app does not use pthreads.


2. Linking libtsctl in your own project directory

This is the ideal choice if you already have a build process in place for your application and simply want to drop in libtsctl support.

The first step is to build all the libraries (e.g. "make libtsctl.a") and then copy libtsctl.a and libtsctl-export.h (renaming it libtsctl.h) to somewhere that your project build process expects them, and the library for each architecture you want to support. For instance, if you have a TS-4200 with a TS-8100 base board you would need libtsctl.a, libts4200.a and libts81x0.a. Then, include libtsctl.h anywhere you need it, and link against the .a files. Note that because of circular dependencies between libtsctl.a and the architecture support libraries you will either need to link against libtsctl twice (once at the beginning and once at the end) or wrap all the libraries with -Wl,--start-group" and "-Wl,--end-group" in order to avoid undefined symbol errors, e.g.

-ltsctl -lts4200 -lts81x0 -ltsctl

or

-Wl,--start-group -ltsctl -lts4200 -lts81x0 -Wl,--end-group

Note that in some cases, in addition to libtsctl.h you may also need to copy and include "Array.h" (if any libtsctl functions used take or return an "Array", which by convention is denoted by the "*" in the pointer being bound to the type e.g. with no spaces.