maximal_driver.c

This example is discussed in Writing a new device driver

00001 /******************************************************************************
00002  *
00003  * This is a demo of how to implement a driver-device plugin.
00004  * 
00005  * The idea is to use every single feature of the API.
00006  *
00007  * Yes, the debugging output is excessive.
00008  *
00009  *******************************************************************************/
00010 
00011 #include <stdlib.h>
00012 #include <devbot/core/driver.h>
00013 #include <devbot/distance.h>
00014 
00015 
00016 #define _DEBUG_TRACE(...) g_debug(__VA_ARGS__)
00017 
00018 
00019 /*******************************************************************************
00020  * Driver implementation
00021  *******************************************************************************/
00022 
00023 static gboolean initialize_driver(void)
00024 {
00025   _DEBUG_TRACE("initialize_driver");
00026   /* Perform initialization here e.g. registering with other drivers, initializing other libraries */
00027   return TRUE;
00028 }
00029 
00030 static gboolean free_driver(void)
00031 {
00032   _DEBUG_TRACE("free_driver");
00033   /* Perform any cleanups necessitated by initialization process */
00034   return TRUE;
00035 }
00036 
00037 struct _privateDeviceData
00038 {
00039   int call_count;
00040 };
00041 
00042 typedef struct _privateDeviceData privateDeviceData;
00043 
00044 static gboolean initialize_device_data (gpointer *data, 
00045                              BotDeviceConfiguration *configuration)
00046 {
00047   _DEBUG_TRACE("create_device_data");
00048 
00049   /* 1. Allocate space for our private data */
00050   privateDeviceData *my_data = g_new0(privateDeviceData, 1);
00051   if (my_data == NULL) goto creation_failed;
00052 
00053   /* 2. Use configuration to populate it */
00054   gchar *value;
00055   gchar *tmp;
00056 
00057   _DEBUG_TRACE(" -> Configuring device");
00058   
00059   if (configuration == NULL)
00060   {
00061     g_warning("debug devices require configuration");
00062     goto creation_failed;
00063   }
00064 
00065   /* 2a. A required configuration value */
00066   _DEBUG_TRACE(" -> Looking for Required_value");
00067   value = bot_configuration_get_value(configuration, "Required_value");
00068   if (value == NULL)
00069   {
00070     g_warning("debug devices must specify a value for the 'Required_value' option");
00071     goto creation_failed;
00072   }
00073 
00074   _DEBUG_TRACE(" -> Looking for Initial_call_count");
00075   /* 2b. An optional configuration value */
00076   value = bot_configuration_get_value(configuration, "Initial_call_count");
00077   if (value != NULL)
00078   {
00079     my_data->call_count = (int) strtol(value, &tmp, 0);
00080     _DEBUG_TRACE("call_count set to %d by configuration", my_data->call_count);
00081   }
00082 
00083   /* 3. Set the device data pointer to our newly constructed data */
00084   *data = my_data;
00085   _DEBUG_TRACE(" -> Initalization complete");
00086   return TRUE;
00087 
00088 creation_failed:
00089   _DEBUG_TRACE("Failed to create debug device (see above for reason)");
00090   g_free(my_data);
00091   return FALSE;
00092 
00093 }
00094 
00095 static gboolean free_device_data (gpointer data)
00096 {
00097     _DEBUG_TRACE("free_device_data");
00098     g_free(data);
00099 
00100     return 0;
00101 }
00102 
00103 static gpointer get_interface (BotDevice *device, BotInterface *type);
00104 
00105 BOT_DRIVER_BOILERPLATE("debug",
00106                        "A maximal driver, demonstrating all the features of the driver API",
00107                        "1.0",
00108                        &initialize_driver,
00109                        &free_driver,
00110                        &initialize_device_data,
00111                        &free_device_data,
00112                        &get_interface);
00113 
00114 /*******************************************************************************
00115  * Interface definitions
00116  *******************************************************************************/
00117 
00118 /* Forward declarations of supported interfaces */
00119 BotDistance _distanceInterface;
00120 
00121 /* Return an interface structure of the specified type or NULL if not available */
00122 static gpointer get_interface(BotDevice *device, BotInterface *type)
00123 {
00124   _DEBUG_TRACE("get_interface (%s)", type->name);
00125   if (BotDistanceInterface == type) return &_distanceInterface;
00126   return NULL;
00127 }
00128 
00129 /*******************************************************************************
00130  *
00131  * Rangefinder implementation
00132  *
00133  *******************************************************************************/
00134 
00135 static double get_metre(BotDevice *device)
00136 {
00137   _DEBUG_TRACE("get_distance");
00138   return ((privateDeviceData *) bot_device_get_data(device))->call_count++;
00139 }
00140 
00141 BotDistance _distanceInterface = 
00142 {
00143   .get_metre = &get_metre
00144 };
00145 
00146 

(c) 2006 Edinburgh Robotics Ltd.
Generated on Fri Feb 2 11:24:04 2007 for libbot by doxygen 1.5.1