Jump to main content | Jump to Primary Navigation | Jump to Sub Navigation
| Previous tutorial | Next tutorial |
Before reading this tutorial you should have covered Drivers 1: A new device driver.
In this tutorial we introduce a benchmark driver which creates integer arrays of a specified length, and in the polling function iterates through the array incrementing the value at each index. The benchmark driver's properties and behaviour is outlined in the Benchmark Driver entry in the driver database.
The private data for the benchmark driver the private data is called BenchmarkData and consists of 3 fields:
The benchmark driver allocates BenchmarkData memory in the allocate_device(), then sets up the fields in initialize_device(), allocating memory to the array buffer in the process. Interestingly the array property is dynamically created in initialize_device() rather than a statically defined property table, as the length of the property is itself a property. All three fields of BenchmarkData are used in poll_device() to copy the array property to the local array buffer, iterate through the array and copy the result back to the array property. The array buffer has its memory freed in shutdown_device() and BenchmarkData is freed in free_device().
typedef struct { BOT_TYPE_UINT_TYPE *buffer; uint32_t data_length; BotProperty *data; } BenchmarkData;
The benchmark driver uses allocate_device() to allocate space for BenchmarkData.
static bool allocate_device(BotDevice *device) { /* Allocate space for the private data */ bot_device_set_data(device, g_new0(BenchmarkData, 1)); return TRUE; }
In the benchmark driver the mandatory length property is queried and used to dynamically create an array property of that length. If the mandatory length property was not specified by the device, then an error would be returned at this point. Finally the array buffer is allocated appropriate memory.
static bool initialize_device(BotDevice *device) { BenchmarkData *benchmark_data; uint32_t length; /* Validate the requested length of Data */ length = bot_property_get_uint( bot_device_lookup_property(device, "DataLength")); if (length < 1) { bot_warn("Invalid length (%d) for data", length); return FALSE; }
static void shutdown_device(BotDevice *device) { /* Free the data buffer associated with this device */ BenchmarkData *benchmark_data = bot_device_get_data(device); if (benchmark_data->buffer) g_free(benchmark_data->buffer); }
The benchmark driver uses free_device() to free the BenchmarkData memory which was assigned in the allocation function.
static void free_device(BotDevice *device) { /* Get the private data associated with this device, and free it */ BenchmarkData *benchmark_data = bot_device_get_data(device); g_free(benchmark_data); }
static const BotDriver boilerplate = { .name = "Benchmark", .description = "Driver used to create basic system benchmarks", .version = "1.0", .allocate_device = allocate_device, .initialize_device = initialize_device, .shutdown_device = shutdown_device, .free_device = free_device, .poll_device = poll_device, .driver_properties = driver_properties };
/****************************************************************************** * Benchmark driver used to generate basic performance statistics. * (c) Edinburgh Robotics 2007 * * This driver also demonstrates many features of the API for driver authors. ******************************************************************************/ #include <devbot/driver/property.h> #include <devbot/driver/driver.h> #include <devbot/driver/device.h> #include <devbot/type.h> #include <devbot/bot.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <glib.h> /* Private data */ typedef struct { BOT_TYPE_UINT_TYPE *buffer; uint32_t data_length; BotProperty *data; } BenchmarkData; static const BotDeviceProto driver_properties[] = { { .name = "DataLength", .description = "The length of the \"Data\" property " "that will be created.", .type = BOT_TYPE_UINT_NAME, .flags = BOT_NO_DEFAULT, }, END_PROPERTY_PROTO }; static bool poll_device(BotDevice *device) { BenchmarkData *benchmark_data = bot_device_get_data(device); uint32_t i; /* Update the data vector */ bot_property_get_uint_all(benchmark_data->data, benchmark_data->buffer); for (i = 0; i < benchmark_data->data_length; i++) benchmark_data->buffer[i]++; bot_property_set_uint_all(benchmark_data->data, benchmark_data->buffer); return TRUE; } static bool allocate_device(BotDevice *device) { /* Allocate space for the private data */ bot_device_set_data(device, g_new0(BenchmarkData, 1)); return TRUE; } static bool initialize_device(BotDevice *device) { BenchmarkData *benchmark_data; uint32_t length; /* Validate the requested length of Data */ length = bot_property_get_uint( bot_device_lookup_property(device, "DataLength")); if (length < 1) { bot_warn("Invalid length (%d) for data", length); return FALSE; } /* Get the private data associated with this device */ benchmark_data = bot_device_get_data(device); /* Store our setup values for use later */ benchmark_data->data_length = length; /* Dynamically create the Data property */ const BotDeviceProto data_proto = { .name = "Data", .description = "Dynamically created data array", .type = BOT_TYPE_UINT_NAME, .length = length, }; benchmark_data->data = bot_device_add_property(device, &data_proto); /* Create a buffer that will be used to manipulate the data */ benchmark_data->buffer = g_new0(uint32_t, benchmark_data->data_length); return TRUE; } static void shutdown_device(BotDevice *device) { /* Free the data buffer associated with this device */ BenchmarkData *benchmark_data = bot_device_get_data(device); if (benchmark_data->buffer) g_free(benchmark_data->buffer); } static void free_device(BotDevice *device) { /* Get the private data associated with this device, and free it */ BenchmarkData *benchmark_data = bot_device_get_data(device); g_free(benchmark_data); } static const BotDriver boilerplate = { .name = "Benchmark", .description = "Driver used to create basic system benchmarks", .version = "1.0", .allocate_device = allocate_device, .initialize_device = initialize_device, .shutdown_device = shutdown_device, .free_device = free_device, .poll_device = poll_device, .driver_properties = driver_properties }; BOT_DRIVER_BOILERPLATE(boilerplate);
| Previous tutorial | Next tutorial |