1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/saul: use flash_utils

This commit is contained in:
Marian Buschsieweke 2022-06-01 22:59:07 +02:00
parent 29cfeb752e
commit cdcec5b3f9
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94
5 changed files with 242 additions and 75 deletions

View File

@ -48,8 +48,9 @@
#ifndef SAUL_H
#define SAUL_H
#include <stdint.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include "phydat.h"
@ -315,11 +316,42 @@ int saul_read_notsup(const void *dev, phydat_t *dat);
*
* @param[in] class_id device class ID
*
* @return string representation of the device class
* @return NULL if class ID is not known
* @return string representation of the device class
* @retval NULL class ID is not known
*
* @deprecated Use @ref saul_class_print or @ref saul_class_write instead
*
* @warning For classic Harvard architectures a small buffer is used to store
* the string, so that subsequent (or concurrent!) calls will
* overwrite the output.
*/
const char *saul_class_to_str(const uint8_t class_id);
/**
* @brief Prints the class string of the given class ID
*
* @param[in] class_id ID of the device class to print
*/
void saul_class_print(uint8_t class_id);
/**
* @brief Write the string representation of the given device class to the
* given buffer
*
* @param[out] dest destination buffer to write to
* @param[in] max_size size of the buffer at @p dest
* @param[in] class_id ID of the device class to write
*
* @return Number of bytes written
* @retval -EOVERFLOW buffer at @p dest is too small
* @retval -EINVAL invalid unit in @p unit
*
* @warning The function will never write a terminating zero byte
* @note If you pass `NULL` for @p dest, it will return the number of bytes
* it would write (regardless of @p max_size)
*/
ssize_t saul_class_write(char *dest, size_t max_size, uint8_t class_id);
#ifdef __cplusplus
}
#endif

View File

