net: lwm2m: Add LWM2M_ON_INIT() macro

Add macro that allows registration of initialization functions that
are called when LwM2M engine starts.

On LwM2M engine starts up, it first executes all initialization
functions in following priority order:
1. LWM2M_PRIO_ENGINE
2. LWM2M_PRIO_CORE, this is where all LwM2M core objects are initialized
3. LWM2M_PRIO_OBJ, this is where all other objects are initialized
4. LwM2M_PRIO_APP, application initialization.

Now on the initialization phase, we could rely that certain objects have
already been registered.
For example custom objects can register callbacks to core objects.
On application phase, we can initialize sensor objects and register
their callbacks because objects have already been initialized.

This LWM2M_ON_INIT() should replace all use of SYS_INIT()
with the default CONFIG_KERNEL_INIT_PRIORITY_DEFAULT.

Priority order is actually just alphabetical order of names, so
the order is set on a linkin phase, and we don't need any
runtime checking for it.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
This commit is contained in:
Seppo Takalo 2024-01-19 16:14:37 +02:00 committed by Carles Cufí
commit ec3ec8cd2a
36 changed files with 105 additions and 47 deletions

View file

@ -127,4 +127,6 @@ zephyr_library_sources_ifdef(CONFIG_LWM2M_SHELL
lwm2m_shell.c lwm2m_shell.c
) )
zephyr_linker_sources(SECTIONS iterables.ld)
zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS)

View file

@ -157,4 +157,4 @@ static int ipso_accel_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_accel_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ipso_accel_init);

View file

@ -258,4 +258,4 @@ static int ipso_buzzer_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_buzzer_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ipso_buzzer_init);

View file

@ -228,5 +228,4 @@ static int ipso_current_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_current_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_current_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -228,7 +228,7 @@ static struct lwm2m_engine_obj_inst *filling_sensor_create(uint16_t obj_inst_id)
return &inst[index]; return &inst[index];
} }
static int init(void) static int fill_sensor_init(void)
{ {
fill_sensor.obj_id = IPSO_OBJECT_ID; fill_sensor.obj_id = IPSO_OBJECT_ID;
fill_sensor.version_major = FILLING_VERSION_MAJOR; fill_sensor.version_major = FILLING_VERSION_MAJOR;
@ -243,4 +243,4 @@ static int init(void)
return 0; return 0;
} }
SYS_INIT(init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(fill_sensor_init);

View file

@ -237,5 +237,4 @@ static int ipso_generic_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_generic_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_generic_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -218,5 +218,4 @@ static int ipso_humidity_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_humidity_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_humidity_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -201,5 +201,4 @@ static int ipso_light_control_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_light_control_init, APPLICATION, LWM2M_OBJ_INIT(ipso_light_control_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -249,4 +249,4 @@ static int ipso_switch_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_switch_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ipso_switch_init);

View file

@ -221,5 +221,4 @@ static int ipso_pressure_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_pressure_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_pressure_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -186,4 +186,4 @@ static int ipso_button_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_button_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ipso_button_init);

View file

@ -221,5 +221,4 @@ static int ipso_temp_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_temp_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_temp_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -366,4 +366,4 @@ static int ipso_timer_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_timer_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ipso_timer_init);

View file

