All Files Functions Typedefs Enumerations Enumerator Macros Pages
Sample Code

MyBconAdapter Sample

The following files are part of the MyBconAdapter Sample which illustrates the implementation of important BCON Adapter library functions and how to debug these implementations.

This sample can be found in the folder Samples/BconAdapterSample There is also a GNU makefile for this sample, see Makefile.

MyBconAdapterLibrary.c

#include "MyBconAdapterLogging.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
{
SetExternalLogFunction(pTraceFunc);
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterInit called");
return BCON_OK;
}
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterExit called");
return BCON_OK;
}
unsigned int *apiMajorVersion,
unsigned int *apiMinorVersion,
unsigned int *adapterMajorVersion,
unsigned int *adapterMinorVersion)
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterGetVersion called");
assert(apiMajorVersion);
assert(apiMinorVersion);
assert(adapterMajorVersion);
assert(adapterMinorVersion);
apiMajorVersion = BCON_ADAPTER_API_MAJORVERSION;
apiMinorVersion = BCON_ADAPTER_API_MINORVERSION;
adapterMajorVersion = 1;
adapterMinorVersion = 0;
return BCON_OK;
}

MyBconAdapterI2CConnection.c

#include "MyBconAdapterLogging.h"
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
// Limit for string length
#define MAX_STRING_LENGTH 256
// Helper function to convert BconAdapterI2cBusHandle to file descriptor (int)
static int getFd(BconAdapterI2cBusHandle arg)
{
return *((int*)(&arg));
}
const char deviceId[], BconAdapterI2cBusHandle *phBus, uint32_t *pDeviceAddress)
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterI2cOpenConnection called");
// Copy string for usage
char devicePath[MAX_STRING_LENGTH] = { 0 };
strcpy(devicePath, deviceId);
// String is like "/dev/i2c-2:99", so find ':'
char *separator = (char*)strchr(devicePath, ':');
if (separator == NULL)
{
LogOutput(TRACE_LEVEL_ERROR, "Device ID incomplete.");
}
// Open device
separator[0] = '\0';
int fp = open(devicePath, O_RDWR);
if (fp <= 0)
{
LogOutput(TRACE_LEVEL_ERROR, "Could not open device.");
}
// Parse device address
int deviceAddress = atoi(separator + 1);
if ((deviceAddress < 0) || (deviceAddress >= 128))
{
LogOutput(TRACE_LEVEL_ERROR, "Error parsing device address, only 7-bit address allowed.");
close(deviceAddress);
}
// Return value device address
if (pDeviceAddress != NULL)
{
pDeviceAddress = deviceAddress;
}
// Return value bus handle
if (phBus != NULL)
{
phBus = (BconAdapterI2cBusHandle)(long)fp;
}
return BCON_OK;
}
BconAdapterI2cBusHandle hBus, uint32_t deviceAddress)
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterI2cCloseConnection called");
(void)deviceAddress;
// Close file descriptor
int ret = close(getFd(hBus));
if (ret != 0)
{
LogOutput(TRACE_LEVEL_ERROR, "Could not close device.");
}
return BCON_OK;
}
EXTERN_C BCON_ADAPTER_API BCONSTATUS BCON_ADAPTER_CALL BconAdapterI2cRead(
uint32_t deviceAddress,
void *pData,
size_t sizeInBytes,
size_t *pBytesRead,
uint32_t timeout_ms)
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterI2cRead called");
(void)timeout_ms;
// Set target device address
if (ioctl(getFd(hBus), I2C_SLAVE, deviceAddress) < 0)
{
LogOutput(TRACE_LEVEL_ERROR, "Error setting target address.");
}
// Read from I2C
int bytesRead = read(getFd(hBus), pData, sizeInBytes);
if (bytesRead <= 0)
{
}
else
{
pBytesRead = bytesRead;
return BCON_OK;
}
}
EXTERN_C BCON_ADAPTER_API BCONSTATUS BCON_ADAPTER_CALL BconAdapterI2cWrite(
uint32_t deviceAddress,
const void *pData,
size_t sizeInBytes,
uint32_t timeout_ms)
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterI2cWrite called");
(void)timeout_ms;
// Set target device address
if (ioctl(getFd(hBus), I2C_SLAVE, deviceAddress) < 0)
{
LogOutput(TRACE_LEVEL_ERROR, "Error setting target address.");
}
// Write to I2C
// Note: The BCON camera uses clock stretching.
// The used I2C master hardware must support clock stretching properly.
int bytesWritten = write(getFd(hBus), pData, sizeInBytes);
if (bytesWritten != sizeInBytes)
{
}
else
{
return BCON_OK;
}
}

MyBconAdapterEnumerator.c

