From 87906333e9aaa089ba94aa38cf26b066be88a141 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Wed, 5 Jul 2023 13:33:28 -0600 Subject: [PATCH] Implement pipe --- drivers/sensor/default_rtio_sensor.c | 5 +- include/zephyr/sensing/sensing.h | 10 +- include/zephyr/sensing/sensor.h | 19 +- samples/sensor/sensor_shell/prj.conf | 1 + subsys/sensing/CMakeLists.txt | 1 + subsys/sensing/Kconfig | 23 ++ .../include/sensing/internal/sensing.h | 3 + subsys/sensing/src/processing.c | 78 +++++++ subsys/sensing/src/sensor_connections.c | 24 ++- subsys/sensing/src/sensor_pipe.c | 38 +++- subsys/sensing/src/shell.c | 199 ++++++++++++++++-- subsys/sensing/src/userspace.c | 13 +- 12 files changed, 377 insertions(+), 37 deletions(-) create mode 100644 subsys/sensing/src/processing.c diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index a86bd81ec1d48f..bc95c1d777aa6a 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -316,9 +316,8 @@ static int decode(const uint8_t *buffer, sensor_frame_iterator_t *fit, { const struct sensor_data_generic_header *header = (const struct sensor_data_generic_header *)buffer; - const q31_t *q = - (const q31_t *)(buffer + sizeof(struct sensor_data_generic_header) + - header->num_channels * sizeof(enum sensor_channel)); + const q31_t *q = (const q31_t *)(buffer + sizeof(struct sensor_data_generic_header) + + header->num_channels * sizeof(enum sensor_channel)); int count = 0; if (*fit != 0 || *cit >= header->num_channels) { diff --git a/include/zephyr/sensing/sensing.h b/include/zephyr/sensing/sensing.h index 3fc6df3c25ac7a..f1791edb250c26 100644 --- a/include/zephyr/sensing/sensing.h +++ b/include/zephyr/sensing/sensing.h @@ -168,6 +168,7 @@ typedef void *sensing_sensor_handle_t; */ typedef void (*sensing_data_event_t)(sensing_sensor_handle_t handle, const void *buf); +#include /** * @struct sensing_sensor_info * @brief Sensor basic constant information @@ -180,6 +181,13 @@ struct sensing_sensor_info { /** Sensor type */ int32_t type; + + /****** TODO hide these (private members) ******/ + struct rtio_iodev *iodev; + +#ifdef CONFIG_SENSING_SHELL + char *shell_name; +#endif }; /** @@ -241,7 +249,7 @@ struct sensing_sensor_attribute { int8_t shift; }; -int sensing_set_attributes(sensing_sensor_handle_t handle, +int sensing_set_attributes(sensing_sensor_handle_t handle, enum sensing_sensor_mode mode, struct sensing_sensor_attribute *attributes, size_t count); /** diff --git a/include/zephyr/sensing/sensor.h b/include/zephyr/sensing/sensor.h index cd4614a8187d7d..f9403961fcf3a9 100644 --- a/include/zephyr/sensing/sensor.h +++ b/include/zephyr/sensing/sensor.h @@ -14,17 +14,25 @@ #define SENSING_SENSOR_INFO_DT_NAME(node_id, type) \ _CONCAT(_CONCAT(__sensing_sensor_info_, DEVICE_DT_NAME_GET(node_id)), type) -#define SENSING_SENSOR_INFO_INST_DEFINE(node_id, prop, idx) \ - const STRUCT_SECTION_ITERABLE( \ - sensing_sensor_info, \ - SENSING_SENSOR_INFO_DT_NAME(node_id, DT_PROP_BY_IDX(node_id, prop, idx))) = { \ +#define SENSING_SENSOR_INFO_INST_DEFINE_NAMED(node_id, name, prop, idx, _iodev) \ + IF_ENABLED(CONFIG_SENSING_SHELL, (static char node_id##_##idx##_name_buffer[5];)) \ + const STRUCT_SECTION_ITERABLE(sensing_sensor_info, name) = { \ .info = &SENSOR_INFO_DT_NAME(DT_PHANDLE(node_id, dev)), \ .dev = DEVICE_DT_GET(node_id), \ .type = DT_PROP_BY_IDX(node_id, prop, idx), \ + .iodev = &(_iodev), \ + IF_ENABLED(CONFIG_SENSING_SHELL, (.shell_name = node_id##_##idx##_name_buffer, )) \ }; +#define SENSING_SENSOR_INFO_INST_DEFINE(node_id, prop, idx, _iodev) \ + SENSING_SENSOR_INFO_INST_DEFINE_NAMED( \ + node_id, SENSING_SENSOR_INFO_DT_NAME(node_id, DT_PROP_BY_IDX(node_id, prop, idx)), \ + prop, idx, _iodev) + #define SENSING_SENSOR_INFO_DT_DEFINE(node_id) \ - DT_FOREACH_PROP_ELEM(node_id, sensor_types, SENSING_SENSOR_INFO_INST_DEFINE) + SENSOR_DT_READ_IODEV(node_id##_read_iodev, node_id, SENSOR_CHAN_ALL); \ + DT_FOREACH_PROP_ELEM_VARGS(node_id, sensor_types, SENSING_SENSOR_INFO_INST_DEFINE, \ + node_id##_read_iodev) #define SENSING_SENSOR_DT_DEFINE(node_id, init_fn, pm_device, data_ptr, cfg_ptr, level, prio, \ api_ptr, ...) \ @@ -38,6 +46,7 @@ #define SENSING_SENSOR_INFO_GET(node_id, type) &SENSING_SENSOR_INFO_DT_NAME(node_id, type) STRUCT_SECTION_START_EXTERN(sensing_sensor_info); +STRUCT_SECTION_END_EXTERN(sensing_sensor_info); #if defined(CONFIG_HAS_DTS) || defined(__DOXYGEN__) #define Z_MAYBE_SENSING_SENSOR_INFO_DECLARE_INTERNAL_DEFINE(node_id, prop, idx) \ diff --git a/samples/sensor/sensor_shell/prj.conf b/samples/sensor/sensor_shell/prj.conf index 6605bdf9f1e0da..0e6ac047463ce6 100644 --- a/samples/sensor/sensor_shell/prj.conf +++ b/samples/sensor/sensor_shell/prj.conf @@ -10,5 +10,6 @@ CONFIG_RTIO_CONSUME_SEM=y CONFIG_USERSPACE=y CONFIG_SENSING=y CONFIG_SENSING_SHELL=y +CONFIG_RTIO_LOG_LEVEL_DBG=y CONFIG_SENSOR_LOG_LEVEL_DBG=y CONFIG_SENSING_LOG_LEVEL_DBG=y diff --git a/subsys/sensing/CMakeLists.txt b/subsys/sensing/CMakeLists.txt index 0ca14419e76a1c..1d19a3c49e4185 100644 --- a/subsys/sensing/CMakeLists.txt +++ b/subsys/sensing/CMakeLists.txt @@ -6,6 +6,7 @@ zephyr_library_sources( src/sensor_info.c src/sensor_pipe.c src/sensor_connections.c + src/processing.c ) zephyr_library_sources_ifdef(CONFIG_SENSING_SHELL src/shell.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE src/userspace.c) diff --git a/subsys/sensing/Kconfig b/subsys/sensing/Kconfig index c7d10fb9436276..c73ac89183e014 100644 --- a/subsys/sensing/Kconfig +++ b/subsys/sensing/Kconfig @@ -6,6 +6,7 @@ config SENSING select DSP select SENSOR_INFO select SYS_MEM_BLOCKS + select SENSOR_ASYNC_API help Enable Sensing Subsystem. @@ -25,6 +26,28 @@ config SENSING_MAX_CONNECTIONS same sensor by different clients or the same client to different sensors). +config SENSING_RTIO_BLOCK_SIZE + int "Block size of the RTIO context" + default 64 + +config SENSING_RTIO_BLOCK_COUNT + int "Number of memory blocks of the RTIO context" + default 32 + +config SENSING_PROCESSING_THREAD_STACK_SIZE + int "Stack size for the subsystem's data processing thread" + default 1024 + help + Thread stack size to use for the sensor data processing of the sensing + subsystem. The more data is expected to come through prior to being + dispatched to clients, the larger the stack will need to be. + +config SENSING_PROCESSING_THREAD_PRIORITY + int "Thread priority of the subsystem's data processing thread" + default 10 + help + The sensor subsystem's data processing thread priority + config SENSING_SHELL bool "Shell commands for sensing subsystem" diff --git a/subsys/sensing/include/sensing/internal/sensing.h b/subsys/sensing/include/sensing/internal/sensing.h index bfa1cfc652f02a..15a5ed9177d8e2 100644 --- a/subsys/sensing/include/sensing/internal/sensing.h +++ b/subsys/sensing/include/sensing/internal/sensing.h @@ -16,6 +16,7 @@ struct sensing_connection { const struct sensing_sensor_info *info; const struct sensing_callback_list *cb_list; + enum sensing_sensor_mode mode; q31_t attributes[SENSOR_ATTR_COMMON_COUNT]; uint32_t attribute_mask; } __packed __aligned(4); @@ -28,6 +29,8 @@ extern struct sensing_connection_pool { BUILD_ASSERT(SENSOR_ATTR_COMMON_COUNT <= 32, "Too many sensor attributes"); +extern struct rtio sensing_rtio_ctx; + static inline bool __sensing_is_connected(const struct sensing_sensor_info *info, const struct sensing_connection *connection) { diff --git a/subsys/sensing/src/processing.c b/subsys/sensing/src/processing.c new file mode 100644 index 00000000000000..ab001ae501219c --- /dev/null +++ b/subsys/sensing/src/processing.c @@ -0,0 +1,78 @@ +// +// Created by peress on 05/07/23. +// + +#include +#include +#include +#include +#include + +#include "sensing/internal/sensing.h" + +LOG_MODULE_REGISTER(sensing_processing, CONFIG_SENSING_LOG_LEVEL); + +static void processing_task(void *a, void *b, void *c) +{ + struct sensing_sensor_info *info; + uint8_t *data = NULL; + uint32_t data_len = 0; + int rc; + int get_data_rc; + + ARG_UNUSED(a); + ARG_UNUSED(b); + ARG_UNUSED(c); + + if (IS_ENABLED(CONFIG_USERSPACE) && !k_is_user_context()) { + rtio_access_grant(&sensing_rtio_ctx, k_current_get()); + k_thread_user_mode_enter(processing_task, a, b, c); + } + + while (true) { + struct rtio_cqe cqe; + + rc = rtio_cqe_copy_out(&sensing_rtio_ctx, &cqe, 1, K_FOREVER); + + if (rc < 1) { + continue; + } + + /* Cache the data from the CQE */ + rc = cqe.result; + info = cqe.userdata; + get_data_rc = + rtio_cqe_get_mempool_buffer(&sensing_rtio_ctx, &cqe, &data, &data_len); + + /* Do something with the data */ + LOG_DBG("Processing data for [%d], rc=%d, has_data=%d, data=%p, len=%" PRIu32, + (int)(info - STRUCT_SECTION_START(sensing_sensor_info)), rc, + get_data_rc == 0, (void *)data, data_len); + + if (get_data_rc != 0 || data_len == 0) { + continue; + } + + sys_mutex_lock(__sensing_connection_pool.lock, K_FOREVER); + for (int i = 0; i < ARRAY_SIZE(__sensing_connection_pool.pool); ++i) { + struct sensing_connection *connection = &__sensing_connection_pool.pool[i]; + if (!__sensing_is_connected(info, connection)) { + continue; + } + sensing_data_event_t cb = connection->cb_list->on_data_event; + + if (cb == NULL) { + continue; + } + /* TODO we actually need to decode the data first before this for loop */ + cb(connection, data); + } + sys_mutex_unlock(__sensing_connection_pool.lock); + + /* Release the memory */ + rtio_release_buffer(&sensing_rtio_ctx, data, data_len); + } +} + +K_THREAD_DEFINE(sensing_processor, CONFIG_SENSING_PROCESSING_THREAD_STACK_SIZE, processing_task, + NULL, NULL, NULL, CONFIG_SENSING_PROCESSING_THREAD_PRIORITY, 0, 0); diff --git a/subsys/sensing/src/sensor_connections.c b/subsys/sensing/src/sensor_connections.c index 7079d49c71f669..71134e8581f699 100644 --- a/subsys/sensing/src/sensor_connections.c +++ b/subsys/sensing/src/sensor_connections.c @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -13,7 +14,7 @@ LOG_MODULE_REGISTER(sensing_connect, CONFIG_SENSING_LOG_LEVEL); struct sensing_connection *name = handle; \ __ASSERT_NO_MSG((uintptr_t)name >= (uintptr_t)__sensing_connection_pool.pool); \ __ASSERT_NO_MSG((uintptr_t)name < (uintptr_t)__sensing_connection_pool.pool + \ - sizeof(__sensing_connection_pool.pool)); + sizeof(__sensing_connection_pool.pool)) SENSING_DMEM SYS_MUTEX_DEFINE(connection_lock); @@ -32,6 +33,10 @@ SENSING_DMEM struct sensing_connection_pool __sensing_connection_pool = { #define __lock sys_mutex_lock(__sensing_connection_pool.lock, K_FOREVER) #define __unlock sys_mutex_unlock(__sensing_connection_pool.lock) +RTIO_DEFINE_WITH_MEMPOOL(sensing_rtio_ctx, CONFIG_SENSING_MAX_CONNECTIONS, + CONFIG_SENSING_MAX_CONNECTIONS, CONFIG_SENSING_RTIO_BLOCK_COUNT, + CONFIG_SENSING_RTIO_BLOCK_SIZE, 4); + int sensing_open_sensor(const struct sensing_sensor_info *info, const struct sensing_callback_list *cb_list, sensing_sensor_handle_t *handle) @@ -84,10 +89,11 @@ int sensing_close_sensor(sensing_sensor_handle_t handle) return rc; } -int sensing_set_attributes(sensing_sensor_handle_t handle, +int sensing_set_attributes(sensing_sensor_handle_t handle, enum sensing_sensor_mode mode, struct sensing_sensor_attribute *attributes, size_t count) { __HANDLE_TO_CONNECTION(connection, handle); + int rc; __lock; for (size_t i = 0; i < count; ++i) { @@ -101,9 +107,21 @@ int sensing_set_attributes(sensing_sensor_handle_t handle, LOG_DBG("Updated attribute (%d) to 0x%08x->0x%08x", attributes[i].attribute, attributes[i].value, value); } + connection->mode = mode; __sensing_arbitrate(); + + switch (mode) { + case SENSING_SENSOR_MODE_ONE_SHOT: + LOG_DBG("Starting one-shot read"); + rc = sensor_read(connection->info->iodev, &sensing_rtio_ctx, + (void *)connection->info); + break; + default: + rc = -EINVAL; + break; + } __unlock; - return 0; + return rc; } const struct sensing_sensor_info *sensing_get_sensor_info(sensing_sensor_handle_t handle) diff --git a/subsys/sensing/src/sensor_pipe.c b/subsys/sensing/src/sensor_pipe.c index 09def4b6136894..c3b264bfbb0922 100644 --- a/subsys/sensing/src/sensor_pipe.c +++ b/subsys/sensing/src/sensor_pipe.c @@ -9,6 +9,8 @@ #include #include +#include "sensing/internal/sensing.h" + LOG_MODULE_REGISTER(sensing_pipe, CONFIG_SENSING_LOG_LEVEL); #define DT_DRV_COMPAT zephyr_sensing_pipe @@ -17,6 +19,10 @@ struct sensor_pipe_config { const struct sensor_info *parent_info; }; +struct sensor_pipe_data { + struct rtio_iodev *oneshot_iodev; +}; + static int attribute_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr, const struct sensor_value *val) { @@ -26,11 +32,30 @@ static int attribute_set(const struct device *dev, enum sensor_channel chan, return sensor_attr_set(cfg->parent_info->dev, chan, attr, val); } -static const struct sensor_driver_api sensor_pipe_api = { +static int submit(const struct device *sensor, struct rtio_iodev_sqe *sqe) +{ + struct sensor_pipe_data *data = sensor->data; + + const struct sensing_sensor_info *info = sqe->sqe.userdata; + + LOG_DBG("Trying to read %s [%d] type=%d", info->info->dev->name, + (int)(info - STRUCT_SECTION_START(sensing_sensor_info)), info->type); + + int rc = sensor_read(data->oneshot_iodev, &sensing_rtio_ctx, sqe->sqe.userdata); + + if (rc == 0) { + rtio_iodev_sqe_ok(sqe, 0); + } else { + rtio_iodev_sqe_err(sqe, rc); + } + return rc; +} + +SENSING_DMEM static const struct sensor_driver_api sensor_pipe_api = { .attr_set = attribute_set, .attr_get = NULL, .get_decoder = NULL, - .submit = NULL, + .submit = submit, }; static int sensing_sensor_pipe_init(const struct device *dev) @@ -45,7 +70,12 @@ static int sensing_sensor_pipe_init(const struct device *dev) static const struct sensor_pipe_config cfg_##inst = { \ .parent_info = &SENSOR_INFO_DT_NAME(DT_INST_PHANDLE(inst, dev)), \ }; \ - SENSING_SENSOR_DT_INST_DEFINE(inst, sensing_sensor_pipe_init, NULL, NULL, &cfg_##inst, \ - APPLICATION, 10, &sensor_pipe_api); + SENSOR_DT_READ_IODEV(underlying_reader_##inst, DT_INST_PHANDLE(inst, dev), \ + SENSOR_CHAN_ALL); \ + static struct sensor_pipe_data data_##inst = { \ + .oneshot_iodev = &underlying_reader_##inst, \ + }; \ + SENSING_SENSOR_DT_INST_DEFINE(inst, sensing_sensor_pipe_init, NULL, &data_##inst, \ + &cfg_##inst, APPLICATION, 10, &sensor_pipe_api); DT_INST_FOREACH_STATUS_OKAY(SENSING_PIPE_INIT) diff --git a/subsys/sensing/src/shell.c b/subsys/sensing/src/shell.c index eea8b2773f912e..8070abfcf0d9c1 100644 --- a/subsys/sensing/src/shell.c +++ b/subsys/sensing/src/shell.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #define SENSING_INFO_HELP "Get sensor info, such as vendor and model name, for all sensors." @@ -13,7 +15,57 @@ #define SENSING_CONFIG_HELP \ "Configure an existing connection:\n" \ - " " + " [ ... " \ + "]" + +static const char *mode_string_map[] = { + [SENSING_SENSOR_MODE_CONTINUOUS] = "continuous", + [SENSING_SENSOR_MODE_ONE_SHOT] = "one_shot", + [SENSING_SENSOR_MODE_PASSIVE_CONTINUOUS] = "passive_continuous", + [SENSING_SENSOR_MODE_PASSIVE_ONE_SHOT] = "passive_one_shot", + [SENSING_SENSOR_MODE_DONE] = "done", +}; + +static int parse_sensor_mode(const char *arg, enum sensing_sensor_mode *mode) +{ + for (int i = 0; i < ARRAY_SIZE(mode_string_map); ++i) { + if (strcmp(mode_string_map[i], arg) == 0) { + *mode = i; + return 0; + } + } + return -1; +} + +static const char *sensor_attribute_name[SENSOR_ATTR_COMMON_COUNT] = { + [SENSOR_ATTR_SAMPLING_FREQUENCY] = "sampling_frequency", + [SENSOR_ATTR_LOWER_THRESH] = "lower_thresh", + [SENSOR_ATTR_UPPER_THRESH] = "upper_thresh", + [SENSOR_ATTR_SLOPE_TH] = "slope_th", + [SENSOR_ATTR_SLOPE_DUR] = "slope_dur", + [SENSOR_ATTR_HYSTERESIS] = "hysteresis", + [SENSOR_ATTR_OVERSAMPLING] = "oversampling", + [SENSOR_ATTR_FULL_SCALE] = "full_scale", + [SENSOR_ATTR_OFFSET] = "offset", + [SENSOR_ATTR_CALIB_TARGET] = "calib_target", + [SENSOR_ATTR_CONFIGURATION] = "configuration", + [SENSOR_ATTR_CALIBRATION] = "calibration", + [SENSOR_ATTR_FEATURE_MASK] = "feature_mask", + [SENSOR_ATTR_ALERT] = "alert", + [SENSOR_ATTR_FF_DUR] = "ff_dur", + [SENSOR_ATTR_FIFO_WATERMARK] = "fifo_wm", +}; + +static int parse_sensor_attribute(const char *arg, enum sensor_attribute *attr) +{ + for (int i = 0; i < ARRAY_SIZE(sensor_attribute_name); ++i) { + if (strcmp(sensor_attribute_name[i], arg) == 0) { + *attr = i; + return 0; + } + } + return -1; +} #define SENSOR_TYPE_TO_STRING(type) \ case type: \ @@ -72,11 +124,19 @@ static int cmd_get_sensor_info(const struct shell *sh, size_t argc, char **argv) struct shell_cmd_connection { sensing_sensor_handle_t handle; bool is_used; + char shell_name[5]; }; static struct shell_cmd_connection open_connections[CONFIG_SENSING_MAX_CONNECTIONS]; +static void sensing_shell_on_data_event(sensing_sensor_handle_t handle, const void *data) +{ + const struct sensing_sensor_info *info = sensing_get_sensor_info(handle); + + printk("Got data for '%s' at %p\n", get_sensor_type_string(info->type), data); +} + static const struct sensing_callback_list callback_list = { - .on_data_event = NULL, + .on_data_event = sensing_shell_on_data_event, }; static int cmd_open_connection(const struct shell *sh, size_t argc, char **argv) @@ -137,7 +197,8 @@ static int cmd_open_connection(const struct shell *sh, size_t argc, char **argv) } open_connections[connection_idx].is_used = true; - shell_print(sh, "New connection [%d] to sensor [%ld] created", connection_idx, sensor_index); + shell_print(sh, "New connection [%d] to sensor [%ld] created", connection_idx, + sensor_index); return 0; } @@ -211,6 +272,7 @@ static int parse_sensor_value(const struct shell *sh, const char *val_str, q31_t static int cmd_config(const struct shell *sh, size_t argc, char **argv) { + int rc; char *endptr; long connection_index = strtol(argv[1], &endptr, 0); @@ -221,25 +283,36 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv) return -EINVAL; } - enum sensor_attribute attribute; - if (strcmp("sampling_frequency", argv[2]) == 0) { - attribute = SENSOR_ATTR_SAMPLING_FREQUENCY; - } else { - shell_error(sh, "Invalid attribute '%s'", argv[2]); + enum sensing_sensor_mode mode; + rc = parse_sensor_mode(argv[2], &mode); + if (rc != 0) { + shell_error(sh, "Invalid mode '%s'", argv[2]); return -EINVAL; } - struct sensing_sensor_attribute config = { - .attribute = attribute, - }; - int rc = parse_sensor_value(sh, argv[3], &config.value, &config.shift); - - if (rc != 0) { - shell_error(sh, "Invalid value '%s'", argv[3]); + int config_count = 0; + struct sensing_sensor_attribute configs[4] = {0}; + if (argc % 2 == 0) { + shell_error(sh, "Invalid config, must use pairs of "); return -EINVAL; } + for (int i = 3; i < argc; i += 2) { + rc = parse_sensor_attribute(argv[i], &configs[config_count].attribute); + if (rc != 0) { + shell_error(sh, "Invalid attribute '%s'", argv[i]); + return -EINVAL; + } + rc = parse_sensor_value(sh, argv[i + 1], &configs[config_count].value, + &configs[config_count].shift); + if (rc != 0) { + shell_error(sh, "Invalid value '%s'", argv[i + 1]); + return -EINVAL; + } + config_count++; + } - rc = sensing_set_attributes(open_connections[connection_index].handle, &config, 1); + rc = sensing_set_attributes(open_connections[connection_index].handle, mode, configs, + config_count); if (rc != 0) { shell_error(sh, "Failed to set attribute '%s' to '%s'", argv[2], argv[3]); return rc; @@ -247,10 +320,98 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv) return 0; } +static void sensing_node_index_get(size_t idx, struct shell_static_entry *entry) +{ + size_t count; + + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; + + STRUCT_SECTION_START_EXTERN(sensing_sensor_info); + STRUCT_SECTION_COUNT(sensing_sensor_info, &count); + if (idx >= count || idx > 9999) { + return; + } + snprintk(STRUCT_SECTION_START(sensing_sensor_info)[idx].shell_name, 5, "%d", (int)idx); + entry->syntax = STRUCT_SECTION_START(sensing_sensor_info)[idx].shell_name; +} +SHELL_DYNAMIC_CMD_CREATE(dsub_node_index, sensing_node_index_get); + +static void sensing_connection_node_index_get(size_t idx, struct shell_static_entry *entry, + const union shell_cmd_entry *subcmd) +{ + entry->syntax = NULL; + entry->handler = NULL; + entry->help = NULL; + entry->subcmd = NULL; + + if (idx >= ARRAY_SIZE(open_connections) || !open_connections[idx].is_used) { + return; + } + + snprintk(open_connections[idx].shell_name, 5, "%d", (int)idx); + entry->syntax = open_connections[idx].shell_name; + entry->subcmd = subcmd; +} + +static void sensing_connection_node_index_get_for_close(size_t idx, + struct shell_static_entry *entry) +{ + sensing_connection_node_index_get(idx, entry, NULL); +} +SHELL_DYNAMIC_CMD_CREATE(dsub_connection_node_index_for_close, + sensing_connection_node_index_get_for_close); + +// static void sensing_attr_for_config(size_t idx, struct shell_static_entry *entry); +// SHELL_DYNAMIC_CMD_CREATE(dsub_sensor_attr_for_config, sensing_attr_for_config); +// +// static void sensing_attr_val_for_config(size_t idx, struct shell_static_entry *entry) +//{ +// entry->syntax = NULL; +// entry->subcmd = &dsub_sensor_attr_for_config; +// } +// SHELL_DYNAMIC_CMD_CREATE(dsub_sensor_attr_val_for_config, sensing_attr_val_for_config); +// +// static void sensing_attr_for_config(size_t idx, struct shell_static_entry *entry) +//{ +// if (idx >= ARRAY_SIZE(sensor_attribute_name)) { +// entry->syntax = NULL; +// return; +// } +// +// entry->syntax = sensor_attribute_name[idx]; +// entry->subcmd = &dsub_sensor_attr_val_for_config; +// } + +static void sensing_sensor_mode_for_config(size_t idx, struct shell_static_entry *entry) +{ + if (idx >= ARRAY_SIZE(mode_string_map)) { + entry->syntax = NULL; + return; + } + + entry->syntax = mode_string_map[idx]; + entry->subcmd = NULL; //&dsub_sensor_attr_for_config; +} +SHELL_DYNAMIC_CMD_CREATE(dsub_sensor_mode_for_config, sensing_sensor_mode_for_config); + +static void sensing_connection_node_index_get_for_config(size_t idx, + struct shell_static_entry *entry) +{ + sensing_connection_node_index_get(idx, entry, &dsub_sensor_mode_for_config); +} +SHELL_DYNAMIC_CMD_CREATE(dsub_connection_node_index_for_config, + sensing_connection_node_index_get_for_config); + SHELL_STATIC_SUBCMD_SET_CREATE( sub_sensing, SHELL_CMD_ARG(info, NULL, SENSING_INFO_HELP, cmd_get_sensor_info, 1, 0), - SHELL_CMD_ARG(open, NULL, SENSING_OPEN_HELP, cmd_open_connection, 1, 1), - SHELL_CMD_ARG(close, NULL, SENSING_CLOSE_HELP, cmd_close_connection, 2, 0), - SHELL_CMD_ARG(config, NULL, SENSING_CONFIG_HELP, cmd_config, 4, 0), SHELL_SUBCMD_SET_END); + SHELL_CMD_ARG(open, &dsub_node_index, SENSING_OPEN_HELP, cmd_open_connection, 1, 1), + SHELL_CMD_ARG(close, &dsub_connection_node_index_for_close, SENSING_CLOSE_HELP, + cmd_close_connection, 2, 0), + SHELL_CMD_ARG(config, &dsub_connection_node_index_for_config, SENSING_CONFIG_HELP, + cmd_config, 3, 11), + SHELL_SUBCMD_SET_END); SHELL_CMD_REGISTER(sensing, &sub_sensing, "Sensing subsystem commands", NULL); diff --git a/subsys/sensing/src/userspace.c b/subsys/sensing/src/userspace.c index f24550bd915467..486814808093b1 100644 --- a/subsys/sensing/src/userspace.c +++ b/subsys/sensing/src/userspace.c @@ -2,9 +2,12 @@ // Created by peress on 29/06/23. // +#include +#include #include #include -#include + +LOG_MODULE_REGISTER(sensing_userspace, CONFIG_SENSING_LOG_LEVEL); K_APPMEM_PARTITION_DEFINE(sensing_mem_partition); @@ -14,9 +17,15 @@ static int sensing_mem_init(void) rc = k_mem_domain_add_partition(&k_mem_domain_default, &sensing_mem_partition); if (rc != 0) { + LOG_ERR("Failed to add sensing memory partition to the default domain"); + return rc; + } + rc = k_mem_domain_add_partition(&k_mem_domain_default, &rtio_partition); + if (rc != 0) { + LOG_ERR("Failed to add rtio partition to the default domain"); return rc; } - return k_mem_domain_add_partition(&k_mem_domain_default, &rtio_partition); + return 0; } SYS_INIT(sensing_mem_init, POST_KERNEL, 99);