@ -229,5 +229,4 @@ static int ipso_voltage_sensor_init(void)
return 0; return 0;
} }
SYS_INIT(ipso_voltage_sensor_init, APPLICATION, LWM2M_OBJ_INIT(ipso_voltage_sensor_init);
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -0,0 +1 @@
ITERABLE_SECTION_ROM(lwm2m_init_func, 4)

View file

@ -1330,9 +1330,12 @@ static int lwm2m_engine_init(void)
(void)memset(output_block_contexts, 0, sizeof(output_block_contexts)); (void)memset(output_block_contexts, 0, sizeof(output_block_contexts));
#endif #endif
if (IS_ENABLED(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)) { STRUCT_SECTION_FOREACH(lwm2m_init_func, init) {
/* Init data cache */ int ret = init->f();
lwm2m_engine_data_cache_init();
if (ret) {
LOG_ERR("Init function %p returned %d", init, ret);
}
} }
/* start sock receive thread */ /* start sock receive thread */

View file

@ -12,6 +12,7 @@
#include "lwm2m_object.h" #include "lwm2m_object.h"
#include "lwm2m_observation.h" #include "lwm2m_observation.h"
#include "lwm2m_registry.h" #include "lwm2m_registry.h"
#include <zephyr/kernel.h>
#define LWM2M_PROTOCOL_VERSION_MAJOR 1 #define LWM2M_PROTOCOL_VERSION_MAJOR 1
#if defined(CONFIG_LWM2M_VERSION_1_1) #if defined(CONFIG_LWM2M_VERSION_1_1)
@ -30,6 +31,65 @@
/* length of time in milliseconds to wait for buffer allocations */ /* length of time in milliseconds to wait for buffer allocations */
#define BUF_ALLOC_TIMEOUT K_SECONDS(1) #define BUF_ALLOC_TIMEOUT K_SECONDS(1)
/** initialization function */
struct lwm2m_init_func {
int (*f)(void);
};
/**
* @defgroup LWM2M_PRIO LwM2M initialization priorities
* @{
*/
#define LWM2M_PRIO_ENGINE 0 /**< Engine initialization */
#define LWM2M_PRIO_CORE 1 /**< Core object initialization */
#define LWM2M_PRIO_OBJ 2 /**< Object initializations */
#define LwM2M_PRIO_APP 3 /**< Application logic initialization */
/** @} */
/**
* @brief Declare an initialization function to be executed when LwM2M engine starts.
*
* When LwM2M engine starts up, it first executes all initialization functions in following
* priority order:
* 1. LWM2M_PRIO_ENGINE
* 2. LWM2M_PRIO_CORE, this is where all LwM2M core objects are initialized
* 3. LWM2M_PRIO_OBJ, this is where all other than core objects are initialized
* 4. LwM2M_PRIO_APP, application initialization.
* For example create sensor objects, and register object callbacks.
*
* @param[in] prio Priority, one of @ref LWM2M_PRIO macros.
* @param[in] init_function Initialization function
*/
#define LWM2M_ON_INIT(prio, init_function) \
STRUCT_SECTION_ITERABLE(lwm2m_init_func, \
CONCAT(LWM2M, prio, init_function)) = {.f = init_function}
/**
* @brief Declare engine initialization function.
* @sa LWM2M_ON_INIT
* @param[in] init_function Initialization function
*/
#define LWM2M_ENGINE_INIT(init_function) LWM2M_ON_INIT(LWM2M_PRIO_ENGINE, init_function)
/**
* @brief Declare core object initialization function.
* @sa LWM2M_ON_INIT
* @param[in] init_function Initialization function
*/
#define LWM2M_CORE_INIT(init_function) LWM2M_ON_INIT(LWM2M_PRIO_CORE, init_function)
/**
* @brief Declare object initialization function.
* @sa LWM2M_ON_INIT
* @param[in] init_function Initialization function
*/
#define LWM2M_OBJ_INIT(init_function) LWM2M_ON_INIT(LWM2M_PRIO_OBJ, init_function)
/**
* @brief Declare application specific initialization function.
* @sa LWM2M_ON_INIT
* @param[in] init_function Initialization function
*/
#define LWM2M_APP_INIT(init_function) LWM2M_ON_INIT(LWM2M_PRIO_APP, init_function)
/** /**
* @brief Validates that writing is a legal operation on the field given by the object in * @brief Validates that writing is a legal operation on the field given by the object in

View file

@ -439,4 +439,4 @@ static int ac_control_init(void)
return 0; return 0;
} }
SYS_INIT(ac_control_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(ac_control_init);

View file

@ -122,4 +122,4 @@ static int lwm2m_binaryappdata_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_binaryappdata_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(lwm2m_binaryappdata_init);

View file

@ -222,4 +222,4 @@ static int lwm2m_connmon_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_connmon_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(lwm2m_connmon_init);

View file

@ -393,4 +393,4 @@ static int lwm2m_device_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_device_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(lwm2m_device_init);

View file

@ -103,4 +103,4 @@ static int lwm2m_event_log_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_event_log_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(lwm2m_event_log_init);

View file

@ -506,4 +506,4 @@ static int lwm2m_firmware_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_firmware_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(lwm2m_firmware_init);

View file

@ -206,7 +206,7 @@ static int lwm2m_gw_init(void)
lwm2m_gw.obj_id = LWM2M_OBJECT_GATEWAY_ID; lwm2m_gw.obj_id = LWM2M_OBJECT_GATEWAY_ID;
lwm2m_gw.version_major = GATEWAY_VERSION_MAJOR; lwm2m_gw.version_major = GATEWAY_VERSION_MAJOR;
lwm2m_gw.version_minor = GATEWAY_VERSION_MINOR; lwm2m_gw.version_minor = GATEWAY_VERSION_MINOR;
lwm2m_gw.is_core = true; lwm2m_gw.is_core = false;
lwm2m_gw.fields = fields; lwm2m_gw.fields = fields;
lwm2m_gw.field_count = ARRAY_SIZE(fields); lwm2m_gw.field_count = ARRAY_SIZE(fields);
lwm2m_gw.max_instance_count = MAX_INSTANCE_COUNT; lwm2m_gw.max_instance_count = MAX_INSTANCE_COUNT;
@ -215,4 +215,4 @@ static int lwm2m_gw_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_gw_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(lwm2m_gw_init);

View file

@ -117,4 +117,4 @@ static int ipso_location_init(void)
return ret; return ret;
} }
SYS_INIT(ipso_location_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(ipso_location_init);

View file

@ -122,4 +122,4 @@ static int lwm2m_portfolio_init(void)
return 0; return 0;
} }
SYS_INIT(lwm2m_portfolio_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(lwm2m_portfolio_init);

View file

@ -261,4 +261,4 @@ static int lwm2m_security_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_security_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(lwm2m_security_init);

View file

@ -18,6 +18,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include "lwm2m_obj_server.h" #include "lwm2m_obj_server.h"
#include "lwm2m_rd_client.h" #include "lwm2m_rd_client.h"
#include "lwm2m_registry.h" #include "lwm2m_registry.h"
#include "lwm2m_engine.h"
#define SERVER_VERSION_MAJOR 1 #define SERVER_VERSION_MAJOR 1
#if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1) #if defined(CONFIG_LWM2M_SERVER_OBJECT_VERSION_1_1)
@ -458,4 +459,4 @@ static int lwm2m_server_init(void)
return ret; return ret;
} }
SYS_INIT(lwm2m_server_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_CORE_INIT(lwm2m_server_init);

View file

@ -794,4 +794,4 @@ static int lwm2m_swmgmt_init(void)
return 0; return 0;
} }
SYS_INIT(lwm2m_swmgmt_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(lwm2m_swmgmt_init);

View file

@ -1791,6 +1791,4 @@ static int sys_lwm2m_rd_client_init(void)
return lwm2m_rd_client_init(); return lwm2m_rd_client_init();
} }
LWM2M_ENGINE_INIT(sys_lwm2m_rd_client_init);
SYS_INIT(sys_lwm2m_rd_client_init, APPLICATION,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -2234,9 +2234,9 @@ int lwm2m_engine_enable_cache(const char *resource_path, struct lwm2m_time_serie
#endif /* CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT */ #endif /* CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT */
} }
int lwm2m_engine_data_cache_init(void)
{
#if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT) #if defined(CONFIG_LWM2M_RESOURCE_DATA_CACHE_SUPPORT)
static int lwm2m_engine_data_cache_init(void)
{
int i; int i;
sys_slist_init(&lwm2m_timed_cache_list); sys_slist_init(&lwm2m_timed_cache_list);
@ -2244,9 +2244,10 @@ int lwm2m_engine_data_cache_init(void)
for (i = 0; i < ARRAY_SIZE(lwm2m_cache_entries); i++) { for (i = 0; i < ARRAY_SIZE(lwm2m_cache_entries); i++) {
lwm2m_cache_entries[i].path.level = LWM2M_PATH_LEVEL_NONE; lwm2m_cache_entries[i].path.level = LWM2M_PATH_LEVEL_NONE;
} }
#endif
return 0; return 0;
} }
LWM2M_ENGINE_INIT(lwm2m_engine_data_cache_init);
#endif
bool lwm2m_cache_write(struct lwm2m_time_series_resource *cache_entry, bool lwm2m_cache_write(struct lwm2m_time_series_resource *cache_entry,
struct lwm2m_time_series_elem *buf) struct lwm2m_time_series_elem *buf)

