Bluetooth: Mesh: Add API to store model's user data in settings work
Mesh models may have a data that needs to be stored persistently. Currently, the models should call bt_mesh_model_data_store and the store will happen in the calling context. Most likely that it will be called in BT RX thread as this is the context from which model's opcodes handlers are called. Thus, the thread will be blocked until the store is finished. Another issues is that some models may have states that changes frequently. Triggering the store on every state change may wear out flash. Therefore, the models need to implement some postpone mechanism to reduce the flash wear out. The mesh stack has already implemented the mechanism of deferred store with its own settings. The models could use it instead of implementing their own mechanism. In combination with the mesh settings workqueue, the models can store their data without blocking the stack work. Signed-off-by: Pavel Vasilyev <pavel.vasilyev@nordicsemi.no>
This commit is contained in:
parent
e33a4ace0f
commit
177e9b93bf
4 changed files with 51 additions and 0 deletions
|
@ -149,6 +149,22 @@ storage. The model can retrieve the data by calling the ``read_cb`` passed as
|
|||
a parameter to the callback. See the :ref:`settings_api` module documentation for
|
||||
details.
|
||||
|
||||
When model data changes frequently, storing it on every change may lead to
|
||||
increased wear of flash. To reduce the wear, the model can postpone storing of
|
||||
data by calling :c:func:`bt_mesh_model_data_store_schedule`. The stack will
|
||||
schedule a work item with delay defined by the
|
||||
:kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. When the work item is
|
||||
running, the stack will call the :c:member:`bt_mesh_model_cb.pending_store`
|
||||
callback for every model that has requested storing of data. The model can
|
||||
then call :c:func:`bt_mesh_model_data_store` to store the data.
|
||||
|
||||
If :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` is enabled, the
|
||||
:c:member:`bt_mesh_model_cb.pending_store` callback is called from a dedicated
|
||||
thread. This allows the stack to process other incoming and outgoing messages
|
||||
while model data is being stored. It is recommended to use this option and the
|
||||
:c:func:`bt_mesh_model_data_store_schedule` function when large amount of data
|
||||
needs to be stored.
|
||||
|
||||
API reference
|
||||
*************
|
||||
|
||||
|
|
|
@ -662,6 +662,16 @@ struct bt_mesh_model_cb {
|
|||
* @param model Model this callback belongs to.
|
||||
*/
|
||||
void (*const reset)(struct bt_mesh_model *model);
|
||||
|
||||
/** @brief Callback used to store pending model's user data.
|
||||
*
|
||||
* Triggered by @ref bt_mesh_model_data_store_schedule.
|
||||
*
|
||||
* To store the user data, call @ref bt_mesh_model_data_store.
|
||||
*
|
||||
* @param model Model this callback belongs to.
|
||||
*/
|
||||
void (*const pending_store)(struct bt_mesh_model *model);
|
||||
};
|
||||
|
||||
/** Vendor model ID */
|
||||
|
@ -842,6 +852,19 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd,
|
|||
const char *name, const void *data,
|
||||
size_t data_len);
|
||||
|
||||
/** @brief Schedule the model's user data store in persistent storage.
|
||||
*
|
||||
* This function triggers the @ref bt_mesh_model_cb.pending_store callback
|
||||
* for the corresponding model after delay defined by
|
||||
* @kconfig{CONFIG_BT_MESH_STORE_TIMEOUT}.
|
||||
*
|
||||
* The delay is global for all models. Once scheduled, the callback can
|
||||
* not be re-scheduled until previous schedule completes.
|
||||
*
|
||||
* @param mod Mesh model.
|
||||
*/
|
||||
void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod);
|
||||
|
||||
/** @brief Let a model extend another.
|
||||
*
|
||||
* Mesh models may be extended to reuse their functionality, forming a more
|
||||
|
|
|
@ -1850,6 +1850,11 @@ static void store_pending_mod(struct bt_mesh_model *mod,
|
|||
mod->flags &= ~BT_MESH_MOD_PUB_PENDING;
|
||||
store_pending_mod_pub(mod, vnd);
|
||||
}
|
||||
|
||||
if (mod->flags & BT_MESH_MOD_DATA_PENDING) {
|
||||
mod->flags &= ~BT_MESH_MOD_DATA_PENDING;
|
||||
mod->cb->pending_store(mod);
|
||||
}
|
||||
}
|
||||
|
||||
void bt_mesh_model_pending_store(void)
|
||||
|
@ -2134,3 +2139,9 @@ void bt_mesh_model_settings_commit(void)
|
|||
{
|
||||
bt_mesh_model_foreach(commit_mod, NULL);
|
||||
}
|
||||
|
||||
void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod)
|
||||
{
|
||||
mod->flags |= BT_MESH_MOD_DATA_PENDING;
|
||||
bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ enum {
|
|||
BT_MESH_MOD_PUB_PENDING = BIT(2),
|
||||
BT_MESH_MOD_EXTENDED = BIT(3),
|
||||
BT_MESH_MOD_DEVKEY_ONLY = BIT(4),
|
||||
BT_MESH_MOD_DATA_PENDING = BIT(5),
|
||||
};
|
||||
|
||||
void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue