Skip to content

Commit

Permalink
add support for userspace
Browse files Browse the repository at this point in the history
  • Loading branch information
yperess committed Jul 5, 2023
1 parent 3a9fb5b commit 1462d8a
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 43 deletions.
67 changes: 67 additions & 0 deletions include/zephyr/sensing/sensing.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,73 @@ extern "C" {
#define SENSING_BMEM
#endif

/**
* @addtogroup sensiong_sensor_modes
* @{
*/

enum sensing_sensor_mode {
/**
* @brief Get events from the sensor.
*
* Power: Turn on if not already on.
* Reporting: Continuous. Send each new event as it comes (subject to batching and latency).
*/
SENSING_SENSOR_MODE_CONTINUOUS,

/**
* @brief Get a single event from the sensor and then become DONE.
*
* Once the event is sent, the sensor automatically changes to
* :c:enum:`SENSING_SENSOR_MODE_DONE`.
*
* Power: Turn on if not already on.
* Reporting: One shot. Send the next event and then be DONE.
*/
SENSING_SENSOR_MODE_ONE_SHOT,

/**
* @brief Get events from a sensor that are generated for any client in the system.
*
* This is considered passive because the sensor will not be powered on for the sake of the
* client. If and only if another client in the system has requested this sensor power on
* will we get events.
*
* This can be useful for something which is interested in seeing data, but not interested
* enough to be responsible for powering on the sensor.
*
* Power: Do not power the sensor on our behalf.
* Reporting: Continuous. Send each event as it comes.
*/
SENSING_SENSOR_MODE_PASSIVE_CONTINUOUS,

/**
* @brief Get a single event from a sensor that is generated for any client in the system.
*
* See :c:enum:`SENSING_SENSOR_MODE_PASSIVE_CONTINUOUS` for more details on what the
* "passive" means.
*
* Power: Do not power the sensor on our behalf.
* Reporting: One shot. Send only the next event and then be DONE.
*/
SENSING_SENSOR_MODE_PASSIVE_ONE_SHOT,

/**
* @brief Indicate we are done using this sensor and no longer interested in it.
*
* See :c:func:`sensing_configure` for more details on expressing interest or lack of
* interest in a sensor.
*
* Power: Do not power the sensor on our behalf.
* Reporting: None.
*/
SENSING_SENSOR_MODE_DONE,
};

/**
* @}
*/

/**
* @struct sensing_sensor_version
* @brief Sensor Version
Expand Down
17 changes: 8 additions & 9 deletions include/zephyr/sensing/sensor_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,25 @@
/**
* sensor category light
*/
#define SENSING_SENSOR_TYPE_LIGHT_AMBIENTLIGHT 0x41
#define SENSING_SENSOR_TYPE_LIGHT_AMBIENTLIGHT 0x41

/**
* sensor category motion
*/
#define SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D 115
#define SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D 118
#define SENSING_SENSOR_TYPE_MOTION_MOTION_DETECTOR 119

#define SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D 115
#define SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D 118
#define SENSING_SENSOR_TYPE_MOTION_MOTION_DETECTOR 119

/**
* sensor category other
*/
#define SENSING_SENSOR_TYPE_OTHER_CUSTOM 0xE1
#define SENSING_SENSOR_TYPE_OTHER_CUSTOM 0xE1

#define SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D 0x240
#define SENSING_SENSOR_TYPE_MOTION_UNCALIB_ACCELEROMETER_3D 0x240

#define SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE 0x20B
#define SENSING_SENSOR_TYPE_MOTION_HINGE_ANGLE 0x20B

#define SENSING_SENSOR_TYPE_ALL 0xFFFF
#define SENSING_SENSOR_TYPE_ALL 0xFFFF

/**
* @}
Expand Down
1 change: 1 addition & 0 deletions samples/sensor/sensor_shell/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ CONFIG_SENSOR_INFO=y
CONFIG_LOG=y
CONFIG_RTIO_CONSUME_SEM=y

CONFIG_USERSPACE=y
CONFIG_SENSING=y
CONFIG_SENSING_SHELL=y
CONFIG_SENSOR_LOG_LEVEL_DBG=y
Expand Down
1 change: 1 addition & 0 deletions subsys/sensing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ zephyr_library_sources(
src/sensor_connections.c
)
zephyr_library_sources_ifdef(CONFIG_SENSING_SHELL src/shell.c)
zephyr_library_sources_ifdef(CONFIG_USERSPACE src/userspace.c)

zephyr_library_include_directories(include)
18 changes: 13 additions & 5 deletions subsys/sensing/include/sensing/internal/sensing.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <zephyr/drivers/sensor.h>
#include <zephyr/sensing/sensing.h>
#include <zephyr/dsp/types.h>
#include <zephyr/sys/mutex.h>

#define __SENSING_POOL_MASK_BUNDLE_COUNT \
(DIV_ROUND_UP(DIV_ROUND_UP(CONFIG_SENSING_MAX_CONNECTIONS, 8), sizeof(uint32_t)))
Expand All @@ -17,20 +18,27 @@ struct sensing_connection {
const struct sensing_callback_list *cb_list;
q31_t attributes[SENSOR_ATTR_COMMON_COUNT];
uint32_t attribute_mask;
struct {
uint8_t in_use: 1;
uint8_t reserved: 7;
} flags;
} __packed __aligned(4);

extern struct sensing_connection_pool {
struct sensing_connection pool[CONFIG_SENSING_MAX_CONNECTIONS];
sys_bitarray_t *bitarray;
struct k_mutex *lock;
struct sys_mutex *lock;
} __sensing_connection_pool;

BUILD_ASSERT(SENSOR_ATTR_COMMON_COUNT <= 32, "Too many sensor attributes");

static inline bool __sensing_is_connected(const struct sensing_sensor_info *info,
const struct sensing_connection *connection)
{
int is_set;
int connection_index = connection - __sensing_connection_pool.pool;
int rc = sys_bitarray_test_bit(__sensing_connection_pool.bitarray, connection_index,
&is_set);

return rc == 0 && is_set != 0 && (info == NULL || connection->info == info);
}

void __sensing_arbitrate();

#endif // ZEPHYR_SUBSYS_SENSING_INCLUDE_SENSING_INTERNAL_SENSING_H
13 changes: 7 additions & 6 deletions subsys/sensing/src/sensor_arbitrate.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,22 @@ static int arbitrate_sensor_attribute(const struct sensing_sensor_info *info,
q31_t value;

for (int i = 0; i < CONFIG_SENSING_MAX_CONNECTIONS; ++i) {
if (connections[i].info != info || !connections[i].flags.in_use) {
// LOG_DBG("Skipping connection %p, info mismatch", (void*)&connections[i]);
if (!__sensing_is_connected(info, &connections[i])) {
continue;
}
if (FIELD_GET(BIT(attribute), connections[i].attribute_mask) == 0) {
// LOG_DBG("Skipping connection %p, attribute not set", (void*)&connections[i]);
continue;
}
if (connection_count == 0) {
/* First connection */
value = connections[i].attributes[attribute];
LOG_DBG("Arbitrating '%s'@%p type=%d attribute=%d", info->info->dev->name,
info->info->dev, info->type, attribute);
LOG_DBG(" First connection %p, value=0x%08x", (void*)&connections[i], value);
LOG_DBG(" First connection %d/%p, value=0x%08x", i, (void*)&connections[i], value);
} else {
value = arbitrate_attribute_value(attribute, value,
connections[i].attributes[attribute]);
LOG_DBG(" Updating %p, value=0x%08x", (void*)&connections[i], value);
LOG_DBG(" Updating %d/%p, value=0x%08x", i, (void*)&connections[i], value);
}
connection_count++;
}
Expand All @@ -83,9 +81,12 @@ static int arbitrate_sensor_attribute(const struct sensing_sensor_info *info,

static void arbitrate_sensor_instance(const struct sensing_sensor_info *info)
{
int count = 0;

for (int i = 0; i < SENSOR_ATTR_COMMON_COUNT; ++i) {
arbitrate_sensor_attribute(info, i);
count += arbitrate_sensor_attribute(info, i);
}
LOG_DBG("Arbitrated %p with %d connections", (void*)info, count);
}

void __sensing_arbitrate(void)
Expand Down
39 changes: 18 additions & 21 deletions subsys/sensing/src/sensor_connections.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ LOG_MODULE_REGISTER(sensing_connect, CONFIG_SENSING_LOG_LEVEL);
__ASSERT_NO_MSG((uintptr_t)name < (uintptr_t)__sensing_connection_pool.pool + \
sizeof(__sensing_connection_pool.pool));

K_MUTEX_DEFINE(connection_lock);
SENSING_DMEM SYS_MUTEX_DEFINE(connection_lock);

static uint32_t bitarray_bundles[__SENSING_POOL_MASK_BUNDLE_COUNT];
static sys_bitarray_t bitarray = {
SENSING_DMEM static uint32_t bitarray_bundles[__SENSING_POOL_MASK_BUNDLE_COUNT] = {0};
SENSING_DMEM static sys_bitarray_t bitarray = {
.num_bits = CONFIG_SENSING_MAX_CONNECTIONS,
.num_bundles = __SENSING_POOL_MASK_BUNDLE_COUNT,
.bundles = bitarray_bundles,
};

struct sensing_connection_pool __sensing_connection_pool = {
SENSING_DMEM struct sensing_connection_pool __sensing_connection_pool = {
.bitarray = &bitarray,
.lock = &connection_lock,
};

#define __lock k_mutex_lock(__sensing_connection_pool.lock, K_FOREVER)
#define __unlock k_mutex_unlock(__sensing_connection_pool.lock)
#define __lock sys_mutex_lock(__sensing_connection_pool.lock, K_FOREVER)
#define __unlock sys_mutex_unlock(__sensing_connection_pool.lock)

int sensing_open_sensor(const struct sensing_sensor_info *info,
const struct sensing_callback_list *cb_list,
Expand All @@ -53,10 +53,9 @@ int sensing_open_sensor(const struct sensing_sensor_info *info,

connection = &__sensing_connection_pool.pool[offset];

__ASSERT_NO_MSG(!connection->flags.in_use);
LOG_DBG("Connection opened @ %p (size=%d) for info @ %p", connection,
(int)sizeof(struct sensing_connection), info);
connection->flags.in_use = true;
memset(connection, 0, sizeof(struct sensing_connection));
connection->info = info;
connection->cb_list = cb_list;
*handle = connection;
Expand All @@ -67,21 +66,19 @@ int sensing_open_sensor(const struct sensing_sensor_info *info,
int sensing_close_sensor(sensing_sensor_handle_t handle)
{
__HANDLE_TO_CONNECTION(connection, handle);

if (!connection->flags.in_use) {
return -EINVAL;
}
connection->flags.in_use = false;
int rc = -EINVAL;

__lock;
LOG_DBG("Releasing connection at %p", handle);
int rc = sys_bitarray_free(__sensing_connection_pool.bitarray, 1,
connection - __sensing_connection_pool.pool);

if (rc != 0) {
connection->flags.in_use = true;
} else {
__sensing_arbitrate();
if (__sensing_is_connected(NULL, connection)) {
LOG_DBG("Releasing connection at %p/%d", handle,
connection - __sensing_connection_pool.pool);
rc = sys_bitarray_free(__sensing_connection_pool.bitarray, 1,
connection - __sensing_connection_pool.pool);
if (rc == 0) {
__sensing_arbitrate();
} else {
LOG_WRN("Failed to release connection");
}
}
__unlock;
return rc;
Expand Down
2 changes: 0 additions & 2 deletions subsys/sensing/src/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ static int parse_sensor_value(const struct shell *sh, const char *val_str, q31_t
micro_value += value;
end:
*q = ((micro_value * (INT64_C(1) << 31)) / 1000000) >> *shift;
shell_info(sh, "micro_value=%" PRIi64, micro_value);
*shift += 1;
return 0;
}
Expand Down Expand Up @@ -240,7 +239,6 @@ static int cmd_config(const struct shell *sh, size_t argc, char **argv)
return -EINVAL;
}

shell_info(sh, "Configuring q=0x%08x, shift=%d", config.value, config.shift);
rc = sensing_set_attributes(open_connections[connection_index].handle, &config, 1);
if (rc != 0) {
shell_error(sh, "Failed to set attribute '%s' to '%s'", argv[2], argv[3]);
Expand Down
22 changes: 22 additions & 0 deletions subsys/sensing/src/userspace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Created by peress on 29/06/23.
//

#include <zephyr/rtio/rtio.h>
#include <zephyr/sensing/sensing.h>
#include <zephyr/app_memory/app_memdomain.h>

K_APPMEM_PARTITION_DEFINE(sensing_mem_partition);

static int sensing_mem_init(void)
{
int rc;

rc = k_mem_domain_add_partition(&k_mem_domain_default, &sensing_mem_partition);
if (rc != 0) {
return rc;
}
return k_mem_domain_add_partition(&k_mem_domain_default, &rtio_partition);
}

SYS_INIT(sensing_mem_init, POST_KERNEL, 99);

0 comments on commit 1462d8a

Please sign in to comment.