#include "MyBconAdapterLogging.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
{
LogOutput(TRACE_LEVEL_INFORMATION, "BconAdapterStartDiscovery called");
BCONSTATUS returnCode = BCON_OK;
// Get the I2C device configuration from environment variable BCON_ADAPTER_I2C_DEVICES
//
// Example for how to set BCON_ADAPTER_I2C_DEVICES for two devices:
//
// export BCON_ADAPTER_I2C_DEVICES="/dev/i2c-1:77 /dev/i2c-2:99"
//
// The two device identifiers /dev/i2c-1:77 and /dev/i2c-2:99 are separated by a blank.
// The first device identifier /dev/i2c-1:77 consists of the I2C bus to open /dev/i2c-1
// and the device address 77, the bus and address parts being separated by a colon.
// Analog for the second device identifier /dev/i2c-2:99.
char *env_config = getenv("BCON_ADAPTER_I2C_DEVICES");
if (env_config == NULL)
{
LogOutput(TRACE_LEVEL_ERROR, "Error reading env.var. ");
}
// Duplicate string for usage
char *config = strdup(env_config);
if (config == NULL)
{
LogOutput(TRACE_LEVEL_ERROR, "Error out of memory. ");
}
// Splitting the config string at the blanks yields the device identifier tokens.
// Call the callback function for each token.
char *token = strtok(config, " ");
do
{
LogOutput(TRACE_LEVEL_INFORMATION, "Current Token is _%s_", token);
if (callbackToBconAdapterUser != NULL)
{
BCONSTATUS callbackToBconAdapterUserStatus = callbackToBconAdapterUser(token, (userCtx));
if (!BCON_SUCCESS(callbackToBconAdapterUserStatus))
{
LogOutput(TRACE_LEVEL_ERROR, "Error calling BCON Adapter user callback in enumeration, status = 0x%08X", callbackToBconAdapterUserStatus);
returnCode = callbackToBconAdapterUserStatus;
}
}
token = strtok(NULL, " ");
}
while (token != NULL);
// free duplicate string created using strdup()
free(config);
return returnCode;
}

MyBconAdapterLogging.h

#pragma once
// Trace level constants
#define TRACE_LEVEL_FATAL (BconAdapterTraceLevel_Critical)
#define TRACE_LEVEL_ERROR (BconAdapterTraceLevel_Error)
#define TRACE_LEVEL_WARNING (BconAdapterTraceLevel_Warning)
#define TRACE_LEVEL_INFORMATION (BconAdapterTraceLevel_Information)
#define TRACE_LEVEL_VERBOSE (BconAdapterTraceLevel_Verbose)
#define TRACE_LEVEL_DEBUG (BconAdapterTraceLevel_Debug)
// Write to log output
void BCON_ADAPTER_CDECL LogOutput(BconAdapterTraceLevel level, const char *pFormat, ...);
// Set log function pointer
void SetExternalLogFunction(BconTraceFunc pFunc);

MyBconAdapterLogging.c

#include "MyBconAdapterLogging.h"
#include <stdio.h>
#include <stdarg.h>
// global function pointer for log function
static BconTraceFunc g_pTraceFunc = NULL;
// Write log output using the log function set with SetExternalLogFunction
void BCON_ADAPTER_CDECL LogOutput(BconAdapterTraceLevel level, const char *pFormat, ...)
{
if (g_pTraceFunc == NULL)
{
return;
}
va_list argptr;
va_start(argptr, pFormat);
BconTraceFunc pTraceFunc = g_pTraceFunc;
if (pTraceFunc != NULL)
{
pTraceFunc(level, pFormat, argptr);
}
va_end(argptr);
}
// Set log function pointer, handed down in BconAdapterInit()
void SetExternalLogFunction(BconTraceFunc pFunc)
{
g_pTraceFunc = pFunc;
}

Makefile

# Makefile for BCON Adapter sample library
.PHONY: all clean
# The shared library to build
NAME := libBconAdapterMySample.so
# Installation directories for pylon
PYLON_ROOT ?= /opt/pylon5
CC ?= gcc
CPPFLAGS := -I. $(shell $(PYLON_ROOT)/bin/pylon-config --cflags-only-I)
CFLAGS := -fPIC -fvisibility=hidden -Wall
LDFLAGS := -shared
DEPS := MyBconAdapterLogging.h
OBJS := MyBconAdapterLibrary.o MyBconAdapterI2CConnection.o MyBconAdapterLogging.o MyBconAdapterEnumerator.o
# Rules for building
%.o: %.c $(DEPS)
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
all: $(NAME)
$(NAME): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
clean:
$(RM) $(OBJS) $(NAME)

BCONAdapterAPI 1.0
© 2016 Basler AG (Thu Aug 11 2016 18:01:25)