From 6d14d429e60de0597c31d10f80caa9166b03f2f4 Mon Sep 17 00:00:00 2001 From: Hauke Petersen Date: Wed, 18 Nov 2015 16:07:44 +0100 Subject: [PATCH] sys: added SAUL registry --- sys/include/saul_reg.h | 144 ++++++++++++++++++++++++++++++++++++++++ sys/saul_reg/Makefile | 1 + sys/saul_reg/saul_reg.c | 133 +++++++++++++++++++++++++++++++++++++ 3 files changed, 278 insertions(+) create mode 100644 sys/include/saul_reg.h create mode 100644 sys/saul_reg/Makefile create mode 100644 sys/saul_reg/saul_reg.c diff --git a/sys/include/saul_reg.h b/sys/include/saul_reg.h new file mode 100644 index 0000000000..7a66c15630 --- /dev/null +++ b/sys/include/saul_reg.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @defgroup sys_saul_reg SAUL registry + * @ingroup sys + * @brief Global sensor/actuator registry for SAUL devices + * + * @{ + * + * @file + * @brief SAUL registry interface definition + * + * @author Hauke Petersen + */ + +#ifndef SAUL_REG_H +#define SAUL_REG_H + +#include + +#include "saul.h" +#include "phydat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief SAUL registry entry + */ +typedef struct saul_reg_t { + struct saul_reg_t *next; /**< pointer to the next device */ + void *dev; /**< pointer to the device descriptor */ + const char *name; /**< string identifier for the device */ + saul_driver_t const *driver; /**< the devices read callback */ +} saul_reg_t; + +/** + * @brief Additional data to collect for each entry + */ +typedef struct { + const char *name; /**< string identifier for a device */ +} saul_reg_info_t; + +/** + * @brief Register a device with the SAUL registry + * + * @note Make sure the registry entry the @p dev pointer is pointing to + * resides in some persistent memory location and not on some position + * on the stack where it will be overwritten... + * + * @param[in] dev pointer to a pre-populated registry entry + * + * @return 0 on success + * @return -ENODEV on invalid entry given + */ +int saul_reg_add(saul_reg_t *dev); + +/** + * @brief Unregister a device from the SAUL registry + * + * @param[in] dev pointer to a registry entry + * + * @return 0 on success + * @return -ENODEV if device was not found in the registry + */ +int saul_reg_rm(saul_reg_t *dev); + +/** + * @brief Get the first device from the list of registered devices + * + * @return pointer to the first device in the list + * @return NULL if list is empty + */ +saul_reg_t *saul_reg_get(void); + +/** + * @brief Find a device by it's position in the registry + * + * @param[in] pos position to look up + * + * @return pointer to the device at position specified by @p pos + * @return NULL if no device is registered at that position + */ +saul_reg_t *saul_reg_find_nth(int pos); + +/** + * @brief Find the first device of the given type in the registry + * + * @param[in] type device type to look for + * + * @return pointer to the first device matching the given type + * @return NULL if no device of that type could be found + */ +saul_reg_t *saul_reg_find_type(uint8_t type); + +/** + * @brief Find a device by its name + * + * @param[in] name the name to look for + * + * @return pointer to the first device matching the given name + * @return NULL if no device with that name could be found + */ +saul_reg_t *saul_reg_find_name(const char *name); + +/** + * @brief Read data from the given device + * + * @param[in] dev device to read from + * @param[out] res location to store the results in + * + * @return the number of data elements read to @p res [1-3] + * @return -ENODEV if given device is invalid + * @return -ENOTSUP if read operation is not supported by the device + * @return -ECANCELED on device errors + */ +int saul_reg_read(saul_reg_t *dev, phydat_t *res); + +/** + * @brief Write data to the given device + * + * @param[in] dev device to write to + * @param[in] data data to write to the device + * + * @return the number of data elements read to @p res [1-3] + * @return -ENODEV if given device is invalid + * @return -ENOTSUP if read operation is not supported by the device + * @return -ECANCELED on device errors + */ +int saul_reg_write(saul_reg_t *dev, phydat_t *data); + +#ifdef __cplusplus +} +#endif + +#endif /* SAUL_REG_H */ +/** @} */ diff --git a/sys/saul_reg/Makefile b/sys/saul_reg/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/sys/saul_reg/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/sys/saul_reg/saul_reg.c b/sys/saul_reg/saul_reg.c new file mode 100644 index 0000000000..7d8c0b5a63 --- /dev/null +++ b/sys/saul_reg/saul_reg.c @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015 Freie Universität Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_saul_reg + * @{ + * + * @file + * @brief SAUL registry implementation + * + * @author Hauke Petersen + * + * @} + */ + +#include +#include +#include + +#include "saul_reg.h" + +/** + * @brief Keep the head of the device list + */ +static saul_reg_t *reg = NULL; + + +int saul_reg_add(saul_reg_t *dev) +{ + saul_reg_t *tmp = reg; + + if (dev == NULL) { + return -ENODEV; + } + + /* prepare new entry */ + dev->next = NULL; + /* add to registry */ + if (reg == NULL) { + reg = dev; + } + else { + while (tmp->next != NULL) { + tmp = tmp->next; + } + tmp->next = dev; + } + return 0; +} + +int saul_reg_rm(saul_reg_t *dev) +{ + saul_reg_t *tmp = reg; + + if (reg == NULL || dev == NULL) { + return -EINVAL; + } + if (reg == dev) { + reg = dev->next; + } + while (tmp->next && (tmp->next != dev)) { + tmp = tmp->next; + } + if (tmp->next == dev) { + tmp->next = dev->next; + } + else { + return -ENODEV; + } + return 0; +} + +saul_reg_t *saul_reg_get(void) +{ + return reg; +} + +saul_reg_t *saul_reg_find_nth(int pos) +{ + saul_reg_t *tmp = reg; + + for (int i = 0; (i < pos) && tmp; i++) { + tmp = tmp->next; + } + return tmp; +} + +saul_reg_t *saul_reg_find_type(uint8_t type) +{ + saul_reg_t *tmp = reg; + + while (tmp) { + if (tmp->driver->type == type) { + return tmp; + } + tmp = tmp->next; + } + return NULL; +} + +saul_reg_t *saul_reg_find_name(const char *name) +{ + saul_reg_t *tmp = reg; + + while (tmp) { + if (strcmp(tmp->name, name) == 0) { + return tmp; + } + tmp = tmp->next; + } + return NULL; +} + +int saul_reg_read(saul_reg_t *dev, phydat_t *res) +{ + if (dev == NULL) { + return -ENODEV; + } + return dev->driver->read(dev->dev, res); +} + +int saul_reg_write(saul_reg_t *dev, phydat_t *data) +{ + if (dev == NULL) { + return -ENODEV; + } + return dev->driver->write(dev->dev, data); +}