mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/phydat: use flash_utils
This commit is contained in:
parent
2825f5f2ae
commit
29cfeb752e
@ -37,6 +37,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "modules.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -177,30 +179,55 @@ void phydat_dump(phydat_t *data, uint8_t dim);
|
||||
/**
|
||||
* @brief Convert the given unit to a string
|
||||
*
|
||||
* @param[in] unit unit to convert
|
||||
* @param[in] unit unit to convert
|
||||
*
|
||||
* @return string representation of given unit (e.g. V or m)
|
||||
* @return NULL if unit was not recognized
|
||||
*
|
||||
* @deprecated Use @ref phydat_unit_print or @ref phydat_unit_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 *phydat_unit_to_str(uint8_t unit);
|
||||
|
||||
/**
|
||||
* @brief Return a string representation for every unit, including
|
||||
* non-physical units like 'none' or 'time'
|
||||
* @brief Same as @ref phydat_unit_to_str
|
||||
*
|
||||
* This function is useful when converting phydat_t structures to non-binary
|
||||
* representations like JSON or XML.
|
||||
* In practise all users used the verbose function anyway. Hence,
|
||||
* @ref phydat_unit_to_str just covers all units and this is just a backward
|
||||
* compatibility wrapper.
|
||||
*
|
||||
* In practice, this function extends phydat_unit_to_str() with additional
|
||||
* identifiers for non physical units.
|
||||
*
|
||||
* @param[in] unit unit to convert
|
||||
*
|
||||
* @return string representation of given unit
|
||||
* @return empty string ("") if unit was not recognized
|
||||
* @deprecated Use @ref phydat_unit_print or @ref phydat_unit_write instead
|
||||
*/
|
||||
const char *phydat_unit_to_str_verbose(uint8_t unit);
|
||||
|
||||
/**
|
||||
* @brief Print a unit
|
||||
*
|
||||
* @param[in] unit unit to print
|
||||
*/
|
||||
void phydat_unit_print(uint8_t unit);
|
||||
|
||||
/**
|
||||
* @brief Write the string representation of the given unit into the given
|
||||
* buffer
|
||||
*
|
||||
* @param[out] dest destination buffer to write to
|
||||
* @param[in] max_size size of the buffer at @p dest
|
||||
* @param[in] unit unit to convert
|
||||
*
|
||||
* @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 phydat_unit_write(char *dest, size_t max_size, uint8_t unit);
|
||||
|
||||
/**
|
||||
* @brief Convert the given scale factor to an SI prefix
|
||||
*
|
||||
|
@ -20,8 +20,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "fmt.h"
|
||||
#include "assert.h"
|
||||
#include "flash_utils.h"
|
||||
#include "fmt.h"
|
||||
#include "phydat.h"
|
||||
|
||||
#define STATIC_LEN (14U)
|
||||
@ -32,11 +33,11 @@
|
||||
static size_t _bool_to_str(int16_t val, char *buf)
|
||||
{
|
||||
if (val) {
|
||||
memcpy(buf, "true", 4);
|
||||
flash_memcpy(buf, TO_FLASH("true"), 4);
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
memcpy(buf, "false", 5);
|
||||
flash_memcpy(buf, TO_FLASH("false"), 5);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
@ -60,10 +61,10 @@ size_t phydat_to_json(const phydat_t *data, size_t dim, char *buf)
|
||||
pos += (data->val[i]) ? 4 : 5; /* true: 4, false: 5 */
|
||||
}
|
||||
}
|
||||
pos += strlen(phydat_unit_to_str_verbose(data->unit));
|
||||
pos += phydat_unit_write(NULL, 0, data->unit);
|
||||
}
|
||||
else {
|
||||
memcpy(buf, "{\"d\":", 5);
|
||||
flash_memcpy(buf, TO_FLASH("{\"d\":"), 5);
|
||||
pos += 5;
|
||||
/* write data */
|
||||
if (dim > 1) {
|
||||
@ -84,13 +85,11 @@ size_t phydat_to_json(const phydat_t *data, size_t dim, char *buf)
|
||||
buf[pos++] = ',';
|
||||
}
|
||||
/* add unit */
|
||||
memcpy(&buf[pos], "\"u\":\"", 5);
|
||||
flash_memcpy(&buf[pos], TO_FLASH("\"u\":\""), 5);
|
||||
pos += 5;
|
||||
const char *u = phydat_unit_to_str_verbose(data->unit);
|
||||
strcpy(&buf[pos], u);
|
||||
pos += strlen(u);
|
||||
pos += phydat_unit_write(&buf[pos], SIZE_MAX, data->unit);
|
||||
/* terminate the JSON string */
|
||||
memcpy(&buf[pos], "\"}", 2);
|
||||
flash_memcpy(&buf[pos], TO_FLASH("\"}"), 2);
|
||||
pos += 2;
|
||||
buf[pos++] = '\0';
|
||||
}
|
||||
|
@ -18,17 +18,19 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "flash_utils.h"
|
||||
#include "fmt.h"
|
||||
#include "phydat.h"
|
||||
|
||||
void phydat_dump(phydat_t *data, uint8_t dim)
|
||||
{
|
||||
if (data == NULL || dim > PHYDAT_DIM) {
|
||||
puts("Unable to display data object");
|
||||
printf("Unable to display data object\n");
|
||||
return;
|
||||
}
|
||||
printf("Data:");
|
||||
@ -50,19 +52,19 @@ void phydat_dump(phydat_t *data, uint8_t dim)
|
||||
char scale_prefix;
|
||||
|
||||
switch (data->unit) {
|
||||
case UNIT_UNDEF:
|
||||
case UNIT_NONE:
|
||||
case UNIT_M2:
|
||||
case UNIT_M3:
|
||||
case UNIT_PERCENT:
|
||||
case UNIT_TEMP_C:
|
||||
case UNIT_TEMP_F:
|
||||
case UNIT_DBM:
|
||||
/* no string conversion */
|
||||
scale_prefix = '\0';
|
||||
break;
|
||||
default:
|
||||
scale_prefix = phydat_prefix_from_scale(data->scale);
|
||||
case UNIT_UNDEF:
|
||||
case UNIT_NONE:
|
||||
case UNIT_M2:
|
||||
case UNIT_M3:
|
||||
case UNIT_PERCENT:
|
||||
case UNIT_TEMP_C:
|
||||
case UNIT_TEMP_F:
|
||||
case UNIT_DBM:
|
||||
/* no string conversion */
|
||||
scale_prefix = '\0';
|
||||
break;
|
||||
default:
|
||||
scale_prefix = phydat_prefix_from_scale(data->scale);
|
||||
}
|
||||
|
||||
printf("\t");
|
||||
@ -92,75 +94,158 @@ void phydat_dump(phydat_t *data, uint8_t dim)
|
||||
printf("%11s ", num);
|
||||
}
|
||||
|
||||
printf("%s\n", phydat_unit_to_str(data->unit));
|
||||
if ((data->unit != UNIT_NONE) && (data->unit != UNIT_UNDEF)
|
||||
&& (data->unit != UNIT_BOOL)) {
|
||||
phydat_unit_print(data->unit);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
static FLASH_ATTR const char _unit_celsius[] = "°C";
|
||||
static FLASH_ATTR const char _unit_fahrenheit[] = "°F";
|
||||
static FLASH_ATTR const char _unit_kelvin[] = "K";
|
||||
static FLASH_ATTR const char _unit_lux[] = "lx";
|
||||
static FLASH_ATTR const char _unit_metre[] = "m";
|
||||
static FLASH_ATTR const char _unit_square_metre[] = "m^2";
|
||||
static FLASH_ATTR const char _unit_cubic_metre[] = "m^3";
|
||||
static FLASH_ATTR const char _unit_g_force[] = "gₙ";
|
||||
static FLASH_ATTR const char _unit_degree_per_second[] = "dps";
|
||||
static FLASH_ATTR const char _unit_gram[] = "g";
|
||||
static FLASH_ATTR const char _unit_ampere[] = "A";
|
||||
static FLASH_ATTR const char _unit_volt[] = "V";
|
||||
static FLASH_ATTR const char _unit_watt[] = "W";
|
||||
static FLASH_ATTR const char _unit_decibel_milliwatts[] = "dBm";
|
||||
static FLASH_ATTR const char _unit_gauss[] = "Gs";
|
||||
static FLASH_ATTR const char _unit_tesla[] = "T";
|
||||
static FLASH_ATTR const char _unit_bar[] = "Bar";
|
||||
static FLASH_ATTR const char _unit_pascal[] = "Pa";
|
||||
static FLASH_ATTR const char _unit_permille[] = "permille";
|
||||
static FLASH_ATTR const char _unit_parts_per_million[] = "ppm";
|
||||
static FLASH_ATTR const char _unit_parts_per_billion[] = "ppb";
|
||||
static FLASH_ATTR const char _unit_candela[] = "cd";
|
||||
static FLASH_ATTR const char _unit_percent[] = "%";
|
||||
static FLASH_ATTR const char _unit_counts[] = "cts";
|
||||
static FLASH_ATTR const char _unit_coulomb[] = "C";
|
||||
static FLASH_ATTR const char _unit_gram_per_cubic_metre[] = "g/m^3";
|
||||
static FLASH_ATTR const char _unit_farad[] = "F";
|
||||
static FLASH_ATTR const char _unit_potential_of_hydrogen[] = "pH";
|
||||
static FLASH_ATTR const char _unit_count_per_cubic_metre[] = "#/m^3";
|
||||
static FLASH_ATTR const char _unit_ohm[] = "ohm";
|
||||
static FLASH_ATTR const char _unit_undefined[] = "undefined";
|
||||
static FLASH_ATTR const char _unit_none[] = "none";
|
||||
static FLASH_ATTR const char _unit_time[] = "time";
|
||||
static FLASH_ATTR const char _unit_date[] = "date";
|
||||
|
||||
static FLASH_ATTR const char * FLASH_ATTR const _unit_to_str[] = {
|
||||
[UNIT_TEMP_C] = _unit_celsius,
|
||||
[UNIT_TEMP_F] = _unit_fahrenheit,
|
||||
[UNIT_TEMP_K] = _unit_kelvin,
|
||||
[UNIT_LUX] = _unit_lux,
|
||||
[UNIT_M] = _unit_metre,
|
||||
[UNIT_M2] = _unit_square_metre,
|
||||
[UNIT_M3] = _unit_cubic_metre,
|
||||
[UNIT_G_FORCE] = _unit_g_force,
|
||||
[UNIT_DPS] = _unit_degree_per_second,
|
||||
[UNIT_GRAM] = _unit_gram,
|
||||
[UNIT_A] = _unit_ampere,
|
||||
[UNIT_V] = _unit_volt,
|
||||
[UNIT_W] = _unit_watt,
|
||||
[UNIT_DBM] = _unit_decibel_milliwatts,
|
||||
[UNIT_GS] = _unit_gauss,
|
||||
[UNIT_T] = _unit_tesla,
|
||||
[UNIT_BAR] = _unit_bar,
|
||||
[UNIT_PA] = _unit_pascal,
|
||||
[UNIT_PERMILL] = _unit_permille,
|
||||
[UNIT_PPM] = _unit_parts_per_million,
|
||||
[UNIT_PPB] = _unit_parts_per_billion,
|
||||
[UNIT_CD] = _unit_candela,
|
||||
[UNIT_PERCENT] = _unit_percent,
|
||||
[UNIT_CTS] = _unit_counts,
|
||||
[UNIT_COULOMB] = _unit_coulomb,
|
||||
[UNIT_GPM3] = _unit_gram_per_cubic_metre,
|
||||
[UNIT_F] = _unit_farad,
|
||||
[UNIT_PH] = _unit_potential_of_hydrogen,
|
||||
[UNIT_CPM3] = _unit_count_per_cubic_metre,
|
||||
[UNIT_OHM] = _unit_ohm,
|
||||
[UNIT_UNDEF] = _unit_undefined,
|
||||
[UNIT_NONE] = _unit_none,
|
||||
[UNIT_BOOL] = _unit_none,
|
||||
[UNIT_TIME] = _unit_time,
|
||||
[UNIT_DATE] = _unit_date,
|
||||
};
|
||||
|
||||
ssize_t phydat_unit_write(char *dest, size_t max_size, uint8_t unit)
|
||||
{
|
||||
if ((unit >= ARRAY_SIZE(_unit_to_str)) || (_unit_to_str[unit]) == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
size_t len = flash_strlen(_unit_to_str[unit]);
|
||||
if (dest) {
|
||||
if (max_size < len) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
flash_memcpy(dest, _unit_to_str[unit], len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *phydat_unit_to_str(uint8_t unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case UNIT_TEMP_C: return "°C";
|
||||
case UNIT_TEMP_F: return "°F";
|
||||
case UNIT_TEMP_K: return "K";
|
||||
case UNIT_LUX: return "lx";
|
||||
case UNIT_M: return "m";
|
||||
case UNIT_M2: return "m^2";
|
||||
case UNIT_M3: return "m^3";
|
||||
case UNIT_G_FORCE: return "gₙ";
|
||||
case UNIT_DPS: return "dps";
|
||||
case UNIT_GRAM: return "g";
|
||||
case UNIT_A: return "A";
|
||||
case UNIT_V: return "V";
|
||||
case UNIT_W: return "W";
|
||||
case UNIT_DBM: return "dBm";
|
||||
case UNIT_GAUSS: return "Gs";
|
||||
case UNIT_T: return "T";
|
||||
case UNIT_BAR: return "Bar";
|
||||
case UNIT_PA: return "Pa";
|
||||
case UNIT_PERMILL: return "permille";
|
||||
case UNIT_PPM: return "ppm";
|
||||
case UNIT_PPB: return "ppb";
|
||||
case UNIT_CD: return "cd";
|
||||
case UNIT_PERCENT: return "%";
|
||||
case UNIT_CTS: return "cts";
|
||||
case UNIT_COULOMB: return "C";
|
||||
case UNIT_GPM3: return "g/m^3";
|
||||
case UNIT_F: return "F";
|
||||
case UNIT_PH: return "pH";
|
||||
case UNIT_CPM3: return "#/m^3";
|
||||
case UNIT_OHM: return "ohm";
|
||||
|
||||
default: return "";
|
||||
#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[8];
|
||||
ssize_t pos = phydat_unit_write(buf, sizeof(buf) - 1, unit);
|
||||
assert(pos >= 0);
|
||||
if (pos < 0) {
|
||||
pos = 0;
|
||||
}
|
||||
buf[pos] = '\0';
|
||||
return buf;
|
||||
#else
|
||||
if ((unit < ARRAY_SIZE(_unit_to_str)) && (_unit_to_str[unit])) {
|
||||
return _unit_to_str[unit];
|
||||
}
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *phydat_unit_to_str_verbose(uint8_t unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case UNIT_UNDEF: return "undefined";
|
||||
case UNIT_NONE: /* fall through */
|
||||
case UNIT_BOOL:
|
||||
return "none";
|
||||
case UNIT_TIME: return "time";
|
||||
case UNIT_DATE: return "date";
|
||||
default: return phydat_unit_to_str(unit);
|
||||
return phydat_unit_to_str(unit);
|
||||
}
|
||||
|
||||
void phydat_unit_print(uint8_t unit)
|
||||
{
|
||||
if ((unit < ARRAY_SIZE(_unit_to_str)) && (_unit_to_str[unit]) != NULL) {
|
||||
flash_print_str(_unit_to_str[unit]);
|
||||
}
|
||||
}
|
||||
|
||||
char phydat_prefix_from_scale(int8_t scale)
|
||||
{
|
||||
switch (scale) {
|
||||
case -3: return 'm';
|
||||
case -6: return 'u';
|
||||
case -9: return 'n';
|
||||
case -12: return 'p';
|
||||
case -15: return 'f';
|
||||
case 2: return 'h';
|
||||
case 3: return 'k';
|
||||
case 6: return 'M';
|
||||
case 9: return 'G';
|
||||
case 12: return 'T';
|
||||
case 15: return 'P';
|
||||
default: return '\0';
|
||||
static FLASH_ATTR const char _prefix[] = {
|
||||
'f', '\0', '\0',
|
||||
'p', '\0', '\0',
|
||||
'n', '\0', '\0',
|
||||
'u', '\0', '\0',
|
||||
'm', '\0', '\0',
|
||||
'\0', '\0', 'h',
|
||||
'k', '\0', '\0',
|
||||
'M', '\0', '\0',
|
||||
'G', '\0', '\0',
|
||||
'T', '\0', '\0',
|
||||
'P',
|
||||
};
|
||||
|
||||
int8_t idx = scale + ARRAY_SIZE(_prefix) / 2;
|
||||
|
||||
if ((idx < 0) || (idx >= (int8_t)ARRAY_SIZE(_prefix))) {
|
||||
return '\0';
|
||||
}
|
||||
|
||||
return _prefix[idx];
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "embUnit.h"
|
||||
#include "flash_utils.h"
|
||||
#include "senml/phydat.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
@ -114,7 +115,7 @@ void test_phydat_to_senml_float(void)
|
||||
|
||||
phydat_to_senml_float(&res, &(value_tests[i].phydat), value_tests[i].dim);
|
||||
|
||||
DEBUG("Float: %" PRIi16 "e%" PRIi16 " %s -> %.f %s\n",
|
||||
DEBUG("Float: %" PRIi16 "e%" PRIi16 " %" PRIsflash " -> %.f %s\n",
|
||||
value_tests[i].phydat.val[value_tests[i].dim], value_tests[i].phydat.scale,
|
||||
phydat_unit_to_str(value_tests[i].phydat.unit),
|
||||
res.value.value.f,
|
||||
@ -137,7 +138,7 @@ void test_phydat_to_senml_decimal(void)
|
||||
|
||||
phydat_to_senml_decimal(&res, &(value_tests[i].phydat), value_tests[i].dim);
|
||||
|
||||
DEBUG("Decimal: %" PRIi16 "e%" PRIi16 " %s -> %" PRIi32 "e%" PRIi32 " %s\n",
|
||||
DEBUG("Decimal: %" PRIi16 "e%" PRIi16 " %s -> %" PRIi32 "e%" PRIi32 " %" PRIsflash"\n",
|
||||
value_tests[i].phydat.val[value_tests[i].dim], value_tests[i].phydat.scale,
|
||||
phydat_unit_to_str(value_tests[i].phydat.unit),
|
||||
res.value.value.df.m, res.value.value.df.e,
|
||||
|
Loading…
Reference in New Issue
Block a user