ReferenceDevLayerThe device layer provides a uniform interface to hardware components under MOS. To build an application using a specified device, you should include "dev.h", as well as the header for the device you wish to use (ie, "mica2-gps.h", "msp-humidity.h", etc). These headers can be found in the src/mos/dev folder. The interface to each device is as follows: uint16_t dev_read(DEVICENAME, void* buffer, uint16_t count) Read count bytes from DEVICENAME into buffer. Returns the number of bytes read or a status code. uint16_t dev_write(DEVICENAME, const void* buffer, uint16_t count) Write count bytes to DEVICENAME from buffer. Returns the number of bytes written or a status code. uint8_t dev_ioctl(DEVICENAME, int8_t request, ...) Handles a device-specific request, which may have additional parameters. Returns a status code. dev_mode(DEVICENAME, uint8_t mode, ...) Change the current state of DEVICENAME to mode. This can be used to turn devices on or off, into low power mode, etc. Returns a status code. dev_open(DEVICENAME) Gain exclusive access to DEVICENAME. Any other thread attempting to open the device with dev_open will block until dev_close(DEVICENAME) is called. dev_close(DEVICENAME) Release exclusive access to DEVICENAME. Other threads may now access the device after calling dev_open. The following example program takes a temperature reading from the TELOSb temperature sensor:
#include "mos.h"
#include "dev.h"
#include "printf.h"
// this function converts the value of the temperature read
// from the sensor into the actual temperature in deg. F.
#define CALC_TEMP(value) (((value) / 100) + ((value) / 125) - 40)
void sense_thread(void)
{
// in this case no other threads are trying to
// access this driver, so dev_open/dev_close
// aren't necessary, but we can use them anyway.
dev_open(DEV_MSP_TEMPERATURE);
dev_mode(DEV_MSP_TEMPERATURE, DEV_MODE_ON);
uint16_t i;
uint16_t value;
for(i = 0; i < 10; ++i)
{
dev_read(DEV_MSP_TEMPERATURE, &value, sizeof(value));
value = CALC_TEMP(value);
printf("[%d] Current Temperature: %d F\n", i, value);
// sleep for one second
mos_thread_sleep(1000);
}
dev_mode(DEV_MSP_TEMPERATURE, DEV_MODE_OFF);
dev_close(DEV_MSP_TEMPERATURE);
}
void start(void)
{
mos_thread_new(sense_thread, 128, PRIORITY_NORMAL);
}
To create a device driver, you need to do is implement the functions above (excepting dev_open and dev_close), with the name of each function as dev_x_DEV_DEVICENAME and missing the DEVICENAME paramenter; ie, uint8_t dev_ioctl_DEV_MYDEVICE(int8_t request, ...) Tip: The ellipses (...) indicate variable arguments. For more information of va_args, check out CPrograming.com. The final step is to add your device name to the list found in dev.h, right before NUM_DEVICES: typedef enum { DEV_ADC = 0, DEV_AVR_EEPROM, ... DEV_MSP_FLASH, DEV_MICA2_GPS, DEV_MYDEVICE, NUM_DEVICES } dev_id_t; and also add the function declarations: extern mos_mutex_t mydevice_mutex; uint8_t dev_read_DEV_MYDEVICE(void *buf, uint16_t count); uint8_t dev_write_DEV_MYDEVICE(const void *buf, uint16_t count); uint8_t dev_mode_DEV_MYDEVICE(uint8_t md); uint8_t dev_ioctl_DEV_MYDEVICE(int8_t request, ...); #define dev_open_DEV_MYDEVICE(void) mos_mutex_lock(&mydevice_mutex) #define dev_close_DEV_MYDEVICE(void) mos_mutex_unlock(&mydevice_mutex) Tip: The above example shows the typical way to implement dev_open and dev_close using a mutex. It assumes that:
To accomplish the second, it's standard to write a mydevice_init() function and call it from sys/main.c in pre_start(). Created by: ledbettj last modification: Wednesday 01 of August, 2007 [19:58:57 UTC] by ledbettj |
Login Search Online users
4
online users
|