View file

@ -242,7 +242,6 @@ struct lwm2m_cache_read_info {
}; };
#endif #endif
int lwm2m_engine_data_cache_init(void);
struct lwm2m_time_series_resource * struct lwm2m_time_series_resource *
lwm2m_cache_entry_get_by_object(const struct lwm2m_obj_path *obj_path); lwm2m_cache_entry_get_by_object(const struct lwm2m_obj_path *obj_path);
bool lwm2m_cache_write(struct lwm2m_time_series_resource *cache_entry, bool lwm2m_cache_write(struct lwm2m_time_series_resource *cache_entry,

View file

@ -150,4 +150,4 @@ static int ucifi_battery_init(void)
return 0; return 0;
} }
SYS_INIT(ucifi_battery_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ucifi_battery_init);

View file

@ -178,4 +178,4 @@ static int ucifi_lpwan_init(void)
return 0; return 0;
} }
SYS_INIT(ucifi_lpwan_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); LWM2M_OBJ_INIT(ucifi_lpwan_init);

View file

@ -10,6 +10,7 @@ set(APP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_sources(app PRIVATE ${APP_SRC_DIR}/main.c) target_sources(app PRIVATE ${APP_SRC_DIR}/main.c)
target_sources(app PRIVATE ${APP_SRC_DIR}/stubs.c) target_sources(app PRIVATE ${APP_SRC_DIR}/stubs.c)
target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/lwm2m_engine.c) target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/lwm2m_engine.c)
zephyr_linker_sources(SECTIONS ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/iterables.ld)
# Add includes directories # Add includes directories
target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)

View file

@ -612,7 +612,6 @@ ZTEST(lwm2m_registry, test_resource_cache)
struct lwm2m_time_series_elem e; struct lwm2m_time_series_elem e;
/* Resource cache is turned off */ /* Resource cache is turned off */
zassert_equal(lwm2m_engine_data_cache_init(), 0);
zassert_is_null(lwm2m_cache_entry_get_by_object(&path)); zassert_is_null(lwm2m_cache_entry_get_by_object(&path));
zassert_equal(lwm2m_enable_cache(&path, &e, 1), -ENOTSUP); zassert_equal(lwm2m_enable_cache(&path, &e, 1), -ENOTSUP);
/* deprecated */ /* deprecated */