@ -23,77 +23,206 @@
#include <stddef.h>
#include <stdint.h>
#include "flash_utils.h"
#include "saul.h"
static const char *actuators[] = {
[SAUL_ACT_ID_ANY] = "ACT_ANY",
[SAUL_ACT_ID_LED_RGB] = "ACT_LED_RGB",
[SAUL_ACT_ID_SERVO] = "ACT_SERVO",
[SAUL_ACT_ID_MOTOR] = "ACT_MOTOR",
[SAUL_ACT_ID_SWITCH] = "ACT_SWITCH",
[SAUL_ACT_ID_DIMMER] = "ACT_DIMMER",
static FLASH_ATTR const char _act_id_any[] = "ACT_ANY";
static FLASH_ATTR const char _act_id_led_rgb[] = "ACT_LED_RGB";
static FLASH_ATTR const char _act_id_servo[] = "ACT_SERVO";
static FLASH_ATTR const char _act_id_motor[] = "ACT_MOTOR";
static FLASH_ATTR const char _act_id_switch[] = "ACT_SWITCH";
static FLASH_ATTR const char _act_id_dimmer[] = "ACT_DIMMER";
static FLASH_ATTR const char * FLASH_ATTR const actuators[] = {
[SAUL_ACT_ID_ANY] = _act_id_any,
[SAUL_ACT_ID_LED_RGB] = _act_id_led_rgb,
[SAUL_ACT_ID_SERVO] = _act_id_servo,
[SAUL_ACT_ID_MOTOR] = _act_id_motor,
[SAUL_ACT_ID_SWITCH] = _act_id_switch,
[SAUL_ACT_ID_DIMMER] = _act_id_dimmer,
};
static const char *sensors[] = {
[SAUL_SENSE_ID_ANY] = "SENSE_ANY",
[SAUL_SENSE_ID_BTN] = "SENSE_BTN",
[SAUL_SENSE_ID_TEMP] = "SENSE_TEMP",
[SAUL_SENSE_ID_HUM] = "SENSE_HUM",
[SAUL_SENSE_ID_LIGHT] = "SENSE_LIGHT",
[SAUL_SENSE_ID_ACCEL] = "SENSE_ACCEL",
[SAUL_SENSE_ID_MAG] = "SENSE_MAG",
[SAUL_SENSE_ID_GYRO] = "SENSE_GYRO",
[SAUL_SENSE_ID_COLOR] = "SENSE_COLOR",
[SAUL_SENSE_ID_PRESS] = "SENSE_PRESS",
[SAUL_SENSE_ID_ANALOG] = "SENSE_ANALOG",
[SAUL_SENSE_ID_UV] = "SENSE_UV",
[SAUL_SENSE_ID_OBJTEMP] = "SENSE_OBJTEMP",
[SAUL_SENSE_ID_COUNT] = "SENSE_PULSE_COUNT",
[SAUL_SENSE_ID_DISTANCE] = "SENSE_DISTANCE",
[SAUL_SENSE_ID_CO2] = "SENSE_CO2",
[SAUL_SENSE_ID_TVOC] = "SENSE_TVOC",
[SAUL_SENSE_ID_GAS] = "SENSE_GAS",
[SAUL_SENSE_ID_PROXIMITY] = "SENSE_PROXIMITY",
[SAUL_SENSE_ID_RSSI] = "SENSE_RSSI",
[SAUL_SENSE_ID_CHARGE] = "SENSE_CHARGE",
[SAUL_SENSE_ID_CURRENT] = "SENSE_CURRENT",
[SAUL_SENSE_ID_OCCUP] = "SENSE_OCCUP",
[SAUL_SENSE_ID_PM] = "SENSE_PM",
[SAUL_SENSE_ID_CAPACITANCE] = "SENSE_CAPACITANCE",
[SAUL_SENSE_ID_VOLTAGE] = "SENSE_VOLTAGE",
[SAUL_SENSE_ID_PH] = "SENSE_PH",
[SAUL_SENSE_ID_POWER] = "SENSE_POWER",
[SAUL_SENSE_ID_SIZE] = "SENSE_SIZE",
static FLASH_ATTR const char _sense_any[] = "SENSE_ANY";
static FLASH_ATTR const char _sense_btn[] = "SENSE_BTN";
static FLASH_ATTR const char _sense_temp[] = "SENSE_TEMP";
static FLASH_ATTR const char _sense_hum[] = "SENSE_HUM";
static FLASH_ATTR const char _sense_light[] = "SENSE_LIGHT";
static FLASH_ATTR const char _sense_accel[] = "SENSE_ACCEL";
static FLASH_ATTR const char _sense_mag[] = "SENSE_MAG";
static FLASH_ATTR const char _sense_gyro[] = "SENSE_GYRO";
static FLASH_ATTR const char _sense_color[] = "SENSE_COLOR";
static FLASH_ATTR const char _sense_press[] = "SENSE_PRESS";
static FLASH_ATTR const char _sense_analog[] = "SENSE_ANALOG";
static FLASH_ATTR const char _sense_uv[] = "SENSE_UV";
static FLASH_ATTR const char _sense_objtemp[] = "SENSE_OBJTEMP";
static FLASH_ATTR const char _sense_pulse_count[] = "SENSE_PULSE_COUNT";
static FLASH_ATTR const char _sense_distance[] = "SENSE_DISTANCE";
static FLASH_ATTR const char _sense_co2[] = "SENSE_CO2";
static FLASH_ATTR const char _sense_tvoc[] = "SENSE_TVOC";
static FLASH_ATTR const char _sense_gas[] = "SENSE_GAS";
static FLASH_ATTR const char _sense_proximity[] = "SENSE_PROXIMITY";
static FLASH_ATTR const char _sense_rssi[] = "SENSE_RSSI";
static FLASH_ATTR const char _sense_charge[] = "SENSE_CHARGE";
static FLASH_ATTR const char _sense_current[] = "SENSE_CURRENT";
static FLASH_ATTR const char _sense_occup[] = "SENSE_OCCUP";
static FLASH_ATTR const char _sense_pm[] = "SENSE_PM";
static FLASH_ATTR const char _sense_capacitance[] = "SENSE_CAPACITANCE";
static FLASH_ATTR const char _sense_voltage[] = "SENSE_VOLTAGE";
static FLASH_ATTR const char _sense_ph[] = "SENSE_PH";
static FLASH_ATTR const char _sense_power[] = "SENSE_POWER";
static FLASH_ATTR const char _sense_size[] = "SENSE_SIZE";
static FLASH_ATTR const char * FLASH_ATTR const sensors[] = {
[SAUL_SENSE_ID_ANY] = _sense_any,
[SAUL_SENSE_ID_BTN] = _sense_btn,
[SAUL_SENSE_ID_TEMP] = _sense_temp,
[SAUL_SENSE_ID_HUM] = _sense_hum,
[SAUL_SENSE_ID_LIGHT] = _sense_light,
[SAUL_SENSE_ID_ACCEL] = _sense_accel,
[SAUL_SENSE_ID_MAG] = _sense_mag,
[SAUL_SENSE_ID_GYRO] = _sense_gyro,
[SAUL_SENSE_ID_COLOR] = _sense_color,
[SAUL_SENSE_ID_PRESS] = _sense_press,
[SAUL_SENSE_ID_ANALOG] = _sense_analog,
[SAUL_SENSE_ID_UV] = _sense_uv,
[SAUL_SENSE_ID_OBJTEMP] = _sense_objtemp,
[SAUL_SENSE_ID_COUNT] = _sense_pulse_count,
[SAUL_SENSE_ID_DISTANCE] = _sense_distance,
[SAUL_SENSE_ID_CO2] = _sense_co2,
[SAUL_SENSE_ID_TVOC] = _sense_tvoc,
[SAUL_SENSE_ID_GAS] = _sense_gas,
[SAUL_SENSE_ID_PROXIMITY] = _sense_proximity,
[SAUL_SENSE_ID_RSSI] = _sense_rssi,
[SAUL_SENSE_ID_CHARGE] = _sense_charge,
[SAUL_SENSE_ID_CURRENT] = _sense_current,
[SAUL_SENSE_ID_OCCUP] = _sense_occup,
[SAUL_SENSE_ID_PM] = _sense_pm,
[SAUL_SENSE_ID_CAPACITANCE] = _sense_capacitance,
[SAUL_SENSE_ID_VOLTAGE] = _sense_voltage,
[SAUL_SENSE_ID_PH] = _sense_ph,
[SAUL_SENSE_ID_POWER] = _sense_power,
[SAUL_SENSE_ID_SIZE] = _sense_size,
};
static FLASH_ATTR const char _class_undef[] = "CLASS_UNDEF";
static FLASH_ATTR const char _class_any[] = "CLASS_ANY";
static FLASH_ATTR const char _class_unknown[] = "CLASS_UNKNOWN";
const char *saul_class_to_str(const uint8_t class_id)
{
#if IS_ACTIVE(HAS_FLASH_UTILS_ARCH)
/* Yeah, this is as bad as it looks... The function is deprecated for this
* reason and it will only affect AVR users, for whom this is a good
* trade-off. */
static char buf[32]; /* yes, whopping 32 byte ... */
ssize_t len = saul_class_write(buf, sizeof(buf) - 1, class_id);
if (len < 0) {
flash_memcpy(buf, _class_unknown, sizeof(_class_unknown));
len = sizeof(_class_unknown);
}
buf[len] = '\0';
return buf;
#else
const char *result = NULL;
uint8_t id = class_id & SAUL_ID_MASK;
uint8_t cat = class_id & SAUL_CAT_MASK;
switch (cat) {
case SAUL_CAT_UNDEF:
return "CLASS_UNDEF";
case SAUL_CAT_ACT:
if (id < SAUL_ACT_NUMOF) {
result = actuators[id];
}
break;
case SAUL_CAT_SENSE:
if (id < SAUL_SENSE_NUMOF) {
result = sensors[id];
}
break;
default:
if (class_id == SAUL_CLASS_ANY) {
return "CLASS_ANY";
}
break;
case SAUL_CAT_UNDEF:
return _class_undef;
case SAUL_CAT_ACT:
if (id < SAUL_ACT_NUMOF) {
result = actuators[id];
}
break;
case SAUL_CAT_SENSE:
if (id < SAUL_SENSE_NUMOF) {
result = sensors[id];
}
break;
default:
if (class_id == SAUL_CLASS_ANY) {
return _class_any;
}
break;
}
if (result == NULL) {
result = "CLASS_UNKNOWN";
result = _class_unknown;
}
return result;
#endif
}
void saul_class_print(uint8_t class_id)
{
uint8_t id = class_id & SAUL_ID_MASK;
uint8_t cat = class_id & SAUL_CAT_MASK;
FLASH_ATTR const char *str = NULL;
switch (cat) {
case SAUL_CAT_UNDEF:
str = _class_undef;
break;
case SAUL_CAT_ACT:
if (id < SAUL_ACT_NUMOF) {
str = actuators[id];
}
break;
case SAUL_CAT_SENSE:
if (id < SAUL_SENSE_NUMOF) {
str = sensors[id];
}
break;
default:
if (class_id == SAUL_CLASS_ANY) {
str = _class_any;
}
break;
}
if (str) {
flash_print_str(str);
}
}
ssize_t saul_class_write(char *dest, size_t max_size, uint8_t class_id)
{
uint8_t id = class_id & SAUL_ID_MASK;
uint8_t cat = class_id & SAUL_CAT_MASK;
FLASH_ATTR const char *str = NULL;
switch (cat) {
case SAUL_CAT_UNDEF:
str = _class_undef;
break;
case SAUL_CAT_ACT:
if (id < SAUL_ACT_NUMOF) {
str = actuators[id];
}
break;
case SAUL_CAT_SENSE:
if (id < SAUL_SENSE_NUMOF) {
str = sensors[id];
}
break;
default:
if (class_id == SAUL_CLASS_ANY) {
str = _class_any;
}
break;
}
if (!str) {
return -EINVAL;
}
size_t len = flash_strlen(str);
if (dest) {
if (len > max_size) {
return -EOVERFLOW;
}
flash_memcpy(dest, str, len);
}
return len;
}

View File

@ -24,6 +24,7 @@
#include <string.h>
#include <stdlib.h>
#include "flash_utils.h"
#include "saul_reg.h"
#include "shell.h"
@ -47,8 +48,9 @@ static void probe(int num, saul_reg_t *dev)
return;
}
/* print results */
printf("Reading from #%i (%s|%s)\n", num, _devname(dev),
saul_class_to_str(dev->driver->type));
printf("Reading from #%i (%s|", num, _devname(dev));
saul_class_print(dev->driver->type);
printf(")\n");
phydat_dump(&res, dim);
}
@ -70,14 +72,15 @@ static void list(void)
int i = 0;
if (dev) {
puts("ID\tClass\t\tName");
printf("ID\tClass\t\tName\n");
}
else {
puts("No devices found");
printf("No devices found\n");
}
while (dev) {
printf("#%i\t%s\t%s\n",
i++, saul_class_to_str(dev->driver->type), _devname(dev));
printf("#%i\t", i++);
saul_class_print(dev->driver->type);
printf("\t%s\n", _devname(dev));
dev = dev->next;
}
}
@ -88,10 +91,11 @@ static void read(int argc, char **argv)
saul_reg_t *dev;
if (argc < 3) {
printf("usage: %s %s <device id>|all\n", argv[0], argv[1]);
printf("usage: %s %s <device id>|all\n",
argv[0], argv[1]);
return;
}
if (strcmp(argv[2], "all") == 0) {
if (flash_strcmp(argv[2], TO_FLASH("all")) == 0) {
probe_all();
return;
}
@ -99,7 +103,7 @@ static void read(int argc, char **argv)
num = atoi(argv[2]);
dev = saul_reg_find_nth(num);
if (dev == NULL) {
puts("error: undefined device id given");
printf("error: undefined device id given\n");
return;
}
probe(num, dev);
@ -113,13 +117,13 @@ static void write(int argc, char **argv)
if (argc < 4) {
printf("usage: %s %s <device id> <value 0> [<value 1> [<value 2]]\n",
argv[0], argv[1]);
argv[0], argv[1]);
return;
}
num = atoi(argv[2]);
dev = saul_reg_find_nth(num);
if (dev == NULL) {
puts("error: undefined device given");
printf("error: undefined device given\n");
return;
}
/* parse value(s) */
@ -151,10 +155,10 @@ static int _saul(int argc, char **argv)
list();
}
else {
if (strcmp(argv[1], "read") == 0) {
if (flash_strcmp(argv[1], TO_FLASH("read")) == 0) {
read(argc, argv);
}
else if (strcmp(argv[1], "write") == 0) {
else if (flash_strcmp(argv[1], TO_FLASH("write")) == 0) {
write(argc, argv);
}
else {

View File

@ -18,9 +18,10 @@
#include <stdio.h>
#include "xtimer.h"
#include "flash_utils.h"
#include "phydat.h"
#include "saul_reg.h"
#include "xtimer.h"
/**
* @brief Read the sensors every second
@ -44,7 +45,7 @@ int main(void)
while (dev) {
int dim = saul_reg_read(dev, &res);
printf("\nDev: %s\tType: %s\n", dev->name,
printf("\nDev: %s\tType: %" PRIsflash "\n", dev->name,
saul_class_to_str(dev->driver->type));
phydat_dump(&res, dim);
dev = dev->next;

View File

@ -19,9 +19,10 @@
#include <stdio.h>
#include "xtimer.h"
#include "flash_utils.h"
#include "phydat.h"
#include "saul_reg.h"
#include "xtimer.h"
/**
* @brief Read th sensors every second
@ -45,7 +46,7 @@ int main(void)
while (dev) {
int dim = saul_reg_read(dev, &res);
printf("\nDev: %s\tType: %s\n", dev->name,
printf("\nDev: %s\tType: %" PRIsflash "\n", dev->name,
saul_class_to_str(dev->driver->type));
phydat_dump(&res, dim);
dev = dev->next;